Skip to main content
Functions in Braintrust are atomic, reusable building blocks for executing AI-related logic. Functions are hosted and remotely executed in a performant serverless environment and are fully intended for production use. Functions can be invoked through the REST API, SDK, or UI, and have built-in support for streaming and structured outputs. Function types:
  • Prompts: LLM prompts with model configuration and templating (see Deploy prompts)
  • Tools: General-purpose code that LLMs can invoke to perform operations or access external data
  • Scorers: Functions for evaluating LLM output quality (returning a number from 0 to 1)
  • Agents: Chains of two or more prompts for multi-step workflows

Composability

Functions can be composed together to produce sophisticated applications without complex orchestration logic. Functions flow In this diagram, a prompt is being invoked with an input and calls two different tools and scorers to ultimately produce a streaming output. Out of the box, you also get automatic tracing, including the tool calls and scores. Any function can be used as a tool. For example, a RAG agent can be defined as just two components:
  • A vector search tool that embeds a query, searches for relevant documents, and returns them
  • A system prompt with instructions for how to retrieve content and synthesize answers using the tool
For a complete example, see the cookbook for Using functions to build a RAG agent.

Deploy tools

Tools are functions that LLMs can call to perform complex operations or access external data. Create tools in code and push them to Braintrust:
calculator.ts
import * as braintrust from "braintrust";
import { z } from "zod";

const project = braintrust.projects.create({ name: "calculator" });

project.tools.create({
  handler: ({ op, a, b }) => {
    switch (op) {
      case "add":
        return a + b;
      case "subtract":
        return a - b;
      case "multiply":
        return a * b;
      case "divide":
        return a / b;
    }
  },
  name: "Calculator",
  slug: "calculator",
  description: "A simple calculator that can add, subtract, multiply, and divide.",
  parameters: z.object({
    op: z.enum(["add", "subtract", "multiply", "divide"]),
    a: z.number(),
    b: z.number(),
  }),
  returns: z.number(),
  ifExists: "replace",
});
Push to Braintrust:
npx braintrust push calculator.ts

Add tools to prompts

Once deployed, add tools to prompts in the UI or via code:
  1. Open a prompt in the editor
  2. Click Tools
  3. Select your tool from the dropdown
  4. Save the prompt
When the model calls the tool, Braintrust automatically:
  • Invokes the tool in a secure sandbox
  • Appends the result to the message history
  • Calls the model again with the tool’s output
  • Continues for up to 5 iterations

Call tools directly

Call tools via the API without going through a prompt:
import { invoke } from "braintrust";

const result = await invoke({
  projectName: "calculator",
  slug: "calculator",
  input: {
    op: "add",
    a: 5,
    b: 3,
  },
});

console.log(result); // 8

Deploy scorers

Scorers evaluate the quality of LLM outputs. Create custom scorers in code:
quality-scorer.ts
import * as braintrust from "braintrust";
import { z } from "zod";

const project = braintrust.projects.create({ name: "My Project" });

project.scorers.create({
  handler: async ({ input, output, expected }) => {
    // Your scoring logic here
    const score = output.includes(expected) ? 1 : 0;
    return {
      name: "contains_expected",
      score,
      metadata: {
        input,
        output,
        expected,
      },
    };
  },
  name: "Quality Scorer",
  slug: "quality-scorer",
  description: "Checks if output contains expected text",
  parameters: z.object({
    input: z.string(),
    output: z.string(),
    expected: z.string(),
  }),
});
npx braintrust push quality-scorer.ts
Use scorers in experiments, playgrounds, or for online scoring. See Write scorers for details.

Deploy agents

Agents chain multiple prompts together into workflows. Create agents in playgrounds:
  1. Navigate to Playgrounds
  2. Click + Agent
  3. Add prompt nodes by selecting + in the comparison pane
  4. Use template variables to pass data between prompts:
    • {{dataset.input}} - Access dataset inputs
    • {{input}} - Access previous prompt’s output
    • {{input.field}} - Access structured output fields
  5. Save the agent
Agents automatically chain prompts and pass outputs between them. View deployed agents in the Agents library.
Agents are in beta and currently work only in playgrounds. Agent deployment via SDK is coming soon.

Handle dependencies

Braintrust automatically bundles dependencies for your functions:
  • TypeScript: Uses esbuild to bundle code and dependencies (excludes native libraries like SQLite)
  • Python: Uses uv to cross-bundle dependencies to Linux (supports most binary dependencies)
If you encounter bundling issues, file an issue on GitHub.

Version functions

Like prompts, functions are automatically versioned. Pin specific versions in code:
import { invoke } from "braintrust";

const result = await invoke({
  projectName: "calculator",
  slug: "calculator",
  version: "a1b2c3d4", // Pin to specific version
  input: { op: "add", a: 5, b: 3 },
});

Use the REST API

Call any function via HTTP:
curl https://api.braintrust.dev/v1/function \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $BRAINTRUST_API_KEY" \
  -d '{
    "project_name": "calculator",
    "slug": "calculator",
    "input": {
      "op": "add",
      "a": 5,
      "b": 3
    }
  }'
See the Data API reference for complete details.

Next steps