@ agentskit/ 可观察性
简介 : beta-package
确切地看你的代理人做什么——每个LLM的呼叫,工具执行,和推理步骤——与你的代理代码零相接.
标记 : ai • 妇女 agents • 妇女 llm • 妇女 agentskit • 妇女 ai-agents • 妇女 observability • 妇女 tracing • 妇女 opentelemetry • 妇女 langsmith • 妇女 logging • 妇女 monitoring
已核实的证据
- 软件包元数据和测试在
packages/observability/。 。 。 . - 软件包指南 : https://www.agentskit.io/docs/参考文献/packages/可观察性
- 稳定地图: 文件/服务.md
如何适应生态系统
@agentskit/可观察性使得代理行为可以检查有痕迹,成本,审计日志,devtools,以及生产遥测钩.
- 探员Kit:与本回购中的其他包一起作曲,从可互换的小零件来构建代理.
- 书记官处: 查找已使用此图层的即时代理和模板 登记. agentskit.io。 。 。 .
- 游戏本: 学习本层背后的生产模式 游戏本. agentskit.io。 。 。 .
为什么观察
- 分钟内调试, 不计时 ——追踪全ReAct循环:哪些工具被叫来,LLM收到什么,哪里出错,都在一个地方
- 用您已有的跟踪堆栈工作 – LangSmith, OpenTelemotry (OTLP), 或简单的控制台记录器; 观察者只是
{ name, on(event) }对象 - 没有接合,没有锁 - 附属于
AgentEvent运行时间的排放; 删除它和您的代理代码不变 - 设计非阻塞 − 观察者的错误从未浮出物剂;生产稳定性没有危险
安装
npm install @agentskit/observability
快速实例
import { createRuntime } from '@agentskit/runtime'
import { anthropic } from '@agentskit/adapters'
import { consoleLogger, langsmith } from '@agentskit/observability'
const runtime = createRuntime({
adapter: anthropic({ apiKey: process.env.ANTHROPIC_API_KEY, model: 'claude-sonnet-4-6' }),
observers: [
consoleLogger({ format: 'human' }),
langsmith({ apiKey: process.env.LANGSMITH_API_KEY }),
],
})
const result = await runtime.run('Analyze sales data in ./data/sales.csv')
console.log(result.content)
// Every step is now logged and traced automatically
计数
@agentskit/observability 包括一个零依赖指数计算API——用于上下文窗口预算检查,成本估算和消息剪切.
快速近似数
import { countTokens, approximateCounter } from '@agentskit/observability'
// async convenience function
const total = await countTokens(messages)
if (total > 120_000) trimOldMessages(messages)
// synchronous via counter directly
const syncTotal = approximateCounter.count(messages)
使用 chars / 4 + 4 per message 热心. 略为高估——有意为预算卫士.
按信息分列的数据
import { countTokensDetailed } from '@agentskit/observability'
const { total, perMessage } = await countTokensDetailed(messages)
// total → number
// perMessage → number[] (one entry per message, same order)
精确的计数器
import { createProviderCounter, countTokens } from '@agentskit/observability'
import { encoding_for_model } from 'tiktoken'
const enc = encoding_for_model('gpt-4o')
const tiktokenCounter = createProviderCounter({
name: 'tiktoken',
tokenize: (text) => [...enc.encode(text)],
})
const exact = await countTokens(messages, { counter: tiktokenCounter, model: 'gpt-4o' })
createProviderCounter 覆盖任意 tokenize(text, model?) 函数 a TokenCounter 符合核心合同并支持 countDetailed 自动.
特征
consoleLogger({ format })本地 dev 的漂亮打印或 JSON 结构日志langsmith({ apiKey })- LangSmith生命周期观察员(可选)langsmith端点)opentelemetry(config)——OTLP寿命周期观察器(可选的开放遥测同位素)datadogSink编号 :axiomSink编号 :newRelicSink- HTTP生命周期汇,有管理的分批处理- 费用警卫 -
costGuard, (中文(简体) ),multiTenantCostGuard, (中文(简体) ),createAdvancedCostGuard approximateCounter零分同步符号计数器(chars/4高压)countTokens编号 :countTokensDetailed使用可选的自定义计数器计数符号createProviderCounter- 工厂将tiktoken或任何装饰剂包装在TokenCounter合同- 观察界面 :
{ name: string, on(event: AgentEvent): void }- 在几分钟内写自定义观察者 - 通过附件
observers阵列在createRuntime——代理逻辑零变化
生产生命周期(水槽+SDK桥)
Datadog, Axiom, 新遗迹, LangSmith, 和 OpenTeleometry 工厂返回 生命周期观察员数字 :
type LifecycleObserver = Observer & {
flush(): Promise<void>
shutdown(): Promise<void> // idempotent
}
HTTP汇分享有限度、最有效出口(不是交货担保):
| 选项 | 默认 | 作用 |
|---|---|---|
batchSize | 25 | 最大事件/ POST |
maxQueueSize | 1000 | 硬队盖; 丢出最老的 满分时 |
flushIntervalMs | 2000 | 定期排水量 |
maxRetries | 3 | 初始尝试后重复 |
retryBaseDelayMs | 100 | 全速指数后退基数,上限为30s |
requestTimeoutMs | 10000 | 按请求暂停 |
onError | —— 说 | 孤立错误槽( 扔出/ 拒绝 永远无法逃脱) on(中文(简体) ) |
HTTP 汇重试网络错误和状态响应 408, (中文(简体) ), 429,或 5xx。 。 。 .
一个有效的 Retry-After 三角秒或 HTTP- date 是最小的延迟; 每个等待是
30岁时封顶 缺少或无效头头使用全快指数回放.
击打是 单机。可选的 SDK 同伴会懒散地解析; 软件包拥有其构造的 SDK 的冲/冲。 在优雅的程序或要求终止期间, 等待时 shutdown() 因此,飞行中 批量有排出的机会。 过度流量在压力下仍然下降得最久——计划能力和 onError 相应监测.
费用警卫
import {
costGuard,
multiTenantCostGuard,
createAdvancedCostGuard,
} from '@agentskit/observability'
const controller = new AbortController()
const guard = costGuard({
budgetUsd: 0.10,
controller,
// prices: { 'gpt-4o': { input: …, output: … } }, // override DEFAULT_PRICES
})
// Advanced modes
const advanced = createAdvancedCostGuard({
budgets: { tenantA: 1 },
mode: 'reject', // 'warn' | 'reject' | 'kill'
// mode 'kill' requires disableRuntime(tenant, reason)
})
advanced.setTenant('tenantA')
// Host enforcement for reject:
if (advanced.isRejected('tenantA')) {
// reject the request / stop scheduling work
}
语义( 当前硬化行):
- 递增会计 ——每个
llm:end使用 活动模式 为了那个事件 当模型改变时,历史符号永远不会被重新定价. 总计保持累积. - 敌对用途 —— 说
NaN编号 :Infinity/ 立即或完成数为负数0永远不要毒药成本,状态,或JSON有效载荷. - 零预算 ——首次正支出超过;利用率和回调保持有限(sentinel)
1当预算是0施舍是正的. - 隔离 —— 说
onCost编号 :onExceeded/警报汇/disableRuntime编号 :tenantOf编号 :now失败被隔离; 可选onError报告他们没有 手无寸铁的拒绝. - 模式 —— 说
warn仅观察;reject由 东道方咨询isRejected(tenant)(窗被卷起时,窗被拒绝;全被拒绝,直到reset(三);kill持续呼叫disableRuntime并揭露isDisabled(如果禁用失败则无法关闭) . DEFAULT_PRICES是一个基线快照,方便. 覆盖prices目前供应商费率 ——表号不是稳定合同. 守卫默认在未知型号上无法关闭;简单的守卫会中止其控制器,而多租户/高级守卫则根据其模式报告或屏蔽. 设定unknownModelPolicy: 'allow-zero'仅用于明确自由/本地模式.
简单 costGuard 通过所供应的终止 AbortController 当运行预算超过时( 标记 + 在潜在敌意之前中止) onExceeded) (中文(简体) ). 多租户和高级警卫不默认中止运行时间.
长期预算 CostStore
一个没有商店的守护者会保持其总计在进程内存中:它们在重启时重设,并且不会在实例或隔离之间共享. 这在开发上是好的,在没有服务器或多功能主机上是错误的,所以当没有设置商店时,警卫警告过一次 NODE_ENV=production,或者在云旗工人时 NODE_ENV 未设置。 过 warnWithoutStore: true 或者说 false 自己决定.
CostStore 是持久端口. reserve 持有对租户上限的估算, commit 把它取而代之的是真正的支出 并写出使用分类账, release 当呼叫失败时返回,并且 window 读取当前状态。 四人都拿房客身份证; reserve, (中文(简体) ), commit 财务报告和审定财务报表 release 以偶数计 reservationId。 。 。 .
import { Pool } from 'pg'
import { drizzle } from 'drizzle-orm/node-postgres'
import { multiTenantCostGuard } from '@agentskit/observability'
import { postgresCostMigrationSql, postgresCostStore } from '@agentskit/observability/postgres'
const pool = new Pool({ connectionString: process.env.DATABASE_URL })
await pool.query(postgresCostMigrationSql) // once, from your migration step
const store = postgresCostStore({ db: drizzle(pool) })
// Gate a request before calling the model.
const reserved = await store.reserve({ tenant, reservationId: turnId, amountUsd: 0.02, capUsd: planCapUsd })
if (!reserved.ok) return new Response('quota exceeded', { status: 402 })
try {
const usage = await runTurn()
await store.commit({ tenant, reservationId: turnId, actualUsd: usage.costUsd, usage: usage.calls })
} catch (error) {
await store.release({ tenant, reservationId: turnId })
throw error
}
// Or let a guard record every priced call and trip on the shared total.
const guard = multiTenantCostGuard({ budgets: { [tenant]: planCapUsd }, store })
- 原子盖. PostgreSQL商店在一份声明中承认保留(
reserved + spent + amount <= cap)),因此并行请求不能将盖相加过度. 盖子是一个论点reserve:从你的计划或应享权利表读取. - 会计窗口. 支出按
windowKey,默认为世界协调时的月份(2026-10) (中文(简体) ). 过windowKey到存储选项或每个调用另一个时段。 有商店,警卫的预算适用于目前的窗口. - 真正的支出赢了.
commit记录actualUsd即使它高于预估。 如果绝对不能通过上限, 则保留一个上限. - 后卫录事. 一个警卫写每个价钱
llm:end到商店和旅行 当存储总量通过预算。 为了在开销前阻止一个请求 打电话reserve和上面一样. - 连接寿命是你的. 在节点上用个游泳池. 关于工人,创建
pg客户端或每个请求的一个小池并关闭其中waitUntil。 。 。 .drizzle-orm财务报告和审定财务报表pg是可选的同伴,仅供/postgres子路径. - 一个释放的ID保持释放.
reserve被解除的保留的编号AK_COST_RESERVATION_RELEASED而不是报告为承认。 使用新代号重试一个呼叫 . - 被废弃的保留. 从未承诺或释放的保留(一个崩溃的过程)保持其数量;商店没有背景收割者。 时间表
expirePostgresCostReservations({ db, olderThan })比起你最慢的电话 截断时间更长new Date(Date.now() - 60 * 60_000)。 。 。 . - 存储失败 . 当商店倒闭时 警卫从不逃跑 它把错误报告给
onError; 无onError它记录了第一个失败的警告。 设定onError所以一个停止录音的商店是可见的. - 匹配错误
code。 。 。 . 在 CommonJS 中,每个子路径都捆绑自己的副本CostReservationError这样instanceof失败require('@agentskit/observability')财务报告和审定财务报表require('@agentskit/observability/postgres')比较error.code。 。 。 . - 交易. 打电话
reserve在您自己的交易之外,或在保存点内。 当两个调用一个预留ID的比赛时,商店会吸收失败者的独特违规,但PostgreSQL已经中止了附加交易. - 你自己的店铺. 执行
CostStore翻过桌子跑costStoreContract从@agentskit/observability/cost-store-contract在你的测试室.createInMemoryCostStore()是开发和测试的实施.
生态系统
| 软件包 | 作用 |
|---|---|
| @ agentskit/ 运行时间 | 说明追踪步骤 |
| @ agentskit/ 核心 | AgentEvent 流线 |
| @ agentskit/ eval (英语) | 质量门与痕迹 |
贡献者
许可证
麻省理工学院——见 自由主义。 。 。 .
文档
成熟性和相容性
- 稳定性: β 语录 看到了吗 文件/服务.md
- 节点.js 20+ 财务报告和审定财务报表 类型脚本 严格模式
- 发表于
@agentskit/observability