学习笔记 · Obsidian

LLM 成本、元数据、多模态与检索

LangChainLangSmith

一个 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 出现了”,而要验证:

  1. Messages View 能重建角色和 tool call。
  2. token 数不重复、不为空。
  3. 模型/provider 与实际请求一致。
  4. cost 来源可解释。
  5. 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_modalityaudio 等模态标识

自托管/别名模型要同时给 provider 和稳定 model name。显示别名如果改变了价格匹配,必须同步组织模型价格映射。

四、Token 与成本

成本来源优先顺序应明确:

  1. Provider 响应的 usage。
  2. wrapper 的规范化 usage metadata。
  3. LangSmith 的模型价格映射推导。
  4. 调用方提交的自定义成本。

成本跟踪已扩展到任意 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 等内容。两类传输方式:

方式优点风险
URLtrace 小、无需上传大对象链接过期、权限泄露、不可复现
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 的主对话一致。