apo SDK 软件
类型脚本/ Java脚本 SDK apo 键,则 将专家知识转化为可执行的测试和工程系统 物剂吊带的能力规格。 任务 API 运行一个真正的控制器 (a) 追踪API, 保存人 或编码代理需要改进。 SDK的切入点:
@apo-ai/sdk/otel——开口遥测-内测追踪. 包装您的 LLM 呼叫和 代理步骤,所以他们降落在apo 作为结构的跨度,然后附加分数.@apo-ai/sdk/agent-task——主要能力试验地表. 定义 任务、适配器和测试; 对照真实的绳索运行并收集 以结构化证据作出判决.@apo-ai/sdk/agent-task/integrations/{ai-sdk,openai,anthropic}—— 说 每一框架的追踪包装被再出口直接进口.
安装
pnpm add @apo-ai/sdk
# or: npm install @apo-ai/sdk / yarn add @apo-ai/sdk
需要20号节点。 包船汇编了无害环境管理+ .d.ts (通过
tsup),因此没有 TypeScript 传输运行时间,也没有 allowImportingTsExtensions
消费者一方需要使用tsconfig旗.
对于 TypeScript 消费者, 也安装 @types/node (SDK发射)
参考节点全局像 Buffer:
pnpm add -D @types/node
释放
见 相关内容 为维护者运行本。 包裹
通过 GitHub OIDC 信任的出版方式发布到 npm sdk-v* 标记 -
没有长期 npm 令牌存储在寄存器中 .
配置
追查表面@apo-ai/sdk/otel阅读环境证书
变量在未明确传递时:
| 目的 | 新闻 var | 用于 |
|---|---|---|
| OTLP 跟踪终点 | APO_OTLP_ENDPOINT | 导出跨度的地方 |
| 项目(诊断) | APO_PROJECT | 只有资源属性——拥有租赁权 |
| 二键认证( 基本) | APO_PUBLIC_KEY + 键 APO_SECRET_KEY | Authorization: Basic base64(pk:sk) |
| 借记符 | APO_AUTH_TOKEN | 短寿命任务运行符; 仅在密钥对缺失时使用 |
遥测提交总是需要将 API- key 配对作为 API- key position
HTTP 基础base64("pk-apo-…:sk-apo-…")); SDK 从未合成部分
基本证书只有一半 故意没有
NEXT_PUBLIC_* 浏览器变体——仅一个公共标识符并不
授权摄取,在浏览器捆绑中曝光会产生误导
直接浏览器整合。 使用 buildApoAuthHeaders (从
@apo-ai/sdk/otel),以明确构建标题.
追踪—— @apo-ai/sdk/otel
犬科追踪路径是 OpenTeleometry 通过 @apo-ai/sdk/otel旧的
TraceTracker 编号 : createClient 自定义协议已被删除 .
import {
configureApoTelemetry,
withApoTrace,
traceTool,
traceAgent,
traceRetriever,
score,
injectTraceparent,
extractTraceparent,
} from "@apo-ai/sdk/otel";
configureApoTelemetry(options)
建立一个OTel追踪器供应商,由OTLP出口商指向apo. 要求数
takeOwnership: true (明确允许拥有OTel生命周期——不要
如果您的应用程序已经配置了 OTel 本身, 请打电话 .
const handle = await configureApoTelemetry({
takeOwnership: true,
endpoint: process.env.APO_OTLP_ENDPOINT ?? "http://localhost:8000/api/public/otel/v1/traces",
// headers, resource attributes, batch/simple processor, etc.
});
// …your traced work…
await handle.shutdown(); // flush + tear down
withApoTrace(name, fn, options?)
打开根跨度, 运行 fn 里面,结束时间,然后返回结果.
const summary = await withApoTrace("analyze-doc", async (span) => {
span.setAttribute("apo.flow.name", "analyze-doc");
return runAnalysis();
});
输入的观察助手
对于非LLM工作(工具、检索器、链条、代理),每个帮助者发出a 正确类型 GenAI 跨度 :
const docs = await traceRetriever("what is apo?", async () => [...]);
const out = await traceAgent("research-agent", async () => ({ ... }));
const tool = await traceTool("search", async () => ({ hits: 3 }));
可用 : traceTool, (中文(简体) ), traceAgent, (中文(简体) ), traceRetriever, (中文(简体) ), traceChain。 。 。 .
分数
在运行或观察中附加分数( 数字 / 绝对 / 布尔 ) :
await score(
{ traceId: runId, name: "correctness", value: 0.92, source: "EVAL" },
{ endpoint: config.endpoint, headers: { Authorization: `Bearer ${token}` } },
);
追踪文字传播
injectTraceparent(carrier, fields) 编号 : extractTraceparent(carrier) 使用 W3C
追踪上下文传播器( 正确处理) traceparent编号 :tracestate 解析,
——用于跨越服务界限的桥梁.
其他出口
createApoTraceExporter, (中文(简体) ), createApoSpanProcessor, (中文(简体) ), buildApoAuthHeaders, (中文(简体) ),
ApoSpanProcessor,加上选项类型(ConfigureApoTelemetryOptions, (中文(简体) ),
ApoTelemetryHandle, (中文(简体) ), ApoTraceExporterOptions, (中文(简体) ), ApoSpanProcessorOptions, (中文(简体) ),
ApoTraceOptions, (中文(简体) ), ScoreOptions) (中文(简体) ).
代理任务评价—— @apo-ai/sdk/agent-task
产品的主要表面:确定一种物剂任务及其检查,电线 与被测试的剂相适应,然后运行并收集结构化结果. 从子路径导入 :
import {
task,
defineAdapter,
runTask,
turn,
includes,
} from "@apo-ai/sdk/agent-task";
核心组成部分
task(id, { adapter, deliverables, … })登记任务定义 并返回适配器类型dtest。 。 。 .defineAdapter({ initialize, startSession, collectDeliverables, cleanup })——被测试的apo与代理人的合同(init,运行会话, 收集交付品,拆除).turn(fn)——可选择定义任务特定单回合或多回合输入.test(id, fn)- 通过返回的范围登记测试task()。 。 。 . 回电收到t(夸张的, 夕阳式的断言在跑道上) 以及从适配器中推断出的任务选择可达到的目标.runTask(taskDir, options?)- 执行任务并返回aTaskRunResult(音标+评价). 适配器来自任务 定义.loadTask(dir)编号 :discoverAgentTaskDirs()从磁盘上装入任务 .
测试( E)*.eval.ts(中文(简体) )
一个 <task-id>.eval.ts 文件持有任务定义、可选转动行为和代码或
LLM支持的检查。 检查读取两个运行 流动 (代理人的行为)和
联合国 可交付成果 (结果).
检查用平面写 t 环境与价值匹配者——单一方式
以断言。 每个断言都被记录下来(没有第一时间),所以每个检查报告
所有的失败.
import { task, includes, satisfies } from "@apo-ai/sdk/agent-task";
import { myAdapter } from "./adapter";
const { test } = task("review-output", {
adapter: myAdapter,
deliverables: ["result", "stats"],
});
test("used-the-right-tools", (t) => {
t.calledTool("read_file"); // did it call this tool
t.notCalledTool(/delete_/); // did it avoid this tool
t.toolOrder(["read_file", "search_content"]); // tools ran in this order
t.maxToolCalls(30); // didn't flail
t.noFailedActions(); // nothing errored
});
test("output-correct", (t, { deliverables }) => {
// result and stats are inferred from myAdapter.collectDeliverables().
t.check(deliverables.result, includes("finding"));
t.check(deliverables.stats, satisfies((s: { turn_count: number }) => s.turn_count > 0, "has turns"));
});
全球 test<TDeliverables>(...) 导出仍然可用
框架不可知性检查和现有任务文件。 喜欢 test 已返回
以 task() 用于新任务文件:它不需要手动通用或铸造
只披露这项任务所选择的交付品.
t - 流动断言 (读出跑道的踪迹,自动捕获):
calledTool(name, opts?), (中文(简体) ), notCalledTool(name, opts?), (中文(简体) ), toolOrder([...]), (中文(简体) ),
usedNoTools(), (中文(简体) ), maxToolCalls(n), (中文(简体) ), noFailedActions(), (中文(简体) ), loadedSkill(skill), (中文(简体) ),
calledSubagent(agent), (中文(简体) ), messageIncludes(token), (中文(简体) ), maxTurns(n), (中文(简体) ),
maxDurationMs(n, { turn? }), (中文(简体) ), maxTokens(n, { turn?, kind? }), (中文(简体) ),
minTokens(n, { turn?, kind? }), (中文(简体) ), assert(label, predicate)。 。 。 .
calledTool 编号 : notCalledTool 使用可选的制约来匹配呼叫
投入, (中文(简体) ), 产出,以及 状态 (和 count 确切数字。 每个
约束接受字元( 对象部分深) 、 RegExp 或
上游 :
t.calledTool("read_file", { input: { path: "source.py" } }); // exact arg
t.calledTool("read_file", { input: { path: /^src\// }, count: 2 }); // regex + count
t.calledTool("compute", { output: (v) => v === 42 }); // predicate on output
t.calledTool("flakey_tool", { status: "error" }); // a failed call
t.assert(label, predicate) 是逃生舱门 任何前置装置
当命名方法不覆盖您的大小写时, 键入了流程视图 :
t.assert("read before write", (flow) =>
flow.toolNamesInOrder.indexOf("read_file") < flow.toolNamesInOrder.indexOf("write_file"),
);
t.check(value, matcher) ——价值断言 (交付,解析JSON,
任何东西。 匹配者 : includes(substring|RegExp), (中文(简体) ), equals(value) (深处),
matches(standardSchema) (Zod/Valibot——任何与 safeParse, (中文(简体) ),
satisfies(predicate, label), (中文(简体) ), similarity(expected, threshold = 0.8) (模糊,
(原始内容存档于2013-10-10). Normaled Levenshtein.
对于 apo 任务, 流量会自动从 run 跟踪中构建 投影——无外接线.
t.judge(value, instruction) ——LLM支持的说法. 配置法官
与 runTask(dir, { judge: { model, apiKey?, baseURL?, provider? } }),或设置
OPENROUTER_MODEL编号 :OPENAI_MODEL编号 :ANTHROPIC_MODEL cLI运行时间。 一个赤裸的
claude-* 模型 id(或 Anthropic 碱性 URL) 将调用切换到
使用 ANTHROPIC_API_KEY 或者说
ANTHROPIC_AUTH_TOKEN法官的判决使用
与代码断言相同的记录器和结果格式,包括模型,即时,
反应、符号使用和延迟元数据.
一项任务也可以设置自己的法官级别(task("id", { judge: { model?, prompt? } })(中文(简体) )
覆盖运行级别配置并被覆盖 t.judge
调用 - 解析为 run-level ← task-level ← per-call,逐个字段.
prompt 是一个构建者 (ctx) => ({ system?, user? }) 获得什么
法官是评分(taskId, (中文(简体) ), taskDescription?, (中文(简体) ), checkName, (中文(简体) ), instruction, (中文(简体) ),
deliverableNames?因此,简报可以说 什么是裸露的可交付品+数字
从未透露过 SDK将其JSON响应合同附加于任何习惯
system ——建设者定制简报,从不采用回复格式. 保留
system 恒定每个任务,并仅变化 user 以保存缓存的提示
前缀横跨任务的标准(问题 # 161).
阿波的适配器上没有特工. fromOpenAIMessages(messages), (中文(简体) ),
fromAnthropicMessages(messages),以及 fromAISDK(result) 转换另一个
框架输出到中性 Flow 格式,以便用
FlowView数字 :
import { fromAISDK, FlowView } from "@apo-ai/sdk/agent-task";
const view = new FlowView(fromAISDK(myGenerateTextResult));
view.toolNamesInOrder; // e.g. ["read_file", "search_content"]
view.reply; // last assistant message text
这些正常化者是: 已贬值 相容性适配器 — canonical 路径发出标准OTel跨度(见上文跟踪集成),其中 apo在没有流程中介的情况下将项目投放到同一视图中.
CLI / 运行时间
parseAgentTaskCliArgs, (中文(简体) ), runAgentTaskCli, (中文(简体) ), loadTaskRuntime, (中文(简体) ), runTaskDir, (中文(简体) ),
AgentTaskRuntime 用于 apo CLI和后端的代理任务跑者.
见 apo CLI (中文(简体) )pnpm apo)和端到端使用的代理任务规格.
许可证
麻省理工学院