@ backendkit-labs/ 代理核心
后端Kit Labs代理框架的基础引擎. 提供构建,运行,并作曲AI代理所需的一切:打入工具定义,提供者适配器,会话内存,MCP客户端,工作流程管弦乐,和高级多层内存.
状态 :
core——企业使用案例要求. 在合并之前,要经过全面审查才能打破这些变化.
目录
- 安装
- 快开始
- 定义工具 - 有 Zod 键入的工具
- Agent Engine——执行核心
- createBaseEngine — 高级工厂
- 上下文收缩(合并预算)
- 护栏
- 供应商
- 运输
- 会话记忆
- MCP 客户端
- 工作流程引擎
- 高级内存系统
- 观察性
- 技能和斜线命令
- 检查站
- 工作空间
- 自主代理人和触发器
- 代表团巴士
- 类型参考
安装
npm install @backendkit-labs/agent-core
需要节点.js ~ 18 和 TypeScript ~ 5.0.
快开始
运行代理的最快路径 :
import {
AgentEngine,
AgentRegistry,
ToolRegistry,
ProviderRegistry,
defineTool,
z,
StdoutTransport,
} from '@backendkit-labs/agent-core';
// 1. Define a tool
const weatherTool = defineTool({
name: 'get_weather',
description: 'Returns current weather for a city',
input: z.object({
city: z.string().describe('City name'),
}),
execute: async ({ city }) => `Weather in ${city}: sunny, 22°C`,
});
// 2. Register tools and agents
const tools = new ToolRegistry();
tools.register(weatherTool);
const agents = new AgentRegistry();
agents.register({
id: 'general',
name: 'General Assistant',
systemPrompt: 'You are a helpful assistant. Use available tools when relevant.',
tools: ['get_weather'],
});
// 3. Register an LLM provider
const providers = new ProviderRegistry();
providers.register('my-provider', myLLMProvider);
// 4. Run
const engine = new AgentEngine({
model: { provider: 'my-provider', id: 'gpt-4o' },
agents,
tools,
providers,
defaultProvider: 'my-provider',
defaultAgentId: 'general',
transport: new StdoutTransport(),
maxIterations: 10,
iterationMode: 'auto',
});
await engine.run("What's the weather in London?");
定义工具 - 有 Zod 键入的工具
defineTool 以 Zod 输入计划来包裹一个函数。 引擎在调用前验证输入 execute,而TypeScript类型会自动流出.
基本工具
import { defineTool, z } from '@backendkit-labs/agent-core';
const greetTool = defineTool({
name: 'greet',
description: 'Greet a user by name',
input: z.object({ name: z.string() }),
execute: async ({ name }) => `Hello, ${name}!`,
});
可选参数和默认值
const searchTool = defineTool({
name: 'search_products',
description: 'Search the product catalog',
input: z.object({
query: z.string().describe('Search term'),
category: z.string().optional().describe('Filter by category'),
limit: z.number().min(1).max(50).default(10),
sort: z.enum(['price_asc', 'price_desc', 'relevance']).default('relevance'),
}),
execute: async ({ query, category, limit, sort }) => {
const results = await db.products.search({ query, category, limit, sort });
return results.map(p => `${p.name} — $${p.price}`).join('\n');
},
});
结构化/嵌入式输入
const createOrderTool = defineTool({
name: 'create_order',
description: 'Create a new customer order',
input: z.object({
customer: z.object({
id: z.string(),
email: z.string().email(),
}),
items: z.array(z.object({
productId: z.string(),
qty: z.number().int().positive(),
})).min(1),
shippingAddress: z.string(),
notes: z.string().optional(),
}),
execute: async ({ customer, items, shippingAddress, notes }) => {
const order = await orders.create({ customer, items, shippingAddress, notes });
return `Order ${order.id} created for ${items.length} item(s).`;
},
});
贾森归来
返回 JSON 字符串, 这样 LLM 可以解释结构化的数据 :
const analyzeCodeTool = defineTool({
name: 'analyze_code',
description: 'Analyze code and return structured issues',
input: z.object({
code: z.string(),
language: z.string(),
}),
execute: async ({ code, language }) => {
const issues = await analyzer.run(code, language);
return JSON.stringify({
issueCount: issues.length,
critical: issues.filter(i => i.severity === 'critical'),
warnings: issues.filter(i => i.severity === 'warning'),
});
},
});
投掷工具( 信号错误)
当一个工具抛出时,引擎会抓住错误并告诉LLM,LLM可以重试修正的参数或者向用户道歉:
const lookupUserTool = defineTool({
name: 'lookup_user',
description: 'Look up a user by email',
input: z.object({ email: z.string().email() }),
execute: async ({ email }) => {
const user = await db.users.findByEmail(email);
if (!user) throw new Error(`No user found with email ${email}`);
return JSON.stringify(user);
},
});
Agent Engine——执行核心
AgentEngine 是个非常出色的特工 它拥有对话循环,工具发送,多代理授权,和迭代控制.
构造选项
new AgentEngine({
// Required
model: { provider: 'openai', id: 'gpt-4o' },
agents,
tools,
providers,
defaultProvider: 'openai',
defaultAgentId: 'general',
// I/O
transport: new StdoutTransport(),
sessionId: 'session-xyz',
// Iteration control
maxIterations: 50,
iterationMode: 'auto', // 'auto' | 'step-by-step' | 'interactive' (default)
// Memory
sessionMemory: mySessionMemory,
memorySystem: myMemorySystem,
historyPath: '/path/to/history.json',
// MCP servers (connected lazily on first run)
mcpServers: [
{ name: 'github', command: 'npx', args: ['-y', '@modelcontextprotocol/server-github'] }
],
// Observability
observability: obsManager,
auditLog: '/path/to/audit.ndjson',
// Context injected into the system prompt
projectContext: 'You are working in project X...',
})
运行引擎
// Basic run — returns when done
const result = await engine.run('Summarize the README.md file');
console.log(result.final); // final assistant response
// Run with a specific agent
const result = await engine.run('Review this code for security issues', {
agentId: 'security-reviewer',
});
// Stream events to a UI
const events: AgentEvent[] = [];
await engine.run('Analyze the database schema', {
onEvent: (event) => {
if (event.type === 'chunk') process.stdout.write(event.content);
events.push(event);
},
});
迭代模式
| 模式 | 行为 |
|---|---|
'auto' | 运行到完成或 maxIterations 达到 |
'step-by-step' | 电话 onStep 每次重复后; 返回 false 停下来 |
'interactive' | 电话 onIterationLimit 达到上限时; 返回 true 继续。 没有回调 运行停止在盖子 |
工具审批独立于模式:任何时候 onToolApproval 已设定, 引擎先询问 write_file, (中文(简体) ), edit_file, (中文(简体) ), run_command 和包安装.
// Approval — user approves destructive tool calls
const engine = new AgentEngine({
...opts,
onToolApproval: async (toolName, agentId, argsPreview) => {
console.log(`[${agentId}] → ${toolName}:`, argsPreview);
const answer = await prompt('Approve? (y/n/all) ');
if (answer === 'y') return 'approve';
if (answer === 'all') return 'approve_all';
return 'reject';
},
});
// Step-by-step — inspect each iteration
const engine = new AgentEngine({
...opts,
iterationMode: 'step-by-step',
onStep: async (stats) => {
console.log(`Iteration ${stats.count}/${stats.max} — agent: ${stats.agentId}`);
return true; // false to stop
},
});
多回合会议
引擎保留了对话历史 run() 同一案件:
await engine.run('My name is Alice.');
await engine.run("What's my name?"); // → "Your name is Alice."
createBaseEngine — 高级工厂
createBaseEngine 从平面选项对象组装出所有内部内容,所以不需要手动即时注册.
import { createBaseEngine } from '@backendkit-labs/agent-core';
const engine = createBaseEngine({
providers: { openai: myOpenAIProvider },
defaultProvider: 'openai',
agents: myAgentList, // AgentProfile[]
tools: myToolList, // ToolDefinition[]
defaultAgent: 'general',
transport: new StdoutTransport(),
maxIterations: 100,
workingDir: process.cwd(),
});
await engine.run('Hello!');
用MCP服务器和管弦乐
const engine = createBaseEngine({
providers: { anthropic: myAnthropicProvider },
defaultProvider: 'anthropic',
agents: myAgents,
tools: myTools,
defaultAgent: 'general',
mcpServers: [
{
name: 'github',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-github'],
env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN! },
},
{
name: 'postgres',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-postgres', process.env.DATABASE_URL!],
},
],
orchestration: true, // enables intent detection + domain routing + QA review
});
上下文收缩(合并预算)
maxContextMessages 以信件计数来封顶历史, 并丢弃剪切的内容 。 与 context 页:1
历史保存在 符号 预算,旧的转折被总结而不是丢失:
const engine = createBaseEngine({
// ...
context: {
maxTokens: 60_000, // budget for the history (not the system prompt)
summarizer: { provider: 'deepseek', model: 'deepseek-chat' }, // cheap model for summaries (default: the default provider)
// strategy: 'summarize' | 'drop' (default 'summarize'; a failing summarizer falls back to 'drop')
// keepRecentTurns: 4 (last user turns are never touched)
// toolResultMaxChars: 8000 (older tool results are cut head+tail)
// threshold: 0.85 (compact above 85% of maxTokens, down to 70%)
// estimateTokens: (msg) => number (default ~4 chars per token, calibrated with real provider usage)
},
});
在每次LLM调用引擎前 (1) 切换出大量旧工具的结果 (2) 将最古老的工具折叠成一个
<conversation_summary> 块合并到第一个保存的用户转弯, 转而扩展上一个摘要
作为最后手段,它们被丢弃。 切口总是落在用户转弯的边界上,所以
工具 call / 工具结果对永远不会成为孤儿。 它发出 compacting 事件和a [Context] 系统行;
概要用途报告为 metrics 就像其他电话一样 CostTracker 说明它.
收缩是最佳的:任何失败都会被报告,运行会继续下去. 可与 maxContextMessages。 。 。 .
护栏
检查什么进入和离开代理循环,应用到主要代理 和每个子代理数字 :
| 阶段 | 已检查文本 | 当护栏挡住时 |
|---|---|---|
input | 用户消息 | 运行结束为 error 事件; 模式从未被调用 |
tool_call | jSON 工具调用的理由(在批准前) | 工具不运行; 模式被告知原因, 参数被从历史中清除 |
tool_result | 什么工具返回(在模型读取之前) | 结果被通知所取代 |
output | 模型的答案 | 答案被历史中的通知所取代 |
import { createBaseEngine, secretLeakGuardrail, piiGuardrail, promptInjectionGuardrail } from '@backendkit-labs/agent-core';
const engine = createBaseEngine({
// ...
guardrails: [secretLeakGuardrail(), piiGuardrail(), promptInjectionGuardrail()],
guardrailOutputMode: 'after', // or 'buffer'
});
准备就绪: piiGuardrail (电子邮件、电话[heuristic]、卡[Luhn]、IBAN[mod 97]、US SSN), secretLeakGuardrail
(文学) AgentProfile.secrets 联 合 国 每个 代理加通用密钥格式;总是在工具参数中将其阻塞),
promptInjectionGuardrail (热度:将可疑工具结果包装为 <untrusted_content>不是一个保证,
maxLengthGuardrail, (中文(简体) ), denyListGuardrail, (中文(简体) ), llmJudgeGuardrail (每检查一次额外的LLM呼叫).
写你自己: { name, phases, check(ctx) => { action: 'allow' } | { action: 'redact', content, reason } | { action: 'block', reason }, failMode?, dryRun? }。 。 。 .
redact 提供下一个守护栏; 第一个 block 赢了 护栏扔出 块 (单位:千美元)failMode: 'closed'默认值)
除非你设定 failMode: 'open'。 。 。 . dryRun: true 只有报告,这是调取假阳性的方法.
guardrailOutputMode: 与 after 当它们到达时,它们会发出信号;如果输出护栏改变答案,则
更正存储历史并 a guardrail 事件带有 replacement 为UI。 与 buffer 持有符号
直到检查答案 : 从未显示任何不受约束, 但没有流线 .
每个编辑、块和出错都显示 { type: 'guardrail', name, phase, action, reason, ... } 事件,将写入
auditLog 作为 guardrail:<phase>:<name>,并计入 MetricsSnapshot.guardrails。 。 。 .
工具取消和时限
每个工具呼叫收到 ctx.signal,一个 AbortSignal 当发动机被中止时会起火(engine.abort(),或预算停止 abortOnBudget)或当呼叫时限已过. 拿来 fetch,儿童过程和任何其他可以取消的:
const fetchPage = defineTool({
name: 'fetch_page',
description: 'Fetch a URL',
input: z.object({ url: z.string().url() }),
timeoutMs: 15_000, // this tool's limit; overrides the engine default
execute: async ({ url }, ctx) => (await fetch(url, { signal: ctx.signal })).text(),
});
const engine = createBaseEngine({
// ...
toolTimeoutMs: 60_000, // default limit for tools without their own (default: none)
toolTimeoutGraceMs: 2000, // wait for a tool to wind down after its signal fires
});
当限制通过时,信号被中止,在宽限期后,模型收到 Error: TOOL_TIMEOUT: tool "fetch_page" exceeded 15000ms (单位:千美元)tool_result.outcome = 'timeout'); 后来的结果被丢弃. 之后 engine.abort() 运行中的工具报告 Error: aborted (单位:千美元)outcome = 'aborted') (中文(简体) ). 等待批准的时间不算。 具有副作用的工具,时间流出时可能仍未完成,所以使这种工具具有一能性.
供应商
提供商将 LLM API 包装并执行 LLMProvider 接口. ProviderRegistry 持有指定供应商,由引擎选择每个代理.
import { ProviderRegistry } from '@backendkit-labs/agent-core';
const providers = new ProviderRegistry();
// Register multiple providers — engine selects per-agent or falls back to defaultProvider
providers.register('openai', openAIProvider);
providers.register('anthropic', anthropicProvider);
providers.register('local', ollamaProvider);
自定义 LLM 提供者
执行 LLMProvider 以添加任何 API :
import type { LLMProvider, LLMMessage, LLMStreamCallbacks, ToolDefinition } from '@backendkit-labs/agent-core';
class MyProvider implements LLMProvider {
async chat(
messages: LLMMessage[],
tools: ToolDefinition[],
callbacks: LLMStreamCallbacks,
): Promise<void> {
const stream = await myAPI.stream({ messages, tools });
for await (const chunk of stream) {
if (chunk.type === 'text') callbacks.onChunk(chunk.text);
if (chunk.type === 'tool_use') callbacks.onToolCall({ id: chunk.id, name: chunk.name, arguments: chunk.input });
}
callbacks.onDone();
}
}
providers.register('my-api', new MyProvider());
运输
接收的运输 AgentEvent 将物品交付给消费者.
Studout 运输
将事件打印为格式化的文本——对 CLI 工具有好处 :
import { StdoutTransport } from '@backendkit-labs/agent-core';
const engine = new AgentEngine({ ...opts, transport: new StdoutTransport() });
回调运输
将事件引导到您自己的函数 —— 用于服务器集成或流出 UI :
import { CallbackTransport } from '@backendkit-labs/agent-core';
const transport = new CallbackTransport((event) => {
switch (event.type) {
case 'chunk': process.stdout.write(event.content); break;
case 'tool_call': console.log(`[tool] ${event.name}`); break;
case 'agent_switch': console.log(`→ ${event.to}`); break;
case 'done': console.log('\n[done]'); break;
}
});
代理事件类型
| 类型 | 关键字段 | 说明 |
|---|---|---|
'chunk' | content: string | 递增LLM 令牌 |
'tool_call' | name, args, result | 调用工具并返回 |
'agent_switch' | from, to | 多机构代表团 |
'iteration' | count, max | 迭代计数器 |
'done' | final: string | 运行完成 |
'error' | message: string | 可恢复错误 |
会话记忆
SessionMemory 存储当前会话的对话框. AgentEngine 自动管理;直接用于自定义初始化或测试.
import { SessionMemory } from '@backendkit-labs/agent-core';
const memory = new SessionMemory();
// Seed with prior context
memory.addMessage({ role: 'user', content: 'My name is Alice.' });
memory.addMessage({ role: 'assistant', content: 'Nice to meet you, Alice!' });
const engine = new AgentEngine({ ...opts, sessionMemory: memory });
await engine.run("What's my name?"); // → "Your name is Alice."
MCP 客户端
MCPClientManager 连接到外部的MCP(模式上下文协议)服务器,发现其工具,并提供给引擎. 支持stdio,可流式HTTP,和SSE运输.
Stdio( 最常见的)
import { MCPClientManager } from '@backendkit-labs/agent-core';
const mcp = new MCPClientManager();
await mcp.connectStdio({
name: 'filesystem',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-filesystem', '/workspace'],
env: {},
});
const tools = mcp.getTools(); // ToolDefinition[] — discovered from the server
HTTP 运输
await mcp.connectStreamableHTTP({
name: 'remote-server',
baseUrl: 'https://mcp.example.com',
apiKey: process.env.MCP_API_KEY,
});
SSE 运输( 遗留服务器)
await mcp.connectSSE({
name: 'legacy-server',
url: 'http://localhost:8080/sse',
});
通过引擎选项的多服务器
通过 mcpServers 改为 createBaseEngine 或者说 AgentEngine 是推荐的路径——引擎管理生命周期,重试和断开检测:
const engine = createBaseEngine({
...opts,
mcpServers: [
{ name: 'github', command: 'npx', args: ['-y', '@modelcontextprotocol/server-github'], env: { GITHUB_TOKEN: '...' } },
{ name: 'slack', command: 'npx', args: ['-y', '@modelcontextprotocol/server-slack'], env: { SLACK_TOKEN: '...' } },
{ name: 'postgres', command: 'npx', args: ['-y', '@modelcontextprotocol/server-postgres'], env: { DATABASE_URL: '...' } },
],
});
断接检测(健康监测)
客户端检测服务器崩溃通过 client.onclose 并标记他们 'failed',防止停滞 'connected' 状态 :
// The engine's MCPRegistrar wires this automatically.
// For manual use:
mcp.setDisconnectHandler((serverName) => {
console.warn(`MCP server "${serverName}" disconnected`);
// Re-attempt connection on next engine.run() call
});
工作流程引擎
构建声明的多代理工作流程 WorkflowBuilder步骤可以按顺序、平行或有条件进行.
顺序工作流程
import { workflow, agent } from '@backendkit-labs/agent-core';
const reviewPipeline = workflow('code-review')
.step('fetch', agent('general', 'List all TypeScript files in src/'))
.step('analyze', agent('security-reviewer', 'Review the files for security issues'))
.step('report', agent('general', 'Summarize the findings into a report'));
const result = await engine.runWorkflow(reviewPipeline);
console.log(result.steps.report.output);
跨步骤的背景
参考以往产出 {{stepName.output}}数字 :
const dataPipeline = workflow('etl')
.step('ingest', agent('data-agent', 'Read /data/sales.csv'))
.step('transform', agent('data-agent', 'Clean {{ingest.output}}: fix nulls, normalize dates'))
.step('analyze', agent('analyst', 'Find the top 5 trends in: {{transform.output}}'));
平行步骤
const auditWorkflow = workflow('full-audit')
.parallel([
agent('frontend-agent', 'Audit React components for accessibility'),
agent('backend-agent', 'Audit API endpoints for security'),
agent('database-agent', 'Audit database schema for missing indexes'),
])
.step('merge', agent('general', 'Synthesize all three audit reports'));
有条件的步骤
const smartReview = workflow('smart-review')
.step('classify', agent('general', 'Classify this PR: feature, bug fix, or refactor. Reply with just the type.'))
.when('{{classify.output}} includes "bug"',
agent('qa-engineer', 'Focus on regression risk and edge cases')
)
.otherwise(
agent('general', 'Perform a standard code quality review')
);
工作流程运行器( 直接使用)
import { WorkflowRunner } from '@backendkit-labs/agent-core';
const runner = new WorkflowRunner(engine);
const result = await runner.run(myWorkflow, {
initialContext: { projectName: 'my-app', version: '2.0' },
onStepStart: (name) => console.log(`▶ ${name}`),
onStepDone: (name, out) => console.log(`✓ ${name}: ${out.slice(0, 80)}`),
});
// result.steps — Map<stepName, { output, durationMs }>
// result.total — total wall time in ms
// result.failed — boolean
高级内存系统
超越会话历史,代理可以使用三层持续记忆. 每层均可独立配置并有可插件商店作后盾.
| 层 | 目的 | 使用大小写 |
|---|---|---|
EpisodicMemory | 二. 发生的情况——事件和互动 | "上个礼拜我们重塑了认证" |
SemanticMemory | 已知的——事实和领域知识 | "爱丽丝拥有认证模块" |
ProceduralMemory | 如何做到——分步走规律 | "部署:建设""推""应用"" |
创建完整的记忆系统
import { createMemorySystem } from '@backendkit-labs/agent-core';
const memory = createMemorySystem({
episodic: {
provider: 'json',
path: '~/.bk-agent/projects/my-project/memory/episodes.json',
},
semantic: {
provider: 'json',
path: '~/.bk-agent/projects/my-project/memory/knowledge.json',
},
procedural: {
provider: 'json',
path: '~/.bk-agent/projects/my-project/memory/patterns.json',
},
retention: {
maxEpisodes: 500, // prunes by relevance score when exceeded (v0.22.3+)
summarizeAfter: 50,
// Optional: compress old episodes with an LLM summary
summarizeFn: async (episodes) => {
const list = episodes.map((e, i) => `${i + 1}. ${e.content}`).join('\n');
return await llm.summarize(list);
},
},
});
// Pass to engine
const engine = new AgentEngine({ ...opts, memorySystem: memory });
直接使用每层
const { episodic, semantic, procedural } = memory;
// --- Episodic ---
await episodic.add({
content: 'User asked to refactor the auth module',
tags: ['refactor', 'auth'],
timestamp: Date.now(),
});
const recentAuth = await episodic.search('auth', { limit: 5 });
// [{ id, content, tags, timestamp }, ...]
// --- Semantic ---
await semantic.add({
key: 'auth-module-owner',
value: 'Alice (Backend Team)',
tags: ['ownership', 'auth'],
});
const owner = await semantic.get('auth-module-owner');
// 'Alice (Backend Team)'
const authKnowledge = await semantic.search('auth', { limit: 10 });
// --- Procedural ---
await procedural.add({
name: 'deploy-to-staging',
steps: ['npm run build', 'docker build .', 'kubectl apply -f k8s/staging/'],
tags: ['deployment'],
});
const deploySteps = await procedural.get('deploy-to-staging');
忘记曲线(v0.22.3+)
何时 maxEpisodes 已设定,已超过的限度, EpisodicMemory 树枝由 相关分数 而非生龄:
relevanceScore = recency(0.6) × 1/(1 + daysSince × 0.1)
+ utility(0.4) × log(1 + recallCount)
被召回的相片往往比闲置的相片活得更久. recall() 自动递增 recallCount 每一张相匹配的记录上,都不需要额外的电话.
// Episode recalled 4× over 30 days: score ~0.43
// Episode that sat idle for 30 days: score ~0.15
// → idle episode is pruned first when the store is full
这个 recallCount 财务报告和审定财务报表 lastRecalledAt 字段在 JsonFileStore 并活下来重启.
室内商店(测试)
import { InMemoryStore, EpisodicMemory } from '@backendkit-labs/agent-core';
const episodic = new EpisodicMemory(new InMemoryStore());
await episodic.add({ content: 'test event', tags: [], timestamp: Date.now() });
JSON 文件存储( 制作)
import { JsonFileStore, SemanticMemory } from '@backendkit-labs/agent-core';
const semantic = new SemanticMemory(new JsonFileStore('/app/data/knowledge.json'));
内存StoreBackend 接口
所有后端执行 :
interface MemoryStoreBackend {
insert(record: StoredRecord): void;
upsert(id: string, record: StoredRecord): void;
getAll(): StoredRecord[];
deleteOldest(keepNewest: number): void;
deleteByIds(ids: string[]): void; // v0.22.3+: used by relevance-based pruning
count(): number;
}
deleteByIds 用于内部 EpisodicMemory 普润. 在自定义后端中使用它来支持遗忘曲线.
内存工具( 代理撰写自己的内存)
buildMemoryTools() 创建工具定义,让代理员读取并写入所有三个内存层:
import { buildMemoryTools } from '@backendkit-labs/agent-core';
const memTools = buildMemoryTools(memory);
// Returns: remember_episode, recall_episodes, store_knowledge, recall_knowledge,
// store_pattern, recall_pattern
memTools.forEach(t => tools.register(t));
观察性
ObservabilityManager 将成本跟踪、计量收集和分布式跟踪联系起来.
在引擎上启用可观察性
import { ObservabilityManager } from '@backendkit-labs/agent-core';
const obs = new ObservabilityManager({
costTracking: true,
metricsEnabled: true,
tracing: true,
});
const engine = new AgentEngine({ ...opts, observability: obs });
费用跟踪
import { CostTracker, MODEL_PRICING } from '@backendkit-labs/agent-core';
const tracker = new CostTracker();
// MODEL_PRICING[model] = { input: $/1M tokens, output: $/1M tokens }
console.log(MODEL_PRICING['gpt-4o']); // { input: 2.50, output: 10.00 }
console.log(MODEL_PRICING['claude-sonnet-4-6']); // { input: 3.00, output: 15.00 }
tracker.record({ model: 'gpt-4o', inputTokens: 1500, outputTokens: 200 });
console.log(`Cost: $${tracker.getTotalCostUSD().toFixed(6)}`); // $0.005750
计量快照
import { MetricsCollector } from '@backendkit-labs/agent-core';
const metrics = new MetricsCollector();
// After some runs:
const snap = metrics.getSnapshot();
// {
// sessionsActive: 3,
// runsTotal: 47,
// runsSucceeded: 44,
// runsFailed: 3,
// avgDurationMs: 1823,
// }
自定义跨度导出者
导出痕迹到 Jaeger, Honeycomb, Datadog, 或任何 OpenTeleometry 后端 :
import { Tracer } from '@backendkit-labs/agent-core';
const tracer = new Tracer({
onSpan: (span) => {
honeycomb.sendEvent({
'span.name': span.name,
'duration_ms': span.durationMs,
'agent.id': span.agentId,
'tool.calls': span.toolCallCount,
});
},
});
审计日志(NDJSON)
每个工具调用都可以登录到一个新线限定的JSON文件:
const engine = new AgentEngine({
...opts,
auditLog: '/var/log/agent-audit.ndjson',
// Each line: { ts, agentId, toolName, args, result, durationMs }
});
技能和斜线命令
技能是可重复使用的可增强代理行为的即时片段. Slash命令让用户直接引用代理特性.
装入内置技能
import { SkillLoader, createSkillManager } from '@backendkit-labs/agent-core';
const manager = createSkillManager('my-app');
// Install a skill pack from GitHub
await manager.install({
source: 'github:backendkit-labs/skills#main',
pack: 'backend',
});
const installed = manager.listInstalled();
// [{ id, name, pack, version }, ...]
内在技能定义
import { SkillRegistry, SkillActivator } from '@backendkit-labs/agent-core';
const registry = new SkillRegistry();
registry.register({
id: 'pr-review',
name: 'PR Review',
description: 'Perform a thorough pull request review',
prompt: `
Review this pull request with the following criteria:
1. Correctness — does the code do what the PR description claims?
2. Security — any new attack surface?
3. Performance — any obvious regressions?
4. Tests — are changes covered?
Output a concise review with LGTM or CHANGES REQUESTED at the end.
`,
tags: ['github', 'review'],
});
const activator = new SkillActivator(registry);
const systemContext = activator.buildContext(['pr-review']);
// Returns the skill prompt injected into the system context
斜线命令
内建命令 : /help, (中文(简体) ), /clear, (中文(简体) ), /status, (中文(简体) ), /skills, (中文(简体) ), /agents, (中文(简体) ), /workspace, (中文(简体) ), /checkpoint。 。 。 .
import { SlashCommandRegistry, registerBuiltinCommands } from '@backendkit-labs/agent-core';
const cmds = new SlashCommandRegistry();
registerBuiltinCommands(cmds);
// Custom command
cmds.register({
name: 'deploy',
description: 'Trigger a deployment to an environment',
handler: async (ctx) => {
const env = ctx.args[0] ?? 'staging';
await ci.triggerDeploy(env);
return `Deployment to ${env} triggered. Watch: https://ci.company.com/jobs/latest`;
},
});
// Handle user input
const input = '/deploy production';
if (input.startsWith('/')) {
const response = await cmds.handle(input, agentContext);
console.log(response);
}
检查站
保存并恢复会话状态用于恢复和分支.
保存检查点
import { createCheckpoint, listCheckpoints, readCheckpoint } from '@backendkit-labs/agent-core';
// After a successful milestone
await createCheckpoint({
sessionId: 'session-abc',
messages: engine.getMessages(),
projectDir: '/app/.bk-agent/projects/my-project',
description: 'After auth module refactor — all tests pass',
});
列出并恢复
// List all checkpoints
const summaries = await listCheckpoints('/app/.bk-agent/projects/my-project');
// [{ id, timestamp, description, messageCount }, ...]
// Restore a specific checkpoint
const checkpoint = await readCheckpoint(summaries[0].id, '/app/.bk-agent/projects/my-project');
const restoredMemory = new SessionMemory();
restoredMemory.loadMessages(checkpoint.messages);
const engine = new AgentEngine({ ...opts, sessionMemory: restoredMemory });
await engine.run('Continue from where we left off');
剪接长会
import { compactSession } from '@backendkit-labs/agent-core';
// Compress a 200-message conversation to a short summary
const compacted = await compactSession(
engine.getMessages(),
async (messages) => await llm.summarize(messages),
);
// Replace memory with compacted version to reduce context size
engine.replaceMessages(compacted);
工作空间
管理多个项目, 让代理在它们之间切换上下文 .
import {
loadWorkspaces, createWorkspace, addProject,
setActiveProject, buildWorkspaceContext,
} from '@backendkit-labs/agent-core';
// One-time setup
const config = await loadWorkspaces('my-app');
await createWorkspace('my-app', 'work');
await addProject('my-app', 'work', {
name: 'api-server',
path: '/home/user/projects/api-server',
});
await addProject('my-app', 'work', {
name: 'frontend',
path: '/home/user/projects/frontend',
});
// Switch active project
await setActiveProject('my-app', 'work', 'frontend');
// Build context string injected into the engine's system prompt
const ctx = buildWorkspaceContext(await loadWorkspaces('my-app'));
// "Active project: frontend (/home/user/projects/frontend)\nWorkspace: work\n..."
自主代理人和触发器
创建火与忘却的代理 运行在时间表或事件的反应.
计划剂(克龙)
import { createAutonomousAgent } from '@backendkit-labs/agent-core';
const standupAgent = createAutonomousAgent({
engine: myEngine,
schedule: '0 9 * * 1-5', // cron: weekdays at 9 AM
buildPrompt: () => 'Generate a daily standup summary from recent git commits and open PRs.',
onResult: (output) => slack.postMessage('#standup', output),
onError: (err) => logger.error('[standup-agent]', err),
});
await standupAgent.start();
// Stops the cron job
await standupAgent.stop();
事件驱动代理人
import { EventBus } from '@backendkit-labs/agent-core';
const eventBus = new EventBus();
// Subscribe to an event
eventBus.on('deployment.failed', async (payload) => {
const analysis = await engine.run(
`Investigate this deployment failure:\n${JSON.stringify(payload, null, 2)}`
);
await pagerduty.alert({ summary: analysis.final });
});
// Publish from your CI/CD system
await eventBus.emit('deployment.failed', {
service: 'payment-api',
version: '2.1.4',
errorLog: lastError,
});
触发管理器( 低级)
import { TriggerManager } from '@backendkit-labs/agent-core';
const triggers = new TriggerManager();
// Cron trigger
triggers.addSchedule({
id: 'daily-report',
schedule: '0 8 * * *',
handler: async () => engine.run('Generate daily report'),
});
// Webhook trigger
triggers.addWebhook({
id: 'github-pr',
path: '/webhooks/github',
handler: async (body) => engine.run(`Review PR: ${body.pull_request.title}`),
});
await triggers.start();
代表团巴士
DelegationBus 能够进行多代理人合作——组织者将分任务委托给专门代理人并收集成果.
import { DelegationBus } from '@backendkit-labs/agent-core';
const bus = new DelegationBus();
// Register specialized agents
bus.register('security-agent', async (req) => ({
output: (await securityEngine.run(req.prompt)).final,
agentId: 'security-agent',
}));
bus.register('data-agent', async (req) => ({
output: (await dataEngine.run(req.prompt)).final,
agentId: 'data-agent',
}));
// Delegate from orchestrator
const secResult = await bus.delegate({
targetAgentId: 'security-agent',
prompt: 'Audit this SQL query for injection risks: SELECT * FROM users WHERE id=' + input,
context: currentMessages,
});
console.log(secResult.output);
类型参考
导出的关键类型 @backendkit-labs/agent-core数字 :
// Engine
AgentEngineOptions // Full constructor options
BaseEngineOptions // Options for createBaseEngine
// Agents
AgentProfile // { id, name, systemPrompt, tools, provider? }
// Tools
ToolDefinition // { name, description, inputSchema, execute }
TypedToolOptions // Options for defineTool
ExecutionContext // Runtime context passed to tool.execute
// LLM
LLMProvider // Interface for LLM adapters
LLMMessage // { role, content }
LLMToolCall // { id, name, arguments }
LLMStreamCallbacks // { onChunk, onToolCall, onDone, onError }
ModelConfig // { provider, id }
// Memory
SessionMemoryData // Serialized session memory
MemorySystemConfig // createMemorySystem options
MemoryStoreBackend // 'json' | 'memory'
Episode // Episodic memory entry
Knowledge // Semantic memory entry
Pattern // Procedural memory entry
// MCP
MCPServerConfig // { name, command, args, env?, baseUrl?, url? }
// Workflows
WorkflowDef // Compiled workflow definition
WorkflowResult // { steps, total, failed }
WorkflowRunOptions // WorkflowRunner.run() options
// Iteration
IterationMode // 'auto' | 'step-by-step' | 'interactive'
IterationStats // { count, max, agentId }
ToolApprovalDecision // 'approve' | 'approve_all' | 'reject'
// Observability
ObservabilityConfig // { costTracking, metricsEnabled, tracing }
MetricsSnapshot // Current counters snapshot
Span // Tracing span
SpanExporter // Interface for custom exporters
// Events
AgentEvent // Union of all transport event types