createAILogger(log, options?) 接受一个选项对象。每个选项都必须显式启用。默认设置保持安静,也保持安全:在你按名称请求之前,模型收到或返回的任何内容都不会进入你的输出端。
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
toolInputs | boolean | ToolInputsOptions | false | 捕获工具调用输入及其名称(默认关闭,以避免泄露敏感数据)。 |
prompt | boolean | CaptureOptions | false | 将发送给第一次模型调用的 Prompt 捕获为 ai.prompt(默认关闭,以避免泄露敏感数据)。 |
output | boolean | CaptureOptions | false | 将最后一次模型调用生成的文本捕获为 ai.output(默认关闭,以避免泄露敏感数据)。 |
cost | Record<string, ModelCost> | undefined | 定价映射。键为模型 ID,值为每 1M token 的美元价格 { input, output }。 |
工具输入
默认情况下,ai.toolCalls 是由工具名称组成的 string[]。启用 toolInputs 后还会捕获输入,这适合调试代理行为或审计模型访问了哪些数据。
工具输入可能很大,并且可能包含 SQL、API 密钥和客户 PII。在生产环境中直接捕获原始输入之前,请先使用
maxLength 和 transform。捕获全部内容
const ai = createAILogger(log, { toolInputs: true })
截断长输入
const ai = createAILogger(log, { toolInputs: { maxLength: 200 } })
脱敏敏感字段
const ai = createAILogger(log, {
toolInputs: {
maxLength: 500,
transform: (input, toolName) => {
if (toolName === 'queryDB') return { sql: '***' }
return input
},
},
})
| 子选项 | 类型 | 描述 |
|---|---|---|
maxLength | number | 截断超过此字符长度的字符串化输入(末尾附加 …)。 |
transform | (input, toolName) => unknown | 在 maxLength 之前应用的自定义转换。用于脱敏字段或重塑数据。 |
启用 toolInputs 后,ai.toolCalls 将变为 Array<{ name, input }>,而不是普通的字符串数组。
Prompt 和 Output 捕获
默认情况下,发送给模型或由模型返回的任何内容都不会进入你的输出端。两个相互独立的选项分别控制两个方向的捕获:prompt 记录发送的内容,output 记录返回的内容。你可以启用其中一个,也可以同时启用两个。
const ai = createAILogger(log, { prompt: true, output: true })
此时宽事件会携带:
ai.prompt:发送给第一次模型调用的 Prompt 格式化文本。每条消息对应一个文本块,并以其角色作为前缀;文本部分会直接内联,其他部分类型会变为[tool-call name]、[tool-result name]或[file]标记ai.output:由最后一次模型调用生成的文本,即多步骤运行中的最终答案。流式响应会从文本块中累积
仅捕获你需要的方向:
const ai = createAILogger(log, { prompt: true }) // 仅 ai.prompt
const ai = createAILogger(log, { output: true }) // 仅 ai.output
Prompt 和 Output 可能很大,并且会携带用户输入的任何内容。在生产环境中直接捕获原始内容之前,请先使用
maxLength 和 transform。截断长内容
每个选项都有自己的 maxLength:
const ai = createAILogger(log, { prompt: { maxLength: 500 } })
脱敏或重塑内容
transform 接收捕获的文本,并在 maxLength 之前运行:
const ai = createAILogger(log, {
prompt: {
maxLength: 500,
transform: text => redact(text),
},
})
| 子选项 | 类型 | 描述 |
|---|---|---|
maxLength | number | 截断超过此字符长度的捕获文本(末尾附加 …)。 |
transform | (content) => string | 在 maxLength 之前应用的自定义转换。 |
Prompt 和 Output 捕获是一项中间件功能:它适用于
createAILogger 和 createAIMiddleware。独立的 createEvlogIntegration 会观察遥测事件,但无法访问模型调用参数,因此其中的 ai.prompt 和 ai.output 会保持缺失。成本估算
传入 cost 映射以计算每次调用的预估美元成本。中间件会将 token 用量乘以每百万 token 的费率,并在宽事件上设置 ai.estimatedCost。
const ai = createAILogger(log, {
cost: {
'claude-sonnet-4.6': { input: 3, output: 15 },
'gpt-4o': { input: 2.5, output: 10 },
},
})
通过 ai.getEstimatedCost() 从处理程序中读取结果,这适合用于计费仪表板,或在高成本调用之前向用户发出警告。
将你的
cost 映射与模型选择放在同一个文件中,这样在生产环境中重命名模型时也会同时更新定价。按路由配置的映射会在两个路由对所调用的模型意见不一致时立即产生偏差,因此请统一维护一份。错误处理
如果模型调用失败,中间件会在重新抛出之前将错误捕获到宽事件中:
Wide Event
{
"ai": {
"calls": 1,
"model": "claude-sonnet-4.6",
"provider": "anthropic",
"finishReason": "error",
"error": "API rate limit exceeded"
}
}
流错误(例如内容过滤错误)也会从流的错误分块中捕获。你的错误处理代码(try/catch、路由级错误处理程序)会像往常一样继续工作,因为中间件只进行观察。