学习笔记 · Obsidian
LLM 成本、元数据、多模态与检索
一个 run 被标为 <code>llm</code> 并不等于 LangSmith 能正确渲染消息、计算成本。生产上必须同时满足消息 I/O、模型元数据和 usage 元数据三套契约。
一、LLM run 的权威契约
LLM run 应包含:
- <code>run_type=llm</code>。
- inputs 中的 prompt 或规范化 messages。
- outputs 中的 generations/message/content blocks。
- metadata 中的 <code>ls_provider</code>、<code>ls_model_name</code>,必要时模型参数。
- usage metadata:input、output、total tokens,以及缓存、推理、图像等细分 token。
- 流式调用的首 token 时间。
判断接入质量不能只看“trace 出现了”,而要验证:
- Messages View 能重建角色和 tool call。
- token 数不重复、不为空。
- 模型/provider 与实际请求一致。
- cost 来源可解释。
- TTFT 与总 latency 同时存在。
二、消息格式
支持的核心角色是 system/developer、user、assistant、tool。工具调用需要稳定的 call ID,tool result 要引用同一个 ID。
内容可以是:
- 普通文本。
- 多 content block:text、image、audio、file/document。
- tool call 与 tool result。
- Provider 特有内容,但最好同时提供 LangSmith 可识别的标准字段。
多条消息可以放在规范化 <code>messages</code> 数组。不要把整段 JSON 字符串塞进一个 text 字段,否则 UI、评估器和语义搜索都失去结构。
Messages View 是适配器:
- 会把上一轮 LLM output 与下一轮 input 的重复消息去重。
- 会选择主对话分区,避免混入 guardrail 和子 Agent 支线。
- 对未知 Provider schema 可能显示空白,应回到 Details 检查原始数据。
三、模型元数据
常用 <code>ls_</code> 字段:
| 字段 | 用途 |
|---|---|
| ls_provider | 供应商、图标、价格规则匹配 |
| ls_model_name | 模型展示与成本规则匹配 |
| ls_temperature | 温度 |
| ls_max_tokens | 最大输出 |
| ls_stop | 停止条件 |
| ls_invocation_params | 其他调用参数 |
| ls_modality | audio 等模态标识 |
自托管/别名模型要同时给 provider 和稳定 model name。显示别名如果改变了价格匹配,必须同步组织模型价格映射。
四、Token 与成本
成本来源优先顺序应明确:
- Provider 响应的 usage。
- wrapper 的规范化 usage metadata。
- LangSmith 的模型价格映射推导。
- 调用方提交的自定义成本。
成本跟踪已扩展到任意 run;tool、第三方 API、retrieval 也可提交自定义成本。这样总成本才是 Agent 全栈成本,而不是“只有模型账单”。
生产注意:
- 区分 input/output、cached、reasoning 和多模态 token。
- 价格规则需包含 provider、model、时间/版本语义;同名模型在不同渠道价格可能不同。
- 未识别模型不会自动得到可信成本。
- 手工 provider 集成如果没有把响应 usage 写入 run,即使页面宣称可追踪,也不能保证精确成本。
- 成本仪表盘是观测估算,最终账单仍以供应商计费系统为准。
五、首 token 延迟
流式 LLM 应在收到第一个可交付 token 时记录 first token time:
- TTFT = first token time − start time。
- 总 latency = end time − start time。
- 用户感知还包括排队、检索、tool 和网络时间,因此要同时保留 root latency。
不要在收到 HTTP headers 时记首 token;也不要把服务端思考事件误当成最终用户可见 token,除非业务指标明确如此定义。
六、Retriever run
Retriever 用 <code>run_type=retriever</code>。输出应是文档列表,每个文档保留:
- page content。
- metadata:source、document ID、chunk ID、score、rank、版本。
生产建议:
- query 放 inputs,top-k、过滤条件、索引版本放 metadata。
- 不要只返回拼接后的 context;那会丢失逐文档可解释性。
- score 的方向和算法要写明,避免 dashboard 把“越低越好”的距离当相关度。
- 文档内容可能包含敏感数据,必须与 LLM prompt 使用同一脱敏策略。
七、多模态
LangSmith 可渲染 image、audio、PDF/file 等内容。两类传输方式:
| 方式 | 优点 | 风险 |
|---|---|---|
| URL | trace 小、无需上传大对象 | 链接过期、权限泄露、不可复现 |
| Attachment | 与 run 绑定、可控上传 | 存储、带宽、保留和隐私成本 |
Base64 适合小内容,不能作为高吞吐音视频默认方案。大文件应采样、压缩、限制类型和大小,并明确定义删除/保留策略。
Attachment 可从 bytes、本地路径或 reader 上传;输入或输出可携带。读取流通常只能消费一次,批处理回调不能随意复用已关闭的 reader。
八、音频
语音 trace 的详细结构见 07-编码代理语音与专用追踪。通用规则:
- root metadata 设 <code>ls_modality=audio</code>。
- root 附一个包含用户和 Agent 的合成音频。
- 记录“客户端实际播放”的 Agent 音频,不记录生成但因 barge-in 未播放的片段。
- 高吞吐时用压缩格式、降采样或只保留抽样会话。
九、输入输出预览
项目可配置表格里用哪些 JSONPath/字段作为 input/output preview,帮助快速扫 trace。它只改变列表展示:
- 不会改原始 inputs/outputs。
- 不等于脱敏。
- 不改变评估器输入。
- 路径错误只会导致预览空,不代表数据没上传。
因此预览配置适合可读性优化,隐私必须在 SDK processor、gateway 或数据入口层处理。
十、验收清单
- ○ LLM run type 正确,模型调用不是 chain。
- ○ system/user/assistant/tool 角色和 tool call ID 可还原。
- ○ model、provider、usage、TTFT 都存在。
- ○ cost 可追溯到价格规则或自定义字段。
- ○ retriever 输出保留文档粒度和索引版本。
- ○ 附件有大小、类型、权限和保留策略。
- ○ Messages View 与 Details 的主对话一致。