Skip to main content
当您直接调用 LLM,而非通过 LangChain 或 LangSmith 支持的集成 时,需要提供特定的元数据,以便 LangSmith 能够显示 token 计数、计算成本,并允许您在 Playground 中使用正确的提供商和模型打开 运行 一个功能完整的 LLM 追踪有四个要求:
要求操作启用功能
1. 设置 run_type="llm"run_type="llm" 传递给 @traceableLLM 特定渲染、token/成本显示
2. 格式化输入/输出使用 OpenAI、Anthropic 或 LangChain 消息格式结构化消息渲染、Playground 支持
3. 设置 ls_providerls_model_namemetadata 中传递两者成本追踪、Playground 模型选择
4. 提供 token 计数在运行上设置 usage_metadatatoken 计数和成本计算
如果您使用 LangChain OSS、OpenAI 包装器Anthropic 包装器,这些细节会自动处理。本页示例使用 traceable 装饰器/包装器(Python 和 JS/TS 的推荐方法)。如果您直接使用 RunTreeAPI,同样的要求也适用。

消息格式

追踪自定义模型或自定义输入/输出格式时,必须遵循 LangChain 格式、OpenAI completions 格式或 Anthropic 消息格式。更多详情,请参阅 OpenAI Chat CompletionsAnthropic Messages 文档。LangChain 格式如下:
 inputs = {
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Hi, can you tell me the capital of France?"
        }
      ]
    }
  ]
}

outputs = {
  "messages": [
    {
      "role": "assistant",
      "content": [
        {
          "type": "text",
          "text": "The capital of France is Paris."
        },
        {
          "type": "reasoning",
          "text": "The user is asking about..."
        }
      ]
    }
  ]
}

将自定义 I/O 格式转换为 LangSmith 兼容格式

如果您使用自定义输入或输出格式,可以使用 @traceable 装饰器(Python)或 traceable 函数(TS)上的 process_inputs/processInputsprocess_outputs/processOutputs 函数将其转换为 LangSmith 兼容格式。 process_inputs/processInputsprocess_outputs/processOutputs 接受函数,允许您在特定追踪的日志记录到 LangSmith 之前转换其输入和输出。它们可以访问追踪的输入和输出,并可以返回包含处理后数据的新字典。 以下是使用 process_inputsprocess_outputs 将自定义 I/O 格式转换为 LangSmith 兼容格式的模板示例:
class OriginalInputs(BaseModel):
    """您的应用的自定义请求形状"""

class OriginalOutputs(BaseModel):
    """您的应用的自定义响应形状。"""

class LangSmithInputs(BaseModel):
    """LangSmith 期望的输入格式。"""

class LangSmithOutputs(BaseModel):
    """LangSmith 期望的输出格式。"""

def process_inputs(inputs: dict) -> dict:
    """字典 -> OriginalInputs -> LangSmithInputs -> 字典"""

def process_outputs(output: Any) -> dict:
    """OriginalOutputs -> LangSmithOutputs -> 字典"""


@traceable(run_type="llm", process_inputs=process_inputs, process_outputs=process_outputs)
def chat_model(inputs: dict) -> dict:
    """
    您的应用的模型调用。保持您的自定义 I/O 形状。
    装饰器调用 process_* 以记录 LangSmith 兼容格式。
    """

在追踪中识别自定义模型

使用自定义模型时,建议同时提供以下 metadata 字段,以便在查看追踪和 过滤 时识别模型。
  • ls_provider:模型的提供商,例如 "openai""anthropic"
  • ls_model_name:模型的名称,例如 "gpt-5.4-mini""claude-3-opus-20240229"
from langsmith import traceable

inputs = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "I'd like to book a table for two."},
]
output = {
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "Sure, what time would you like to book the table for?"
            }
        }
    ]
}

@traceable(
    run_type="llm",
    metadata={"ls_provider": "my_provider", "ls_model_name": "my_model"}
)
def chat_model(messages: list):
    return output

chat_model(inputs)
如果您实现了自定义流式 chat_model,可以将输出“归约”为与非流式版本相同的格式。这仅在 Python 中受支持:
def _reduce_chunks(chunks: list):
    all_text = "".join([chunk["choices"][0]["message"]["content"] for chunk in chunks])
    return {"choices": [{"message": {"content": all_text, "role": "assistant"}}]}

@traceable(
    run_type="llm",
    reduce_fn=_reduce_chunks,
    metadata={"ls_provider": "my_provider", "ls_model_name": "my_model"}
)
def my_streaming_chat_model(messages: list):
    for chunk in ["Hello, " + messages[1]["content"]]:
        yield {
            "choices": [
                {
                    "message": {
                        "content": chunk,
                        "role": "assistant",
                    }
                }
            ]
        }

list(
    my_streaming_chat_model(
        [
            {"role": "system", "content": "You are a helpful assistant. Please greet the user."},
            {"role": "user", "content": "polly the parrot"},
        ],
    )
)
metadata 中设置 ls_model_name 是 LangSmith 识别模型并计算自定义 LLM 追踪成本所必需的。没有它,token 计数可能仍会被记录,但成本不会被估算。
要了解更多关于如何使用 metadata 字段的信息,请参阅 添加元数据和标签 指南。

提供 token 和成本信息

token 计数支持成本计算,LangSmith 在 追踪项目 UI 中显示。有两种提供方式:
  • 在运行树上设置 usage_metadata:在您的 @traceable 函数内调用 get_current_run_tree() / getCurrentRunTree() 并设置 usage_metadata 字段。这不会改变函数的返回值。
  • 在输出中返回 usage_metadata:在函数返回的字典中包含 usage_metadata 作为顶级键。

支持的 usage_metadata 字段

字段类型描述
input_tokensint总输入/提示 token 数
output_tokensint总输出/补全 token 数
total_tokensint输入 + 输出的总和(可选,可推断)
input_token_detailsobject明细:cache_readcache_creationcache_read_over_200kephemeral_5m_input_tokensephemeral_1h_input_tokensaudiotextimage
output_token_detailsobject明细:reasoningaudiotextimage
要直接发送成本(用于非线性定价),您还可以包含 input_costoutput_costtotal_cost 字段。有关配置模型定价和在 UI 中查看成本的详细信息,请参阅 成本追踪 页面。

首个 token 时间

如果您使用 traceable 或 SDK 包装器之一,LangSmith 将自动填充流式 LLM 运行的首个 token 时间。但是,如果您直接使用 RunTree API,则需要向运行树添加 new_token 事件,以便正确填充首个 token 时间。 以下是示例:
from langsmith.run_trees import RunTree
run_tree = RunTree(
    name="CustomChatModel",
    run_type="llm",
    inputs={ ... }
)
run_tree.post()
llm_stream = ...
first_token = None
for token in llm_stream:
    if first_token is None:
      first_token = token
      run_tree.add_event({
        "name": "new_token"
      })
run_tree.end(outputs={ ... })
run_tree.patch()

相关内容