@amaster.ai/pi-遥测

运行时间追踪,先接后任,信使和成本核算,以及诊断Pi. Langfuse,Arize Phoenix,和通用的OpenTeleometry出口共享一个私人供应商.
使用官方的"Langfuse JS v5"和"OpenTeleometry SDK". Langfuse 导出通过 @langfuse/tracing 财务报告和审定财务报表 @langfuse/otel; 通用 OTLP 导出使用 JSON OTLPTraceExporter凤凰网使用匹配的原生产品出口国,因为其直接 /v1/traces 端点不接受OTLP/JSON. 15秒后请求暂停 寿命周期冲出时间为30秒.
条目点
@amaster.ai/pi-telemetry: 稳定合同,NoopRuntimeEventExporter,以及CompositeRuntimeEventExporter。 。 。 .@amaster.ai/pi-telemetry/config数字 :TelemetryConfig类型,resolveConfig,以及loadConfigFromFile。 。 。 .@amaster.ai/pi-telemetry/langfuse: Langfuse JS v5出口商@langfuse/tracing财务报告和审定财务报表@langfuse/otel。 。 。 .@amaster.ai/pi-telemetry/otel:通用OTLP/HTTP和凤凰号出口商,外加综合遥测工厂.
活动
延伸接通了以下Pi生命周期事件:
| 活动 | 遥测动作 |
|---|---|
session_start | 从配置初始化导出者 |
input | 启动新跟踪( traceId 边界 = 用户输入) |
turn_start | 在第一个转弯时开始根或子剂跨度 |
before_provider_request | 开始 LLM 生成范围并记录模型输入 |
after_provider_response | 标记失败的提供者响应 |
provider_stream_event 编号 : message_update | 支持时记录原始提供者帧, 返回到活动 LLM 生成下的已规范的流事件 |
agent_end | 存储最新结果; 立即完成 遗留 Pi |
agent_before_settle | 可用时记录最后运行结果 |
agent_settled | 完成 root 或 sub agent 跨度, 并在重试和队列续作完成后安排一个背景冲出; 记录取消从 aborted 可用时 |
tool_execution_start | 开始工具跨度 |
tool_execution_end | 结束工具间距和本地执行 durationMs (第1.1页+) |
message_end | 完成 LLM 生成周期,输出和使用 |
model_select | 记录模式切换事件 |
tool_result | 记录报告的工具-内部LLM使用情况 |
session_before_compact 编号 : session_compact 编号 : session_compact_failed | 记录收缩持续时间、摘要、故障/注销和报告的代号/费用使用情况 |
session_before_tree 编号 : session_tree | 记录分支时间和报告的使用情况 |
session_shutdown | 结束任何仍然开放的跨度( 标记) terminatedBy: session_shutdown),然后冲出并关闭出口商 |
追踪生命周期
追踪范围为新的用户即时边界。 流出期间所进行引导和后续排队,作为输入观测,一直停留在运行中直至和解. 单一用户信息可能触发多个模式请求,回覆和工具呼叫,被分组在一个跟踪下. Pi 0.84.2 然后完成追踪 agent_settled; 保留较早的同行 agent_end明确记录错误、取消和被取代的请求.
最多一个背景冲出和返回的结算时间表,而不等待缓慢或无法到达的后端。 以后的跨度由下一个解决方案或最后关闭覆盖. session_shutdown 在关闭出口者之前等待待处理的冲出,所以不放弃交货,而 /telemetry flush 仍然是等待和检查冲浪的明确方式。 当一个背景冲洗完成时, 状态会刷新, 但只有当输出方和会话仍然在时, 因此旧会话无法覆盖更新会话的状态 .
根会话ID来自 Pi会话存储,所以恢复会话保留其身份,而新的/被伪造会话使用自己的会话ID. 从持续存在的用户信件中迅速编号恢复。 儿童过程保留所继承的根会话并追踪,同时使用本地的Pi会话ID进行观察. 在结算和关闭时恢复相关环境变量.
Langfuse 跟踪带配置 serviceName 作为资源/元数据属性和 langfuse.session.id 这样共享的项目可以通过运行时间和会话过滤痕迹。 延长部分还添加 taskRunId 关联元数据当 PI_TELEMETRY_TASK_RUN_ID 已存在.
配置
配置从 "pi-telemetry" 在增加优先度方面, ~/.pi/agent/settings.json,则配置代理目录中的 settings.json (例如 $PI_CODING_AGENT_DIR/settings.json),以及一个值得信赖的项目的 .pi/settings.json当项目信任降低时,项目设置被忽略。 环境变量仅在用户和代理目录设置中被扩展.
{
"pi-telemetry": {
"serviceName": "my-service",
"serviceVersion": "1.0.0",
"includePayloads": true,
"mediaUploadEnabled": false,
"userId": "developer-id",
"environment": "development",
"release": "my-app-v1",
"langfuse": {
"enabled": true,
"publicKey": "pk-lf-...",
"secretKey": "sk-lf-...",
"baseUrl": "https://cloud.langfuse.com",
"flushAt": 20,
"flushIntervalMs": 5000
},
"otel": {
"enabled": true,
"endpoint": "https://otel-collector.example.com",
"headers": { "Authorization": "Bearer ..." },
"flushAt": 20,
"flushIntervalMs": 5000
},
"phoenix": {
"enabled": true,
"endpoint": "http://localhost:6006",
"apiKey": "${PHOENIX_API_KEY}",
"projectName": "pi-agent",
"flushAt": 20,
"flushIntervalMs": 5000
}
}
}
配置字段
| 外地 | 类型 | 默认 | 说明 |
|---|---|---|---|
serviceName | string | "pi-server" | 追踪服务名称 |
serviceVersion | string | —— 说 | 跟踪服务版本 |
includePayloads | boolean | false | 包括聊天有效载荷、工具参数和模式I/ 欧 |
mediaUploadEnabled | boolean | false | 上传快速/工具图像到 Langfuse; 也要求 includePayloads: true |
userId | string | —— 说 | 标准跟踪用户标识符 |
environment | string | —— 说 | Langfuse 环境标签,例如. development 或者说 production |
release | string | —— 说 | 释放标签; 独立于 OTEL 服务Version |
tags | string[] | [] | 在Langfuse和Phoenix中追加了痕量标记;最多32个有128个字符的独特修饰条目,检查了前256名候选人(超过4096个字符被忽略) |
traceName | string | "chat-turn" | Langfuse 微量和凤凰根显示名, 以 90 个字符为界 |
redactFields | string[] | [] | 在捕获的有效载荷、JSON编码的有效载荷和自定义元数据中掩盖不敏感个案的域名;与标记相同的列表限制 |
朗福斯配置
| 外地 | 类型 | 默认 | 说明 |
|---|---|---|---|
enabled | boolean | false | 启用 Langfuse 导出器 |
publicKey | string | —— 说 | Langfuse 公共 API 密钥 |
secretKey | string | —— 说 | Langfuse 秘密 API 密钥 |
baseUrl | string | "https://cloud.langfuse.com" | Langfuse 服务器 URL |
flushAt | number | 20 | 冲洗前批量大小 |
flushIntervalMs | number | 5000 | 平缓间隔( ms) |
布尔设置也接受环境插件 true, (中文(简体) ), TRUE, (中文(简体) ), 1,以及 yes;其他字符串是虚假的. Langfuse 证书和 URL 被裁剪。 缺少或空白的证书会禁用导出 。 选择 baseUrl 使用默认值; 明确空白值会禁用 Langfuse 导出 。 媒体上传仍需要同时启用有效载荷包含和媒体上传功能.
TEL 配置
| 外地 | 类型 | 默认 | 说明 |
|---|---|---|---|
enabled | boolean | false | 启用 OTEL 出口国 |
endpoint | string | —— 说 | OTLP 跟踪终点 |
headers | Record<string, string> | —— 说 | 请求信头 |
flushAt | number | 20 | 冲洗前批量大小 |
flushIntervalMs | number | 5000 | 平缓间隔( ms) |
当结束点没有结束时 /v1/traces,出口附件 /v1/traces。 。 。 .
凤凰配置
| 外地 | 类型 | 默认 | 说明 |
|---|---|---|---|
enabled | boolean | false | 启用 Phoenix/ 打开推断导出 |
endpoint | string | "http://localhost:6006" | 自行托管、云或完整的OTLP跟踪 URL |
apiKey | string | —— 说 | 凤凰 API 密钥,作为 Authorization: Bearer ... |
projectName | string | 凤凰服务器默认值 | 凤凰城项目,只设于凤凰城 openinference.project.name 资源属性 |
flushAt | number | 20 | 冲洗前的凤凰城批量大小 |
flushIntervalMs | number | 5000 | 凤凰冲洗间隔( ms) |
projectName 是可选的。 您也可以设定 PHOENIX_PROJECT_NAME 在进程环境中。 设置值优先于环境变量;如果两者都没有设定,凤凰城服务器会选择其默认项目. 整合工作流程提供变量,而不是创建每个运行的项目.
对于未经认证的自办凤凰,使用 endpoint: "http://localhost:6006" 并省略 apiKey。对于凤凰云或经认证的服务器,设置 apiKey 在用户或代理目录设置中 "${PHOENIX_API_KEY}" 例如插入和使用提供的空间 URL https://app.phoenix.arize.com/s/<space>。一个基础URL或一个完整 /v1/traces URL被接受;行走的斜线被正常化,路径前缀被保存,没有附加后缀两次. 不要将 API 密钥放在信任的项目设置中: 项目设置不会扩展环境变量 .
凤凰世代曝光了结构化的信息,思维,工具调用和结果,工具定义,引用参数,以及和Raw I/O一起选择的图像URL. 环境,发布,相关性和成本出处出现在元数据;痕量标记使用OpenInference标记. 其他信件/工具属性被封顶为512个属性和每个跨度250 KB. 最多100条信息、部分或工具定义被预测,有利于产出和最新投入; pi.telemetry.projection.truncated 表示投影限制。 Raw I/O保留了自己的极限.
Phoenix 适配器在 Open Information 中完成相同的工程 AGENT, (中文(简体) ), CHAIN, (中文(简体) ), LLM,以及 TOOL 类型。 它保存了跟踪/扫描ID和时间,将根会话映射到 session.id,赤裸的模型身份和提供者,工具名称/呼叫ID,并报告符号细节. 即时令牌包括已报告的缓存已读出/写出令牌;推理仍然是完成细节,而不是被计算两次. 有效载荷及其MIME 类型仅以 includePayloads: true. Phoenix 专用资源和跨度属性在导出前被克隆,因此同时的Langfuse和通用OTLP预测保持不变并保留匹配的ID.
已知的 Pi Cost 组件作为 OpenInference 成本属性导出,而不创建推理成本分拆. 凤凰城通常从自己的模型/提供物价表来计算摄入过程中显示的成本,因此未知的模型需要凤凰城自定义定价,所显示的成本可能与所报金额不同. 元数据保存 reportedCost 与凤凰城计算价格分开 costSource; 凤凰显示不同数量时检查. 显示 $0 与 costSource: "unknown" 并未证明该请求是免费的。 报告的第一内容时间戳作为 first_token 横跨事件和数字 llm.time_to_first_token_ms 编号 : llm.time_to_first_token_seconds 诊断。 这些数字属性并不能保证一个专门的凤凰城TTFT图表.
使用 phoenix没有 otel, 对于一个直通凤凰终端:凤凰接收gzip-compressed protobuf批次,而通用OTLP则有意保留其现有的JSON线条格式. 一个翻译OTLP/JSON的外部收藏家仍然可以接收通用的OTLP并转发给凤凰.
实况凤凰网核查
选入集成试验出口和查询真正的即时 → LLM → 工具 → LLM 有有效载荷的痕迹启用并被禁用. 在正常单元测试中跳过它 。 从寄存器根开始,从一个终端开始凤凰:
docker run --rm -e PHOENIX_ENABLE_AUTH=false -p 6006:6006 -p 4317:4317 arizephoenix/phoenix:latest
然后在另一个终端进行集成测试:
PHOENIX_TEST_ENDPOINT=http://localhost:6006 pnpm vitest run tests/telemetry-phoenix.test.ts
对于一个认证的服务器, 也设定 PHOENIX_TEST_API_KEY 在试验环境中。 测试使用独特的痕量ID并检查所储存的分级,项目/会场分组,模型,符/成本属性,出错,TTFT事件,并通过凤凰号的跨度API进行有效载荷压制. 它只设置 projectName 何时 PHOENIX_PROJECT_NAME 明确规定。 未认证的当地凤凰公司 default 项目,除非 PHOENIX_PROJECT_NAME 选择另一个已有工程.
GitHub 动作 Integration 工作流程还输出每个装入的B阶段/C阶段运行 pi-telemetry 给兰福斯和凤凰 专用浏览器-会话模型的取用是一个明显的例外,因为它会使其他扩展和遥测功能被禁用来隔离浏览器状态. 这个 pi-telemetry 基本,分级,并被编辑的情景验证了同样的真实的对两个后端的快感,没有第二次模型调用. 凤凰城出口和核查用途 PHOENIX_PROJECT_NAME 选择一个已有的工程,使用 github-pi 作为默认和可选的可变寄存器覆盖。 每个运行都会被其独特的密码字痕量ID所过滤;没有创建每个运行或每个工作的项目. PHOENIX_API_KEY 财务报告和审定财务报表 PHOENIX_COLLECTOR_ENDPOINT 仍然需要动作秘密,缺少的证书会失败受影响的E2E步骤,而不是默默地跳出导出.
程序用途
import { loadConfigFromFile, resolveConfig } from "@amaster.ai/pi-telemetry/config";
import { createPhoenixExporter, createTelemetryExporter } from "@amaster.ai/pi-telemetry/otel";
const config = resolveConfig(loadConfigFromFile());
const telemetry = createTelemetryExporter(config); // one provider for all configured destinations
const phoenixOnly = createPhoenixExporter(config);
隐私
运行时事件默认省略用户提示,助理响应,工具参数,工具输出,以及模型输入/输出. 错误消息总是导出 。 设定 includePayloads: true 包括有效载荷。 对于更精细的控制,可直接建造出一个出口商,然后通过 redactEvent。 。 。 .
观察细节
生成输入/输出使用可读的对话角色,结构化思维块和可用时的工具调用. 显示工具定义为 Langfuse ChatML name编号 :parameters 横跨 Chat Professions, Response, Anthropic and Bemini; 原始供应商计划仍在原始请求检查中。 生成输入来自在 before_provider_request,维护系统/开发者的作用,为查特补全,Anthropic,Resignation和双子星有效载荷发布消息命令和工具声明. 未识别的有效载荷格式返回捕获 context_with_system 记录,或者系统在更早的运行时间上迅速获取和激活工具注册. 每个孩子 llm-stream 将“输入”中的原始提供者请求与“输出”中捕获的流出事件相配对,包括任何帧到来前失败的空流。 原始请求仍保留在生成元数据中,因为 rawInput 在可读输入的同时进行兼容性和方便检查; 当有效载荷出口启用时,这有意重复请求。 原组装产出仍在 rawOutput有效载荷抑制、证明性遮盖和应用程序校正适用于这两种观测。 后期扩展仍然可以在遥测钩后更改请求. 反应模型,所请求的模型,API,反应ID和停止理由分别记录. 工具处决使用 Langfuse 的 TOOL 观察类型。 仪器范围记录了已安装的软件包版本.
与 includePayloads: true,每代元数据包含 requestHeaders 财务报告和审定财务报表 responseHeaders 从皮的 before_provider_headers 财务报告和审定财务报表 after_provider_response 事件,包括HTTP故障响应. 包含认证、饼干、密钥、令牌、秘密、密码、证书或签名的页眉名称被掩盖; 配置了证书面具、字段编辑和 redactEvent 也适用。 抓取最多保留了64个头和每个方向16个KB,其值仅限于2048个字符并有明显的省略/调取标记. 这些是运行时提供头头的快照:后期扩展或HTTP SDK可以在钩后添加或更改头头. 没有这些事件的旧运行时间省略了这些字段. 没有修改请求头 .
TTFT 开始于 before_provider_request 和结束于第一个非空文本、思考或工具调用内容,而不是初始流启动事件。 世代搭载了Langfuse的标准完成-启动时间戳,即使有效载荷出口被禁用.
Cache读取/写出使用和成本使用Langfuse的标准输入桶. 被报告推理是产出的一个子集,在不增加总数的情况下被分割;无效推理分裂会回落到合并输出. 合理成本是报告产出成本的成比例分拆 proportional-output-cost。1小时缓存仍为子集元数据,而不是额外的符号/成本桶。 估计没有缺失的使用量.
没有正价的模型中的全部零 SDK成本被标记 costSource: "unknown" 并省略了Langfuse的成本细节,允许后端模型-价格推论. 推断还需要一个相匹配的Langfuse模型定义. 包括零在内的明确事件或挂钩成本得到保存;生产者可以设定 usage.costSource: "provided" 对于已知的自由请求。 采用配置正模型率计算的费用标出 model-pricing。 。 。 .
辅助生成名保持其目的并有一个会话正文封顶为999999;制作人标签被限定为40个字符并保存在整个起/起事件. 收缩和分支摘要是指在闲置时按会话分组的活性痕量或独立痕量中的代数. 他们的服务模式是明确的 unknown,因为摘要条目不报告; modelAttribution: unreported 和可选 sessionModel 表示这个限制。 工具内部使用被嵌入到其工具下方,也有一个未知的模型. timingAttribution: operation 表示覆盖一个附件操作,而 usage-report 这意味着只遵守了报告时间。 没有摘要的平面分支导航不会生成一代.
命令和状态
/telemetry status(或/telemetry: 显示出口国状态和会话ID而不披露证书./telemetry flush: 冲出未完成的跨度并报告导出错误/超时。 这不会结束活动跨度或确认后端摄入.
TUI状态表示准备状态,禁用导出,缺少证书/端点,冲出完成,或出口失败. 当另一个目标活动时, 配置警告仍然可见 。 导出回调跟踪 Langfuse 、 一般 OTLP 和 Phoenix 的失败; 一个成功的目的地无法隐藏另一个失败 。 OTLP 部分成功答复 rejectedSpans > 0 也标记该目的地为出错,不作为整批重试,避免重复跨; OTLP/JSON使用的十进制倒数倒数倒数为64的值会被识别而不用数字转换. 以后完全成功就能清除错误。 会话启动、 和解和明确命令时更新状态 。 快速完成不等待后端冲出 。 会话关闭等待待取遥测出口.
图像和证书面具
图像需要有效载荷和媒体开关。 即时和工具图像使用Langfuse SDK支持的经验证的内置图像数据;对话历史使用图像标记. 已禁用,无效或超大小的图像二进制被替换为标记,包括嵌入到提供者请求中的二进制. 内置介质的上限为600 KB,每件内容值为基数64,每起事件为750 KB;较大投入保留了明显的省略图像标记. 超大小的属性截取在生成预览之前去除介质来防止部分图像上传. 通用OTLP可能包含所选择的内置介质;其收藏器不执行朗福斯介质上传.
所有配置了Langfuse证书,Phoenix API密钥,以及敏感的OTLP信头值,包括被禁用的目的地,而Langfuse密钥模式则被掩盖在每个目的地之前,包括错误消息和原始流输入. 这是证明性面具,不是一般的PII去除. 默认情况仍然是没有对话/工具有效载荷导出,以及 redactEvent 仍可用于具体应用政策.
当导出被禁用时,事件处理器会跳过遥测处理. 已禁用启动也会跳过运行时间加载和历史扫描. 与 includePayloads: false,每一代保留一个空 llm-stream 用于计时和分级的子,而扩展则跳过上下文投影和模型/工具有效载荷捕获,同时保留用法,出错,模型归属,以及先接取的时间. 流捕捉会将每个帧在转盘过程中被所剩的1 MB预算,10,000个值和32个嵌入水平所约束,再被截取后停止了后续帧的转换. 标记和阵列格式计算到抓取预算.
背景和辅助请求扩展作者
释放 pi-telemetry:request-context 打开 pi.events 在下一个提供时间之前 TelemetryRequestContext: 可选 userId, (中文(简体) ), traceName, (中文(简体) ), tags, (中文(简体) ), metadata,和一个W3C traceparent在新的快速边界上,一次就消耗了背景;指导和后续行动保持了积极的背景。 方案出口商曝光 setContext(context) 对于相同的数值。 元数据应包含明确的相关性事实,而不是对话内容。 自定义元数据需要 includePayloads: true 通过 redactEvent 作为 event.contextMetadata 导出前; userId, (中文(简体) ), tags 财务报告和审定财务报表 traceName 没有有效载荷捕获,仍可使用。 自定义元数据最多保留了31个条目,加上60个KB值预算中的省略标记;超大小的数值被明确省略. 无效的痕量父母会回到本地根上 。 有效载荷选择入场和认证口罩仍然有效.
pi.events.emit('pi-telemetry:request-context', {
userId: 'operator-1',
tags: ['batch'],
metadata: { jobId: 'job-42' },
});
子 Pi 进程会自动继承作为父工具的独特活性工具. 当多个工具被激活时,它会倒回代理母体而不是猜测. 对于精确的并行归属,请查询执行工具的上下文,并将返回的只有遥测环境覆盖到该特定儿童发射中:
let telemetryEnv: Record<string, string> = {};
pi.events.emit('pi-telemetry:tool-context', {
toolCallId,
respond: (env: Record<string, string> | undefined) => { telemetryEnv = env ?? {}; },
});
// Pass { ...process.env, ...telemetryEnv } as the child process environment.
方案出口商曝光 getToolContext(sessionId, toolCallId) 为了同样的目的。 已完成或未知的工具返回 undefined保留现有的发射机相关变量;不要将一次发射的超载与另一次同时发射共用。 嵌入式运行时间工具也保存了已报告 parentToolCallId。 。 。 .
执行自己模式调用的扩展 pi-telemetry:llm 使用导出 TelemetryAuxiliaryEvent 类型。 释放 started,则 completed 或者说 failed 同样的 llmGenerationId实际数 model时间戳, source (单位:千美元)compaction, (中文(简体) ), branch_summary,或 tool)和任何报告的请求/答复、使用、第一内容时间戳和错误。 关于工具呼叫,包括 parentToolCallId。源属性标记 producer;事件与该代人的积极跟踪或共享的独立跟踪相关. 保持每个电话唯一的身份 该事件属于相应的收缩,分支-摘要或工具生命周期内;被观测到的呼叫压制了该操作的重建用法生成,因此放出所有调用,而不仅仅是一个子集. 该桥不拦截未设防的第三方模式客户.
实地编辑适用于所捕获的有效载荷字段,并明确提供自定义元数据,而不是运行时间路由ID. 也掩盖了JSON嵌入字符串的有效. 无效的JSON和普通道具只接收到证书口罩;字段名的校正不是一般的PII检测. JSON超大需要外地编辑的被替换为省略标记. 对话显示保留了500 KB / 100 个消息中的最新消息,然后是通用属性截取;省略的历史被明确标记. 完整的协议输入本身可能在现有属性限制下被截取.