尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

【Bug已解决】ChatMistralAI incompatible token output format for LangSmith traceability

【Bug已解决】ChatMistralAI incompatible token output format for LangSmith traceability 【Bug已解决】ChatMistralAI incompatible token output format for LangSmith traceability一、现象长什么样用ChatMistralAI跑模型把调用链接到LangSmithLangChain 官方的 tracing 平台做可观测性时发现token 用量在 trace 里显示不出来或格式错乱。原因ChatMistralAI把 Mistral 返回的 token 用量放在自己定义的结构里比如嵌套 dict、字段名prompt_tokens/completion_tokens或 Mistral 特有的usage形状而 LangSmith 期望的是标准的llm_output.token_usage格式带prompt_tokens/completion_tokens/total_tokens顶层键。两者对不上LangSmith 解析不到用量trace 的 token 面板空白或报格式错。后果成本监控、token 归因、按用量分析 prompt 全部失效排查时要去比对 Mistral 原始响应和 LangSmith 期望 schema定位慢。二、背景LangSmith 的 trace 对 LLM 调用期望在标准位置读到 tokenllm_output[token_usage] {prompt_tokens: N, completion_tokens: M, total_tokens: T}。Mistral 的 API 响应usage字段可能长这样{prompt_tokens: N, completion_tokens: M, total_tokens: T}看起来键名一致但ChatMistralAI有时把它包了一层如llm_output[usage] {...}而非llm_output[token_usage] {...}或漏填total_tokens或把 usage 放在response_metadata而非llm_output。LangSmith 只读llm_output.token_usage于是读不到。三、根因根因两点字段位置/命名不对齐ChatMistralAI把 usage 放在usage或response_metadata而非 LangSmith 期望的token_usage顶层键。缺 total_tokens 等字段部分情况下只填了 prompt/completion漏total_tokensLangSmith 解析不完整。本质把模型原始 usage直接当LangSmith 期望的 token_usage用忽略了两者 schema 差异未做归一化映射。四、最小可运行复现下面缩略逻辑复现格式不对齐def bad_to_llm_output(mistral_resp): # 把 usage 放在错误位置/命名 return {usage: mistral_resp[usage]} # LangSmith 读 token_usage读不到 # LangSmith 期望 def good_to_llm_output(mistral_resp): u mistral_resp[usage] return { token_usage: { prompt_tokens: u[prompt_tokens], completion_tokens: u[completion_tokens], total_tokens: u.get(total_tokens, u[prompt_tokens] u[completion_tokens]), } }五、解决方案第一层最小直接修复最小修法把 Mistral usage 映射成 LangSmith 标准token_usage补全total_tokens放在llm_output顶层。def to_langsmith_tokens(mistral_usage: dict) - dict: prompt mistral_usage.get(prompt_tokens, 0) completion mistral_usage.get(completion_tokens, 0) total mistral_usage.get(total_tokens, prompt completion) return { token_usage: { prompt_tokens: prompt, completion_tokens: completion, total_tokens: total, } } # 在 ChatMistralAI._generate 里 llm_output to_langsmith_tokens(raw[usage])这一层让 LangSmith 能正确读到 token。六、解决方案第二层结构化改进把token 输出格式归一化策略固化成策略对象作为单一事实来源明确目标 schema 与字段补全。from dataclasses import dataclass from typing import Dict dataclass(frozenTrue) class LangChainMistralTokenPolicy: ChatMistralAI token 输出格式策略的单一事实来源。 target_key: str token_usage required_fields: tuple (prompt_tokens, completion_tokens, total_tokens) def normalize(self, usage: Dict) - Dict: prompt usage.get(prompt_tokens, 0) completion usage.get(completion_tokens, 0) total usage.get(total_tokens, prompt completion) out { prompt_tokens: prompt, completion_tokens: completion, total_tokens: total, } return {self.target_key: out} def validate(self) - None: if self.target_key ! token_usage: raise AssertionError(LangSmith expects token_usage)ChatMistralAI用policy.normalize(raw_usage)产出标准格式。七、解决方案第三层断言 / CI 守护用 pytest 锁死格式对齐import pytest from policy import LangChainMistralTokenPolicy as P def test_standard_shape(): p P() out p.normalize({prompt_tokens: 10, completion_tokens: 5}) assert out[token_usage][prompt_tokens] 10 assert out[token_usage][total_tokens] 15 assert set(out[token_usage]) set(p.required_fields) def test_target_key_correct(): p P() out p.normalize({prompt_tokens: 1, completion_tokens: 1}) assert token_usage in out # LangSmith 期望的键 def test_total_fallback(): p P() out p.normalize({prompt_tokens: 3, completion_tokens: 4}) assert out[token_usage][total_tokens] 7 def test_target_must_be_token_usage(): with pytest.raises(AssertionError): P(target_keyusage).validate()CI 加一条ChatMistralAI单测必须构造 Mistral usage断言llm_output含标准token_usage且三字段齐全。八、排查清单LangSmith trace 看不到 token→ ChatMistralAI 没把 usage 放到token_usage。usage 放错位置usage/response_metadata→ 必须映射到llm_output.token_usage。total_tokens 缺失→ 用 promptcompletion 补全。字段名是否标准→ 必须是 prompt/completion/total_tokens。是否和 LangSmith schema 对齐→ 用policy.normalize统一。是否有token_usage 标准格式测试→ 必须有。九、小结ChatMistralAI把 Mistral 的原始 usage 放在错误位置/命名如usage、response_metadata且可能漏total_tokens与 LangSmith 期望的llm_output.token_usage标准 schema 不对齐导致 trace 里 token 不可见。根因是缺格式归一化映射。第一层把 usage 映射成标准token_usage并补全 total第二层用LangChainMistralTokenPolicy把输出格式固化成单一事实来源第三层用 pytest 守护格式对齐。token 上报的通用原则模型原始用量必须归一化到可观测平台期望的标准 schema缺字段要补全位置要对。
返回列表