Agent examples
Three agents, from the smallest possible one to a retrieval-backed support agent. Each is a single
deep-agents/<name>/index.tsfile you can drop into a workspace and run withstackbone dev. They follow the layout from Getting started.
Every tool below reads from the ambient stackbone client. Reads from that
client come back as a { data, error } envelope, so each example checks
.error before using .data. The one exception is stackbone.database,
which is native Drizzle and throws on error.
1. A plain greeter
The smallest useful agent: a model and a system prompt, no tools. It answers in the voice you set in the prompt.
import { defineDeepAgent } from '@stackbone/sdk/deep';
export default defineDeepAgent({
model: 'openai/gpt-4o-mini',
systemPrompt: [
'You are a warm, concise greeter.',
'Welcome the person by name when they give it, and offer one helpful next step.',
'Keep every reply to two sentences.',
].join('\n'),
});Run stackbone dev, then:
curl http://127.0.0.1:4242/openai/v1/chat/completions \
-H 'content-type: application/json' \
-H 'authorization: Bearer local-dev' \
-d '{"model":"greeter","messages":[{"role":"user","content":"Hi, I am Sam"}]}'2. A config-driven agent
This agent reads its tone from the config surface so an operator can change behaviour without a redeploy. The tool exposes the current tone, and the system prompt tells the model to apply it.
import { tool } from '@langchain/core/tools';
import { z } from 'zod';
import { defineDeepAgent } from '@stackbone/sdk/deep';
import { stackbone } from '@stackbone/sdk';
const getTone = tool(
async () => {
const tone = await stackbone.config.get('tone');
return tone.error ? 'neutral' : String(tone.data);
},
{
name: 'get_tone',
description: "Return the agent's current tone setting.",
schema: z.object({}),
},
);
export default defineDeepAgent({
model: 'openai/gpt-4o-mini',
systemPrompt: [
'You are a hotel concierge.',
'Before your first reply in a conversation, call get_tone and adopt that tone',
'(for example "formal" or "playful") for the rest of the chat.',
].join('\n'),
tools: [getTone],
});Because the tone comes from config, the operator sets it once and every new conversation picks it up.
3. A retrieval-backed support agent
A support agent that searches a knowledge base with RAG and looks up orders in its own database. Two tools, one agent.
import { tool } from '@langchain/core/tools';
import { z } from 'zod';
import { defineDeepAgent } from '@stackbone/sdk/deep';
import { stackbone } from '@stackbone/sdk';
import { eq } from '@stackbone/sdk/db';
import { orders } from './schema';
const searchKb = tool(
async ({ query }: { query: string }) => {
const result = await stackbone.rag.retrieve({ text: query, topK: 5 });
if (result.error) throw new Error(result.error.code);
return JSON.stringify(result.data.map((hit) => ({ score: hit.score, content: hit.content })));
},
{
name: 'search_kb',
description: 'Search the help-center knowledge base before answering.',
schema: z.object({ query: z.string() }),
},
);
const lookupOrder = tool(
async ({ orderId }: { orderId: string }) => {
const [order] = await stackbone.database
.select()
.from(orders)
.where(eq(orders.id, orderId))
.limit(1);
return order ? JSON.stringify(order) : 'not_found';
},
{
name: 'lookup_order',
description: 'Look up an order by its id.',
schema: z.object({ orderId: z.string() }),
},
);
export default defineDeepAgent({
model: 'openai/gpt-4o-mini',
systemPrompt: [
"You are Acme's support agent.",
'Search the knowledge base with search_kb before answering policy questions.',
'Use lookup_order when the user gives an order number.',
"Answer in two sentences or fewer, and say plainly when you don't know.",
].join('\n'),
tools: [searchKb, lookupOrder],
});The model picks the right tool from each description. Send an
x-stackbone-session header on every call to keep one running conversation
per user, so a follow-up question lands in the same context without you
re-sending the history.
Where to go next
- What is an agent: the model behind these examples.
- Workflow + Agents: drive an agent like this one from a durable workflow.
- SDK overview: every surface a tool can reach
(
config,storage,rag,database,ai, and more).