You need to enable JavaScript to run this app.
文档中心
数据智能体

数据智能体

复制全文
下载 pdf
开发指南
Python SDK 接入指南
复制全文
下载 pdf
Python SDK 接入指南

本文面向在自有网络或私有化环境中接入 Agent 运营分析的 Python 用户,覆盖安装、初始化、Trace 与 Span 上报、常用框架集成、多模态、失败留存、验收和故障排查。

注意事项

本文提供的示例基于bytedance.tea_era 1.1.0+tob.1,支持 Python 3.9 及以上版本。

前提条件

在正式开始接入之前,您需要获取以下参数信息。

  • Agent 运营分析服务根地址
    • SaaS 火山云华北:https://gator.volces.com。
    • 私有化部署:您的私有化服务根地址。
  • Workspace ID、Agent ID
    进入 Agent 运营分析 > 空间管理 > 数据接入,在指定 Agent 内获取空间 ID(Workspace ID)和 Agent ID。
  • API Token
    进入 Agent 运营分析 > 空间管理 > 数据接入,在指定 Agent 内获取 API Token。
    Image
  • 接入过程中,顶层trace_id 请使用 32 位小写十六进制字符串。

开始接入

Python SDK 只保留一个初始化入口 Config(...),您必须显式提供服务根地址和鉴权信息。

接入架构

业务线程只负责结束 Span 并非阻塞入队,实际网络请求由 Dispatcher worker 执行。Native、OpenAI、LangChain、LangGraph 和 OTel 最终共用同一投递链路,因此队列、批量、重试、统计、多模态和失败留存语义一致。
Image

离线安装

统一通过 SDK-only 离线包安装。该包只包含 Agent 运营分析 SDK 自身,不包含任何第三方依赖 wheel;您应在自己的可信制品源和安全治理流程中准备第三方依赖,再把依赖 wheelhouse 与 SDK-only 包一起传入离线环境。

说明

离线附件:​本节附件 era-python-sdk-1.1.0+tob.1-sdk-only.zip 适用于 Linux、macOS、Windows 和 Python 3.9 及以上版本。

SDK 包

License

Notice

era-python-sdk-1.1.0+tob.1-sdk-only.zip
未知大小
LICENSE
未知大小
Third-party software notice.txt
未知大小

交付物与责任边界

内容

SDK 交付方

客户方

ERA SDK wheel

提供并校验 bytedance_tea_era-1.1.0+tob.1-py3-none-any.whl

在目标环境使用 --no-deps 安装

直接依赖范围

提供 requirements/PROFILE.txt 和 dependency-contract.json

根据实际能力选择 profile

第三方wheel与传递依赖

不包含

从客户可信源下载、锁定并保存

平台和ABI兼容性

SDK wheel 为 py3-none-any

确保第三方 wheel 匹配 OS、CPU 和 Python 版本

第三方漏洞和许可证

不替客户选择版本

对最终锁定版本执行漏洞扫描和许可证审查

第三方直接依赖版本限制

以下为 SDK wheel 元数据中的直接依赖范围。您还需让 pip 或依赖锁定工具解析传递依赖,并对最终完整依赖树进行测试和安全治理。

Profile

直接依赖范围

Python

能力

native

cozeloop>=0.1.28,<2.0.0
httpx>=0.23.0,<1.0.0

3.9+

Native、Dispatcher、多模态、DeadLetter

openai

native + openai>=1.0.0,<3.0.0

3.9+

OpenAI 兼容模型接口

otel

native + opentelemetry-sdk>=1.29.0,<2.0.0
opentelemetry-exporter-otlp-proto-http>=1.29.0,<2.0.0

3.9+

OpenTelemetry

langchain

native + langchain-core>=0.3.0,<2.0.0

3.9+

LangChain

langgraph

native + langgraph>=0.2.0,<2.0.0

3.9+

LangGraph

fornax

native + OpenAI、LangChain Core、LangGraph上述范围

3.9+

Fornax 兼容路径

deepagents

native + deepagents>=0.3.12,<0.5.0
langchain-openai>=1.1.0,<2.0.0

3.11+

DeepAgents

all

native + OpenAI + OTel + LangChain + LangGraph

3.9+

常用全集,不含 DeepAgents

步骤一:在联网构建机准备第三方 wheelhouse

联网构建机应与生产离线环境使用相同 OS、CPU 架构和 Python 次版本。不要混用 cp39、cp311、cp312 wheel。

unzip era-python-sdk-1.1.0+tob.1-sdk-only.zip
cd era-python-sdk-1.1.0+tob.1-sdk-only

# 可改为 native/openai/otel/langchain/langgraph/fornax/deepagents
PROFILE=all

python -m pip download \
  --only-binary=:all: \
  --dest ./customer-wheelhouse \
  --index-url https://CUSTOMER_PYPI/simple \
  -r requirements/$PROFILE.txt

--only-binary=:all: 会在任一依赖没有目标平台 wheel 时失败,避免离线环境临时编译源码。若您使用 pip-tools、uv、Poetry 或内部治理平台,应基于相同 profile 生成完整锁定文件并保留 hash。
在干净的同构环境预验证:

python -m venv ./verify-env
source ./verify-env/bin/activate
python -m pip install --no-index \
  --find-links ./customer-wheelhouse \
  -r requirements/$PROFILE.txt
python -m pip check

Windows 激活环境:

python -m venv .\verify-env
.\verify-env\Scripts\Activate.ps1

步骤二:在离线环境安装第三方依赖

python -m venv ./.venv
source ./.venv/bin/activate
python -m pip install --no-index \
  --find-links ../customer-wheelhouse \
  -r requirements/all.txt
python -m pip check

仅使用 Native 时替换为 native.txt;其他能力使用对应 profile。DeepAgents 必须使用 Python 3.11 及以上。

步骤三:使用 --no-deps 安装 SDK

推荐安装器先检查 profile 直接依赖和版本范围,再以 --no-deps 安装 SDK,最后执行版本检查和 pip check:

./install.sh --profile all
powershell -ExecutionPolicy Bypass -File .\install.ps1 --profile all

手动安装:

python -m pip install --no-deps \
  ./bytedance_tea_era-1.1.0+tob.1-py3-none-any.whl
python -m pip check
python -c "from bytedance import tea_era as era; print(era.__version__)"

预期版本为 1.1.0+tob.1。

步骤四:安装后验证

python -c "from bytedance import tea_era as era; print(era.__version__)"
python -c "import openai; print('openai ok')"
python -c "import opentelemetry.sdk; import bytedance.tea_era.otel; print('otel ok')"
python -c "import langchain_core, langgraph; print('frameworks ok')"

随后使用测试 Workspace 和 32 位 hex trace_id运行本文最小可运行示例,确认 flush.ok=True、failed=0、pending=0、close.ok=True,并在产品页面核对 Span 数量和父子关系。

常见安装问题

问题或报错

解决方案

缺少依赖

安装器会显示缺少的直接依赖和范围。回到联网构建机重新生成您的 wheelhouse,不要让离线机器连接公网补包。

No matching distribution found

通常是 wheelhouse 与目标 OS、CPU 或 Python 次版本不匹配,或某依赖没有二进制wheel。不要使用 --ignore-requires-python,也不要强制跨 ABI 安装。

pip check失败

说明您选择的第三方版本或传递依赖不一致。SDK-only 安装器不会自动修改环境,应回到依赖锁定阶段解决。

安全扫描结果不同

SDK-only 包不携带第三方依赖,最终漏洞结果取决于您的实际锁定版本。您应对完整环境生成 SBOM,并在每次升级后重新扫描。

初始化

from bytedance import tea_era as era

client = era.Client(era.Config(
    workspace_id="CUSTOMER_WORKSPACE_ID",
    agent_id="CUSTOMER_AGENT_ID",
    base_url="https://CUSTOMER_ERA_HOST",
    api_token="CUSTOMER_API_TOKEN",
    auth_mode=era.AuthMode.BEARER,
    service_name="customer-agent-service",
))

参数

是否必填

说明

workspace_id

是

Agent 运营分析中对应的空间 ID。

说明

进入 Agent 运营分析 > 空间管理 > 数据接入,在指定 Agent 内获取空间 ID(Workspace ID)、Agent ID 和 API Token。

agent_id

是

Agent 运营分析中对应的 Agent ID。

base_url

是

HTTPS 服务根地址。不要填写完整 ingest path、query、fragment 或 userinfo。

  • SaaS 火山云华北:https://gator.volces.com。
  • 私有化部署:您的私有化服务根地址。

api_token

Bearer 模式必填

SDK 发送 Authorization: Bearer TOKEN。AuthMode.NONE 时必须为空。

service_name

否

用于多服务检索和运行时标签。

推荐通过环境变量注入:

export ERA_WORKSPACE_ID=CUSTOMER_WORKSPACE_ID
export ERA_AGENT_ID=CUSTOMER_AGENT_ID
export ERA_BASE_URL=https://CUSTOMER_ERA_HOST
export ERA_API_TOKEN=CUSTOMER_API_TOKEN
export ERA_AUTH_MODE=bearer
from bytedance import tea_era as era

client = era.Client(era.config_from_env())

私有 CA、代理和环境代理继承可分别使用 ERA_CA_BUNDLE、ERA_PROXY 和 ERA_TRUST_ENV。生产环境不要关闭 TLS 校验。若传入自定义 httpx.Client,TLS、代理和 Client 关闭责任归调用方,不能再同时配置 SDK 管理的 CA/代理参数。

上报数据

身份字段

字段

含义

建议

user_id

业务用户标识。

使用稳定、非敏感的内部用户 ID。

thread_id

一段连续会话;同一会话可包含多个 Trace。

使用 conversation/session/ticket ID,同一会话保持不变。

trace_id

一次完整请求或 Agent run。

使用 secrets.token_hex(16) 生成 32 位小写 hex。

span_id

Trace 内的一个操作步骤。

由 SDK 生成,不需要业务侧指定。

message_id

可选业务消息 ID。

若业务原始 ID 不是 32 位 hex,请放这里或自定义 tag,不要直接作为顶层 trace_id。

默认 require_trace_config=True。根 Trace 缺少 user_id 或 thread_id 时,SDK 会创建 NoOp Span 并拒绝上报。无会话概念的单次任务可以把 request ID 同时作为 thread_id。

最小可运行示例

import secrets
from bytedance import tea_era as era

client = era.Client(era.Config(
    workspace_id="CUSTOMER_WORKSPACE_ID",
    agent_id="CUSTOMER_AGENT_ID",
    base_url="https://CUSTOMER_ERA_HOST",
    api_token="CUSTOMER_API_TOKEN",
))

trace_id = secrets.token_hex(16)
trace = client.new_trace(era.TraceConfig(
    user_id="customer-user-123",
    thread_id="conversation-456",
    trace_id=trace_id,
    message_id="customer-message-789",
    tags={"biz_scene": "customer_service"},
))

root = trace.agent_span("agent_request").set_input({
    "query": "帮我查询订单状态",
})

tool = (
    trace.tool_span("query_order", parent=root)
    .set_input({"order_id": "order-123"})
    .set_output({"status": "shipped"})
    .set_tag("tool_name", "query_order")
    .finish()
)

root.set_output({
    "answer": "订单已发货",
    "tool_span_id": tool.span_id,
}).finish()

result = client.flush(timeout=30)
print(trace_id, result.ok, result.exported, result.failed)

close_result = client.close(timeout=30)
print(close_result.ok, close_result.closed)

常用 Span 类型包括 agent、prompt、model、tool、retriever、skill、embedding、chain、graph 和 custom。根 Span 推荐使用 agent,其 parent_id 为 0。

上报流程与结果语义

Image
业务线程结束 Span 后仅执行冻结和非阻塞入队。Dispatcher 按 item 数和字节数限制队列,worker 批量发送;DNS、连接、代理、超时、连接重置、HTTP 408/429/5xx 可按预算重试,TLS、鉴权、其他4xx、序列化和非法响应等终态错误不重试。
flush() 等待调用前 checkpoint 对应的网络投递与死信任务,并返回结构化结果。close() 停止接收新 Span、排空队列并关闭 SDK 自建资源;应在进程退出前调用。主统计始终满足:

accepted = exported + dropped + failed + pending

exported 表示接收端返回成功协议响应,不等同于 Trace 已完成异步落库和产品索引。正式验收还需使用 exact trace_id 到产品页面确认 Span 数量和父子关系。

健康检查与诊断

snapshot = client.snapshot()
health = client.health()
diagnosis = client.diagnose(smoke=False)

print(snapshot.conserved)
print(health.status, health.reasons)
print(diagnosis)

health() 是只读本地检查,不发网络请求。diagnose(smoke=True) 会额外发送一个无业务载荷的最小 Span,仅在明确需要网络诊断时使用。诊断结果不会输出 API Token、Authorization 或完整业务 payload。

Span 上报规范

规范要求说明

  • 必须:任何场景均应上报;缺失会导致 Trace 无法串联、检索、归属或正确解析。
  • 条件必须:满足字段说明中的适用条件时必须上报;不满足条件时可以不报。
  • 推荐:原则上应上报;缺失不影响基础解析,但会降低排查、分析或跨框架映射能力。
  • 可选:业务可自主选择是否上报;缺失不影响 Trace 基础解析与核心分析。

关键 span_type

ERA 的规范关键 span_type 支持以下几种:

span_type

说明

Root

Root 表示 Trace 的开始节点,判断方式是 parent_id="0" 或为空。Root 是拓扑角色,不是固定的 span_type;一次 Agent 运行的入口推荐使用 agent。

prompt

Prompt 组装、模板渲染、变量填充。

model

LLM / 多模态模型调用。Trace 中有模型调用时必须上报。

embedding

向量化(Embedding)调用。将文本、图片等输入转换为向量表示时必须上报。

tool

当 model output 存在 tool call,或业务实际调用工具 / API 时必须上报。

agent

一次 Agent 运行、子 Agent、任务编排节点。入口 Span 推荐使用 agent。

retriever

RAG、知识库检索、搜索召回。

skill

一次 Skill 调用,记录 Skill 的输入参数与最终产物(contents / result)。

cli

命令行程序(短生命周期进程)执行

chain

工作流 / 编排流程,把多个步骤(检索、模型、工具等子 Span)串联的"编排容器"节点

系统保留 tag

以下 tag key 在 ERA 中具有固定语义,推荐通过 SDK 提供的方法或约定字段写入,避免用不同类型重复上报:

参数

概念

规范要求

space_id

每个 Span 节点都必须传入,ERA 业务空间标识

必须

agent_id

每个 Span 节点都必须传入,ERA agent标识

必须

thread_id

一次连续会话,例如:用户和Agent的多轮聊天。
每个 Span 节点都必须传入,用于标识上报数据所属的会话(多问多答),如果业务上在TEA中有业务语意的会话id,那么推荐这个值设置为业务语意的会话id,这样在与GUI事件关联时可以关联分析

必须

trace_id

全局唯一,用于标识一次完整的一问一答。
每个 Span 节点都必须传入,用于标识上报数据所属的对话(一问一答),如果业务上在TEA中有业务语意的对话id,那么推荐这个值设置为业务语意的对话id,这样在与GUI事件关联时可以关联分析
ERA trace_id 可使用业务对话 ID 以便 TEA 联查;若 OTel/W3C trace_id 不同,同时保留 otel.trace_id / traceparent,避免跨服务链路丢失。

必须

user_id

每个 Span 节点都必须传入,如果用户自己没有在 Span 中上报 user_id,则需要额外传入,用于标识终端用户,如果业务上在TEA中有业务语意的用户id,那么上报时推荐这个值设置为业务语意的用户id,这样在与GUI事件关联时可以关联分析

必须

span_id

操作单元 ID。在同一个 Trace 内唯一,用于标识一个具体的操作步骤(如一次模型调用、一次工具调用等)。

必须

parent_id

父操作单元 ID。指向当前 Span 的直接上游 Span。通过 parent_id 和 span_id,可以构建出完整的调用树。对于根 Span (root),此字段通常为空或为 0。

必须

span_type

Span 类型。标识了该操作单元的性质

必须

span_name

Span 名称。更具体地描述 Span 的功能,例如 span_type 为 tool 时,span_name 可能是具体的工具名 weather.get_forecast。
低基数约束(全局):span_name 只允许使用稳定的逻辑名称,禁止拼接用户输入、订单号、UUID、时间戳等动态实例值;动态值应放入 tag。
正例:get_order_status
反例:get_order_status:A1024、summarize_doc_3f8a91

必须

start_time

开始时间,单位:微秒(μs)

必须

duration

持续时长,单位:微秒(μs)

必须

status_code

状态码。标识 Span 的执行结果。通常 0 或 200 代表成功,其他非零值代表不同类型的错误。

必须

error_type

错误类型。当 status_code 非 0 时条件必须上报。用于对错误进行分类聚合与统计。
允许值枚举:model_error
业务可自定义扩展,格式须为 namespace.error_name(如 billing.quota_exceeded),避免与系统枚举冲突。

rate_limit
条件必须

error

错误描述。当 status_code 非 0 时条件必须上报。人类可读的错误信息,用于排障定位。禁止包含 PII / 密钥等敏感信息,敏感内容须脱敏。

条件必须

input/output

输入与输出。以 JSON 字符串形式记录了 Span 的输入参数和返回结果。对于 model 类型的 Span,这通常是 Prompt 和模型的回复。

必须

latency_first_resp

流式调用模型时,从 Span start_time 到首包返回的相对耗时,单位:微秒(μs)。注意:该值为相对时长(duration),不是绝对时间戳。例如首包在 Span 开始后 160ms 返回,则 latency_first_resp = 160000。

条件必须

input_tokens

输入token数

条件必须

output_tokens

输出token数

条件必须

total_tokens

总 token 数,通常等于 input_tokens + output_tokens。

条件必须

agent_version

agent版本号

可选

ds_agent_id

子agent_id,主要用于era子agent分析场景

可选

Trace 连续性

一条 Trace 由 trace_id 串联,Span 之间通过 span_id / parent_id 表达父子关系。

字段

类型

规范要求

说明

trace_id

string

必须

单次请求链路 ID,支持业务自定义。如需要和TEA GUI事件联合分析,trace_id需要和TEA中的对话id保持一致

span_id

string

必须

当前 Span ID,由 SDK 生成或业务传入。

parent_id

string

必须

根 Span 的 parent_id 为 "0" 或为空;其他 Span 必须指向直接父 Span。同一业务 Trace 必须且只能有一个预期根节点。

span

入口 Span

入口 Span 表示一次用户请求或一次 Agent 运行的入口。推荐使用 span_type = "agent",并设置 parent_id = "0"。
一条 Trace 必须且只能有一个 Root Span;若继承了上游 span_id,当前 Span 不再是 Root Span

tags

下面是入口Span常用的tag定义,您应该组合系统保留tag一起使用。

Key

Desc

规范要求

parent_id

父 Span ID,root span的parent_id推荐为0

必须

span_type

可以自定义

必须

span_name

可以自定义

必须

start_time

Trace 开始时间

必须

duration

Trace 端到端执行耗时

条件必须

status_code

本次 Trace 的最终执行状态,0和200为成功,其他为失败

必须

input

本次请求或 Agent 运行的输入,推荐格式如下

条件必须

output

本次请求或 Agent 运行的最终输出,推荐格式如下

条件必须

error_type

错误类型。当 status_code 非 0 时条件必须上报。枚举值参见系统保留 tag 中的 error_type 定义。

条件必须

error

人类可读的错误描述信息,用于排障定位。

条件必须

latency_first_resp

从 Trace 开始到首次向用户返回有效响应的耗时

推荐

input

Key

Desc

Example

contents

本次请求或 Agent 运行的输入内容,按顺序排列。
类型: Content 列表。支持 text / image / file / audio / video / json,多种类型可混排;数组顺序必须与原始输入或输出顺序一致。

{
  "contents": [
    {
      "content_type": "text",
      "text": "帮我看下这张报销单能不能通过审批"
    },
    {
      "content_type": "image",
      "image": {
        "url": "https://example.com/receipt.png",
        "name": "receipt.png"
      }
    }
  ]
}

output

Key

Desc

Example

contents

本次请求或 Agent 运行最终返回给用户的输出内容。
类型: Content 列表。支持 text / image / file / audio / video / json,多种类型可混排;数组顺序必须与原始输入或输出顺序一致。

{
  "contents": [
    {
      "content_type": "text",
      "text": "这张报销单金额 328 元、类目为『差旅-市内交通』,票据信息完整且符合报销规范,可以直接提交审批。"
    }
  ]
}
  • content
    Content 通用约束
    Content 是 Root / Agent / Skill / Chain 等边界 Span 复用的多模态内容结构。Model Span 可继续使用 Message 协议,并由适配层映射为 Content;Retriever、Tool、CLI 等已有专用输入输出结构时不强制使用 Content。
    媒体与文件优先使用 url 或 reference_id,;鉴权参数、密钥和 PII 必须脱敏。单项截断使用 truncated,整体结果不完整使用 output.partial;已有 arguments / result 等正式字段时,不应在 json Content 中重复上报。

  • Discriminated Union 规则
    Content 是以 content_type 为判别字段(discriminator)的 tagged union。校验规则如下:

    #

    规则

    说明

    1

    判别字段必填

    每个 Content 项必须包含 content_type

    2

    载荷字段一一对应

    content_type 的值决定唯一合法的载荷字段名:text → text、image → image、file → file、audio → audio、video → video、json → json

    3

    互斥

    同一 Content 项中禁止出现多个载荷字段(如同时有 text + image)

    4

    资源定位二选一

    媒体类型(image/file/audio/video)的载荷对象中,url 与 reference_id 至少存在一个,可同时存在;两者均缺时校验不通过

    5

    截断标记

    任何载荷若经过截断/摘要处理,必须设置 truncated: true;未设置时默认为完整内容

  • 通用媒体字段(适用于 image / file / audio / video)
    以下字段在所有媒体类型的载荷对象中通用:

    字段

    类型

    规范要求

    说明

    url

    string

    条件必须

    资源的可访问 URL(HTTP/HTTPS)。与 reference_id 至少存在一个

    reference_id

    string

    条件必须

    资源的平台内部引用 ID(如文件系统 ID、OSS key)。与 url 至少存在一个;适用于资源已在平台内部存储、无需外部 URL 的场景

    name

    string

    推荐

    资源原始文件名

    mime_type

    string

    推荐

    MIME 类型(如 image/png、application/pdf、audio/mpeg)。未提供时由消费方按扩展名推断

    truncated

    boolean

    条件必须

    是否经过截断/摘要处理。为 true 表示该项内容不完整,默认 false(完整)。注意与 output.partial(整体输出不完整)的区别:truncated 是单项级别

Key

Desc

Example

content_type
必须

当前 Content 项的数据类型,决定该项使用哪个载荷字段。每个 Content 必须且只能包含一种与 content_type 对应的载荷字段。
类型: string
允许值:

  • text - 纯文本类型
  • image - 图片内容类型
  • file - 文件内容类型
  • audio - 音频内容类型
  • video - 视频内容类型
  • json - 结构化 JSON 类型
{
    "content_type": "text",
    .....
}

text

content_type = "text"

纯文本内容。
类型: string
举例: "你好"

{
    "content_type": "text",
    "text": "帮我查一下订单 order_123 的物流状态"
}

image

content_type = "image"

图片内容。
类型:object
url 与 reference_id 至少存在一个;name、mime_type、truncated 可选。

type Image struct {
    Url         string `json:"url,omitempty"`
    ReferenceId string `json:"reference_id,omitempty"`
    Name        string `json:"name,omitempty"`
    MimeType    string `json:"mime_type,omitempty"`
    Truncated   bool   `json:"truncated,omitempty"`
}
{
    "content_type": "image",
    "image": {
        "url": "https://example.com/receipt.png",
        "reference_id": "img_a1b2c3",
        "name": "receipt.png",
        "mime_type": "image/png"
    }
}

file

content_type = "file"

文件内容。
类型:object
url 与 reference_id 至少存在一个;name、suffix、mime_type、truncated 可选。

type File struct {
    Url         string `json:"url,omitempty"`
    ReferenceId string `json:"reference_id,omitempty"`
    Name        string `json:"name,omitempty"`
    Suffix      string `json:"suffix,omitempty"`
    MimeType    string `json:"mime_type,omitempty"`
    Truncated   bool   `json:"truncated,omitempty"`
}
{
    "content_type": "file",
    "file": {
        "url": "https://example.com/report.pdf",
        "reference_id": "file_x7k9m2",
        "name": "report.pdf",
        "suffix": "pdf",
        "mime_type": "application/pdf"
    }
}

audio
条件必须:content_type = "audio"

音频内容。
类型:object
url 与 reference_id 至少存在一个;name、mime_type、duration_ms 可选。

{
    "content_type": "audio",
    "audio": {
        "url": "https://example.com/audio.mp3",
        "name": "audio.mp3",
        "mime_type": "audio/mpeg",
        "duration_ms": 120000
    }
}

video
条件必须:content_type = "video"

视频内容。
类型:object
url 与 reference_id 至少存在一个;name、mime_type、duration_ms、width、height 可选。

{
    "content_type": "video",
    "video": {
        "url": "https://example.com/video.mp4",
        "name": "video.mp4",
        "mime_type": "video/mp4",
        "duration_ms": 30000,
        "width": 1920,
        "height": 1080
    }
}

json
条件必须:content_type = "json"

结构化 JSON 内容。
类型:JSON value,支持 object / array / string / number / boolean / null。
json 必须直接存放原生 JSON 值,不得再次序列化为 JSON string。已有 arguments、result 等正式字段时,不应重复上报。

{
    "content_type": "json",
    "json": {
        "order_id": "order_123",
        "status": "paid"
    }
}

Prompt Span

Prompt Span 表示 Prompt 模板渲染、变量填充或上下文组装。

tags

常用span定义:

Key

Desc

规范要求

span_type

prompt

必须

span_name

可以自定义

必须

prompt_provider

prompt平台,如fornax、langsmith

推荐

prompt_key

prompt唯一的key

推荐

prompt_version

Prompt版本号

推荐

input

Key

Desc

Example

templates

Prompt 模板内容(字符串),可含 {{变量}} 占位符,由 arguments 填充。

{
  "templates": "你是一个客服助手,请根据知识库回答用户问题。当前用户等级:{{user_level}},用户问题:{{query}}",
  "arguments": [
    {
      "key": "query",
      "value": "帮我查订单 order_123 的物流状态",
      "source": "user_input"
    },
    {
      "key": "user_level",
      "value": "vip",
      "source": "user_profile"
    }
  ]
}

arguments

Prompt 模板中的参数。
类型: argument数组。具体参考下面: argument

  • argument

    Key

    Desc

    key

    参数名

    value

    参数值。

    source

    参数来源(自由字符串,用于标注取值出处)。常见取值:user_input(用户输入)、user_profile(用户画像)、system(系统)、tool(工具返回)等。

output

渲染后的 Prompt 内容:

{
  "prompt": "你是一个客服助手,请根据知识库回答用户问题。当前用户等级:vip,用户问题:帮我查订单 order_123 的物流状态"
}

Model Span

Model Span 表示一次模型调用。

tags

常用span定义:

Key

Desc

规范要求

span_type

model

必须

span_name

可以自定义

必须

model_name

模型名称

推荐

model_platform

模型所在的推理平台 / 供应商,例如:火山方舟、OpenAI、内部推理网关等。

推荐

input_tokens

输入token数

条件必须

output_tokens

输出token数

条件必须

total_tokens

本次调用消耗的总 token 数,等于 input_tokens + output_tokens。

条件必须

reasoning_tokens

推理消耗token数

推荐

input_cached_tokens

输入中命中 KV Cache(缓存)的 token 数,该部分通常计费更低。

推荐

latency_first_resp

首包耗时,单位:微秒(μs)

推荐

call_options

调用参数

推荐

input

输入。
符合下面 input 定义的 JSON object。协议层为原生 JSON value,仅在传输层(如 HTTP body / Protobuf string 字段)按需序列化为 string。

条件必须

output

输出。
符合下面 output 定义的 JSON object。协议层为原生 JSON value,仅在传输层按需序列化为 string。

条件必须

call_options

Key

Desc

temperature

回复随机性。
类型: float。

max_tokens

模型回答的最大 token 数量。
类型:int

stop

停止词表。
类型:string 列表。

top_p

核采样(nucleus sampling)阈值,只在累计概率达到 top_p 的候选集中采样,取值范围 0~1。
类型:float。

n

模型生成的候选回复数量,对应 output.choices 的长度。
类型:int

top_k

采样时只保留概率最高的 k 个候选 token。
类型:int

presence_penalty

存在惩罚:对已出现过的 token 施加惩罚,值越大越鼓励模型谈论新话题,取值范围一般为 -2~2。
类型:float。

frequency_penalty

频率惩罚:按 token 出现频率施加惩罚,值越大越抑制重复内容,取值范围一般为 -2~2。
类型:float。

reasoning_effort

推理强度档位,控制模型思考深度,常见取值 low / medium / high。
类型:string 。

input

Key

Desc

Example

messages

消息内容。
类型: message 列表

{
"messages": [
    {
      "role": "user",
      "content": "北京今天天气怎么样?"
    }
  ]
}

tools

可调用的 Tool 列表。
类型: tool 列表。详细见: tool

{
"tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "查询指定城市的实时天气",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string",
              "description": "城市名称,例如:北京"
            }
          },
          "required": ["city"]
        }
      }
    }
  ]
}

tool_choice

用于控制模型是否可以或必须调用工具,以及调用哪个工具
类型: tool_choice。详细见: tool_choice

{
"tool_choice": {
    "type": "function",
    "function": {
      "name": "get_weather"
    }
  }
}
  • tool
    tool注册表,用于提供给Model的Input中,作为可以被调用的tool的列表。

    Key

    Desc

    type

    tool类型。
    类型: string
    固定值: "function"

    function

    function 描述。
    类型: function 对象。详细见: tool.function

    • tool.function

      Key

      Desc

      name

      函数名,不应为空。
      类型: string
      举例: "my_function"

      description

      Function 描述。
      类型: string

      parameters

      参数说明。
      类型: JSON schema 格式的对象。

  • tool_choice

    Key

    Desc

    type

    Tool 调用方式。
    类型: string
    可能值: none auto required function

    function

    Function 描述。Type 为 function 时使用。
    类型: function 对象。详细见: message.tool_calls[*].function,但是只需要填写name字段

message

Key

Desc

Example

role

消息对应的角色,不应为空。
类型: string
允许值:

  • user 用户输入的消息
  • system 系统消息
  • assistant
  • tool 工具调用
{
  "messages": [
    {
"role": "system",
      "content": "你是一个天气助手,可调用工具查询实时天气。"
    }
  ]
}

content

消息内容。
类型: string

{
  "messages": [
    {
      "role": "system",
"content": "你是一个天气助手,可调用工具查询实时天气。"
    }
  ]
}

reasoning_content

模型可观测的推理内容或摘要(可选)。与最终回复 content 区分。不承诺所有模型均提供完整 CoT——模型若仅返回摘要或不支持推理输出,接入方无需填充。该字段沿用 input/output 相同的字段级隐藏、动态 Masking 及空间/角色权限策略。
类型: string

{
  "messages": [
    {
      "role": "assistant",
      "content": "北京今天晴,气温 18~26℃。",
      "reasoning_content": "用户想知道北京天气,需要先调用 get_weather 获取实时数据,再整理成自然语言回复。"
    }
  ]
}

parts

多模态的消息内容。
类型: part 列表。详细见:message.parts[*]

{
  "messages": [
    {
      "role": "system",
      "content": "你是一个天气助手,可调用工具查询实时天气。"
    },
    {
      "role": "user",
"parts": [
        {
          "type": "text",
          "text": "看看这张照片是哪个城市,顺便告诉我那里今天的天气"
        },
        {
          "type": "image_url",
          "image_url": {
            "url": "https://example.com/city.jpg"
          }
        }
      ]
    }
  ]
}

name

消息名,可为空。
(beta)目前只使用在Tool Message中,作为Tool的Name。
类型: string

-

tool_calls

Tool 调用列表,用于 assistant role 的消息。
类型: tool_call 列表

{
  "messages": [
    {
"role": "assistant",
      "content": "",
"tool_calls": [
        {
          "id": "call_001",
          "type": "function",
          "function": {
            "name": "get_weather",
            "arguments": "{\n  \"city\": \"北京\"\n}"
          }
        }
      ]
    }
  ]
}

tool_call_id

Tool Call ID,用于标识某一次需要进行/已经执行的tool call。
常见场景:Model output.tool_calls指示需要调用某个tool、调用参数、tool_call_id;在Tool节点调用具体的tool,携带tool_call_id。
类型: string

-

Message 条件约束——字段必填性与互斥规则随 role 变化,上报时须满足以下条件:

条件

必填字段

说明

role = tool

tool_call_id

必须关联触发该工具执行的 Model output 中对应的 tool_calls[].id,否则 Trace 链路断裂

role = assistant 且含 tool_calls

tool_calls[].id
tool_calls[].function.name
tool_calls[].function.arguments

三字段缺一不可;下游 Tool Span 依赖 id 做关联,name/arguments 为回放必需

content 与 parts 同时出现

-

允许并存。若两者均有值,消费端以 parts 为权威来源,content 视为纯文本摘要/降级兼容;禁止将同一内容在两处重复上报(即 content 不可是 parts 中文本的拼接副本)

仅有 content

-

适用于纯文本消息(最常见场景);无需填 parts

仅有 parts

-

适用于多模态或结构化消息;content 可留空或省略

  • message.parts[*]

    Key

    Desc

    type

    内容类型。
    类型: string
    允许值:

    • text
    • image_url
    • file_url
    • audio_url
    • video_url

    text

    文本内容。
    类型: string

    image_url

    图片内容。
    类型: image_url 结构。详细见: message.parts[*].image_url

    file_url

    文件内容。
    类型: file_url 结构。详细见: message.parts[*].file_url

    audio_url

    音频内容。
    类型: audio_url 结构。详细见: message.parts[*].audio_url

    video_url

    视频内容。
    类型: video_url 结构。详细见: message.parts[*].video_url

    signature

    用于校验 Text 块 / 多模态块 / tool_call 完整性的签名标识。类型: string。部分模型(如 Gemini 3)会返回。

    • message.parts[*].image_url

      Key

      Desc

      name

      图片名

      url

      图片文件地址或 base64 编码的图片信息。
      类型: string

      detail

      控制如何处理图片
      类型: string
      允许值:

      • "auto" (默认值)
      • "low"
      • "high"
    • message.parts[*].file_url

      Key

      Desc

      name

      附件名

      url

      附件文件地址或 base64 编码的文件信息。
      类型: string

      detail

      暂时无用

      suffix

      后缀名

    • message.parts[*].audio_url

      Key

      Desc

      name

      音频名

      url

      音频文件地址或 base64 编码的音频信息。
      类型: string

    • message.parts[*].video_url

      Key

      Desc

      name

      视频名

      url

      视频文件地址或 base64 编码的视频信息。
      类型: string

    • message.tool_calls[*]
      模型指示要调用的tool和调用信息。

      Key

      Desc

      id

      Tool 的 ID。
      类型: string

      type

      Call 类型。
      类型: string
      固定值: "function"

      function

      调用的 Function 对象,不应为空。
      类型: function,详细见: message.tool_calls[*].function

      signature

      用于校验 tool_call 完整性的签名标识。类型: string。部分模型(如 Gemini 3)会返回。

  • message.tool_calls[*].function

    Key

    Desc

    name

    被调用的 Function 名,不应为空。
    类型: string
    举例: "my_function"

    arguments

    调用参数,不应为空。
    类型: JSON 格式的 string

output

Key

Desc

Example

choices

Choice 列表。
类型: choice列表。详细见: choice

{
  "id": "resp_cdbwb423432cwd3cdxxxxchoice",
"choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "北京今天晴,气温 18~26℃。"
      }
    }
  ]
}

id

responseAPI场景中,用于标识本地请求的id

resp_cdbwb423432cwd3cdxxxx

  • choice

    Key

    Desc

    finish_reason

    停止原因。
    类型: string
    值可能为:

    • "stop":最终停止
    • "length"
    • "content_filter"
    • "tool_calls":需要调用tool,这是一般伴随着返回了tool_calls的结构(包含需要调用tool的名字和希望调用的参数)

    index

    Choice 序号。
    类型:int

    message

    输出内容。
    类型: message。详细见上面的message定义

    当模型决定调用工具时,finish_reason 为 tool_calls,message 内携带 tool_calls:

    {
      "id": "resp_cdbwb423432cwd3cdxxxx",
      "choices": [
        {
          "index": 0,
          "finish_reason": "tool_calls",
          "message": {
            "role": "assistant",
            "content": "",
            "tool_calls": [
              {
                "id": "call_001",
                "type": "function",
                "function": {
                  "name": "get_weather",
                  "arguments": "{\"city\":\"北京\"}"
                }
              }
            ]
          }
        }
      ]
    }
    

Embedding Span

Embedding Span 表示一次向量化(Embedding)调用,将文本、图片等输入转换为稠密向量表示。常见场景包括:RAG 索引构建时的文档切片向量化、检索时的 query 向量化、语义相似度计算等。

tags

Key

Desc

规范要求

span_type

embedding

必须

span_name

Embedding 操作名,推荐 embed_query / embed_documents / embed_image 等

必须

model_name

Embedding 模型名称,例如 text-embedding-3-small、bge-large-zh

推荐

model_platform

模型所在的推理平台 / 供应商,例如:火山方舟、OpenAI、内部推理网关等。

推荐

input_tokens

输入 token 数

条件必须

total_tokens

本次调用消耗的总 token 数

条件必须

embedding_dimension

输出向量维度,例如 1536、1024

推荐

input

输入。符合下面 input 定义的 JSON object。协议层为原生 JSON value,仅在传输层按需序列化。

条件必须

output

输出。符合下面 output 定义的 JSON object。协议层为原生 JSON value,仅在传输层按需序列化。

条件必须

input

Embedding 输入:待向量化的内容列表及编码参数。

Key

Desc

规范要求

texts

待向量化的文本列表,类型 string[]

条件必须(文本场景)

images

待向量化的图片 URL 列表,类型 string[]

条件必须(多模态场景)

call_options

本次调用生效的参数,类型 object

推荐

{
  "texts": [
    "如何查询订单物流状态",
    "退货流程是什么"
  ],
  "call_options": {
    "encoding_format": "float",
    "dimensions": 1536
  }
}

call_options

Key

Desc

encoding_format

向量编码格式,如 float、base64。类型:string

dimensions

输出向量维度(部分模型支持动态维度)。类型:int

input_type

输入类型标识,如 query、document。类型:string

output

Embedding 输出:向量化结果及用量信息。

Key

Desc

规范要求

embeddings

向量列表,每个元素包含 index 和 vector(或摘要信息),类型 object[]

条件必须

count

本次返回的向量数量,类型 int

推荐

usage

token 用量汇总,类型 object

推荐

{
  "embeddings": [
    {
      "index": 0,
      "vector_dim": 1536,
      "vector_preview": [0.0123, -0.0456, 0.0789, "..."]
    },
    {
      "index": 1,
      "vector_dim": 1536,
      "vector_preview": [0.0321, 0.0654, -0.0987, "..."]
    }
  ],
  "count": 2,
  "usage": {
    "input_tokens": 24,
    "total_tokens": 24
  }
}

注意

output 中 embeddings[*].vector 完整向量通常较大(数千浮点数),实际上报时推荐只记录维度 (vector_dim) 和前几位预览 (vector_preview),避免 Span 体积膨胀。如需完整向量,建议以外部存储引用方式记录。

Tool Span

Tool Span 表示一次工具调用。

tags

Key

Desc

规范要求

span_type

tool

必须

span_name

tool的name

必须

tool_call_id

对应上次Model output返回的tool_call的tool_call_id

推荐

input

工具入参,通常是模型在 tool_calls.arguments 里给出的参数(JSON object;协议层为原生对象,仅传输层按需序列化为 string):

{
  "tool_call_id": "call_001",
  "name": "get_weather",
  "arguments": {
    "city": "北京"
  }
}

output

工具执行成功的返回:

{
  "tool_call_id": "call_001",
  "city": "北京",
  "weather": "晴",
  "temperature": "18~26℃",
  "humidity": "45%",
  "updated_at": "2026-07-13T14:00:00+08:00"
}

工具执行失败时,推荐在 output 中记录错误信息,并将 Span 的 status_code 置为非 0,同时上报 error_type 和 error

Skill Span

Skill Span 表示一次 Skill(独立能力单元)的调用与执行,Skill 内部产生的模型调用、工具调用应通过子 Span 独立记录,不在 Skill Span 中重复上报。

tags

Key

Desc

规范要求

span_type

skill

必须

span_name

Skill 名称

必须

skill.id

Skill id

推荐

skill.version

Skill 版本,存在版本信息时推荐上报

推荐

skill.source

Skill 来源,枚举:builtin / local / plugin / remote

推荐

skill.trigger

本次 Skill 被激活的直接原因,枚举:user / rule / model / system;多因素并存时记录最直接来源

推荐

skill.operation

操作类型,推荐 invoke;观测加载过程时可用 load

推荐

skill.trigger 记录导致本次 Skill 被激活的直接原因(而非来源或执行方式)。多个因素并存时记录最直接的决定来源,例如用户点名后由模型执行,应记 user 而非 model。四个枚举含义如下:

枚举值

含义

典型场景

示例

user

用户明确指定使用某个 Skill

用户通过命令、名称或 UI 手动选择 Skill

用户输入「使用 code-review skill 审查代码」

rule

Agent Runtime 根据预定义的确定性规则匹配并激活 Skill

根据文件类型、任务类型、关键词或路由配置自动匹配,不经过模型决策

检测到输入是 PDF,规则自动激活 pdf-processing

model

模型根据当前任务和 Skill 描述,自主判断需要使用该 Skill

模型读取可用 Skill 的名称和描述后进行选择

模型判断当前任务是代码审查,选择 code-review

system

平台或 Agent 配置默认、强制激活 Skill

Skill 是内置能力、全局默认能力,或由安全和合规策略强制启用

所有请求都自动启用 data-redaction,模型和用户都不能关闭

input

Skill 的边界输入:父节点实际交给 Skill 的任务、材料与执行参数。

Key

Desc

规范要求

contents

传给 Skill 的任务内容和输入材料,类型 Content[](复用通用 Content,支持 text/image/file/json)

推荐

arguments

Skill 本次实际生效的结构化参数,类型 object,不记录默认配置全集

可选

约束:contents 与 arguments 至少存在其一,否则 input 语义不完整。arguments 中的敏感值(密钥、token、PII 等)应脱敏或以引用/哈希代替明文。

{
  "contents": [
    {
      "content_type": "text",
      "text": "请检查这段代码中的安全问题"
    },
    {
      "content_type": "file",
      "file": {
        "url": "https://example.com/main.go",
        "name": "main.go",
        "suffix": "go"
      }
    }
  ],
  "arguments": {
    "scope": "security",
    "severity_threshold": "medium"
  }
}

output

Skill 的边界产出:最终返回给父节点的内容与结构化结果。

Key

Desc

规范要求

contents

Skill 返回的最终内容或产物,类型 Content[],仅记录返回给父节点的结果,不复制子 Span 输出

推荐

result

Skill 返回的结构化结果,类型 object,用于机器消费与聚合;与 contents 中的 json 二选一,避免重复

可选

summary

一句话结果摘要,类型 string,供 trace 列表快速预览

可选

partial

输出是否不完整,类型 boolean,默认 false;失败、取消、超时或结果被截断时置为 true

可选

{
  "summary": "发现 3 个安全问题,其中 1 个高风险",
  "contents": [
    { "content_type": "text", "text": "发现 3 个安全问题,其中 1 个为高风险问题。" },
    {
      "content_type": "file",
      "file": { "url": "https://example.com/code-review-report.md", "name": "code-review-report.md", "suffix": "md" }
    }
  ],
  "result": { "issue_count": 3, "high": 1, "medium": 2, "low": 0 },
  "partial": false
}

Agent Span

Agent Span 表示一次 Agent 运行、子 Agent 调用或任务编排节点。

tags

推荐:

Key

Desc

规范要求

span_type

agent

必须

span_name

Agent 操作名,推荐 agent_request / sub_agent / plan_and_execute 等

必须

input

Agent 输入:本次 Agent 运行的初始请求。规范约束顶层结构(推荐 contents + arguments),不约束业务字段;Agent 内部的模型、工具、子 Agent 调用应下沉到子 Span,不在此重复。

Key

Desc

规范要求

contents

本次 Agent 运行的初始请求内容,类型 Content[](复用通用 Content,支持 text/image/file/json)

推荐

arguments

本次运行实际生效的结构化参数,类型 object,不记录默认配置全集

可选

{
  "contents": [
    { "content_type": "text", "text": "北京今天天气怎么样?" }
  ],
  "arguments": { "session_id": "sess_8823", "user_level": "vip" }
}

output

Agent 输出:本次 Agent 运行最终返回给上游的结果。summary 供 trace 列表预览,partial 在结果不完整时置 true。

Key

Desc

规范要求

contents

返回给上游的最终内容或产物,类型 Content[],不复制子 Span 输出

推荐

result

结构化结果,类型 object,用于机器消费与聚合;与 contents 中的 json 二选一,避免重复

可选

summary

一句话结果摘要,类型 string,供 trace 列表快速预览

可选

partial

输出是否不完整,类型 boolean,默认 false;失败、取消、超时或结果被截断时置为 true

可选

{
  "summary": "已回复北京天气",
  "contents": [
    { "content_type": "text", "text": "北京今天晴,气温 18~26℃。" }
  ],
  "result": { "tool_calls_count": 1, "steps": 2 },
  "partial": false
}

RAG

Retriever Span 表示检索、召回或 RAG 上下文构造。

tags

推荐:

Key

Desc

规范要求

span_type

retriever

必须

span_name

检索操作名,推荐 search_knowledge_base / retrieve_documents 等

必须

retriever_provider

检索来源类型(如 knowledge_base / vector_store)

推荐

retrieval_type

检索方式,例如 vector、keyword、hybrid、graph、web_search

推荐

data_source_id

应用侧使用的数据源稳定标识

推荐

collection

检索的集合 / 索引名

推荐

input

检索请求:检索参数为 JSON object(协议层为原生对象,仅传输层按需序列化为 string)。至少包含 query;top_k、min_score、filter 等参数与 call_options 保持一致,可选补充。

Key

Desc

规范要求

query

实际用于检索的查询文本,类型 string

必须

call_options

本次检索生效的调用参数,类型 object

推荐

{
  "query": "如何查询订单物流状态",
  "call_options": {
    "top_k": 3,
    "min_score": 0.5,
    "filter": {
      "op": "must",
      "field": "lang",
      "conds": ["zh"]
    }
  }
}

call_options

Key

Desc

top_k

检索结果数量。
类型:int

min_score

Score 下限。
类型: float

filter

VikingDB 的 DSL。
类型:object(协议层为原生 JSON object,仅传输层按需序列化为 string)。结构遵循 VikingDB Filter DSL。

{
  "top_k": 3,
  "min_score": 0.5,
  "filter": {
    "op": "must",
    "field": "lang",
    "conds": ["zh"]
  },
  "search_params": {
    "dense_weight": 0.7
  }
}

output

Key

Desc

Example

documents

召回的文档列表。
类型: document 列表。详细见: document

{
  "documents": [
    {
      "id": "faq_1024",
      "content": "在『我的订单』页面可查看物流状态……",
      "score": 0.92,
      "metadata": {
        "index": "faq",
        "source": "order_help_center",
        "chunk_id": "chunk_001",
        "url": "https://example.com/order/faq"
      }
    },
    {
      "id": "faq_1050",
      "content": "标准快递一般 2~3 个工作日送达……",
      "score": 0.85,
      "metadata": {
        "index": "faq",
        "source": "delivery_policy",
        "chunk_id": "chunk_023"
      }
    }
  ],
  "returned_count": 2
}

returned_count

本次实际返回的文档数量,类型 int。当结果经 min_score 或去重过滤后可能少于 top_k,该字段便于消费端判断召回是否充分而无需遍历数组。
规范要求:推荐

document

Key

Desc

id

doc id。
类型: string

index

索引名。
类型: string

content

文档内容。
类型: string

score

得分。
类型: float

metadata

文档扩展信息,类型 object。约束:单个 document 的 metadata 序列化后不超过 4 KB;禁止包含 PII / 密钥等敏感原文——需脱敏或以引用 ID 代替;敏感字段沿用 input/output 相同的字段级隐藏与动态 Masking 策略。

CLI Span

CLI Span 表示一次命令行程序(短生命周期进程)的执行,用于观测命令调用、参数、耗时、退出码与错误。字段对齐 OpenTelemetry CLI 语义约定(process.*),process.exit.code 非 0 判定为失败。

tags

Key

Desc

规范要求

span_type

cli

必须

span_name

命令名,推荐取可执行文件名 process.executable.name(如 git / kubectl);遵循全局低基数约束

必须

process.executable.name

可执行文件名

推荐

process.executable.path

可执行文件全路径,如 /usr/bin/git

可选

process.command_args

命令参数数组(含命令本身);含敏感值时须脱敏或不采集

推荐

input

CLI 输入:本次执行的命令、参数与运行环境,结构化为 JSON object(协议层为原生对象,仅传输层按需序列化为 string)。至少包含 command;args、cwd、关键环境变量等可选补充,敏感值须脱敏。

Key

Desc

规范要求

command

可执行文件名或命令,类型 string

推荐

args

参数列表,类型 string[],不含命令本身;敏感值脱敏

推荐

cwd

执行时的工作目录,类型 string

可选

env

本次生效的关键环境变量,类型 object;仅记必要项,敏感值以引用/哈希代替

可选

{
  "command": "git",
  "args": ["clone", "https://example.com/repo.git", "--depth", "1"],
  "cwd": "/workspace",
  "env": { "GIT_TERMINAL_PROMPT": "0" }
}

output

CLI 输出:进程退出码与标准输出/错误摘要,结构化为 JSON object(协议层为原生对象,仅传输层按需序列化为 string)。exit_code 为核心判定字段;stdout / stderr 推荐截断保留摘要,避免超大日志。失败时 exit_code 非 0,并将 Span 的 status_code 置为非 0、记录 error.type。

Key

Desc

规范要求

exit_code

进程退出码,类型 int,0 成功

必须

stdout

标准输出摘要,类型 string,推荐截断

可选

stderr

标准错误摘要,类型 string,推荐截断;失败时优先记录

可选

执行成功:

{
  "exit_code": 0,
  "stdout": "Cloning into 'repo'...\nReceiving objects: 100% (128/128), done."
}

chain Span

chain Span 表示一次工作流/编排流程的执行,是把多个步骤(检索、模型调用、工具调用等子 Span)串联起来的"编排容器"节点。

tags

Key

Desc

规范要求

span_type

chain

必须

span_name

工作流逻辑名(如 order_qa_pipeline / doc_summarize_flow);遵循全局低基数约束

必须

input

chain 输入:本次流程的初始请求内容与生效参数,结构化为 JSON object(协议层为原生对象,仅传输层按需序列化为 string)。与 Agent/Skill 统一使用 Content[],不使用 Message[]——Chain 是通用工作流编排,不绑定聊天协议语义。

Key

Desc

规范要求

contents

本次流程的初始请求内容,类型 Content[](复用通用 Content,支持 text/image/file/json)

推荐

arguments

本次流程实际生效的结构化参数,类型 object,不记录默认配置全集;敏感值须脱敏

可选

output

Workflow 输出:流程的最终产物与执行状态,结构化为 JSON object(协议层为原生对象,仅传输层按需序列化为 string)。不复制子 Span 输出;失败、取消、超时或结果被截断时置 partial=true,并将 Span 的 status_code 置为非 0、记录 error.type。与 Agent/Skill 统一使用 Content[]。

Key

Desc

规范要求

contents

返回给上游的最终内容或产物,类型 Content[],不复制子 Span 输出

推荐

result

结构化结果,类型 object,用于机器消费与聚合;与 contents 中的 json 二选一,避免重复

可选

summary

一句话结果摘要,类型 string,供 trace 列表快速预览

可选

完整 Trace 上报示例

Trace Envelope 继承规则
space_id、agent_id、thread_id、user_id 为每个 Span 必填的上下文字段。上报时有两种合法方式:

  1. Envelope 继承(推荐):在 Trace 顶层一次性声明,同一 Trace 内所有子 Span 自动继承,无需逐 Span 重复;
  2. 逐 Span 显式传入:每个 Span 独立携带上述字段(适用于跨 agent 调用或流式分批上报场景)。

下方示例采用方式 1(Envelope 继承),仅在 Trace 顶层声明一次。

示例 1:最小问答 Trace

拓扑:customer_qa_agent(Agent Root)→ chat gpt-4.1-mini(Model)。Root 只记录边界输入、最终输出和整条链路耗时,不复制 Model Span 的 token。

{
  "space_id": "era_space_001",
  "agent_id": "agent_customer_qa",
  "thread_id": "thread_8823",
  "user_id": "user_10086",
  "trace_id": "9f3b5d7a1c2e4f608192a3b4c5d6xxxx",
  "spans": [
    {
      "span_id": "1000000000000001",
      "parent_id": "0",
      "span_type": "agent",
      "span_name": "customer_qa_agent",
      "start_time": 1784217600000000,
      "duration": 620000,
      "status_code": 0,
      "input": {
        "contents": [
          {
            "content_type": "text",
            "text": "退款多久到账?"
          }
        ]
      },
      "output": {
        "contents": [
          {
            "content_type": "text",
            "text": "退款通常在 1~3 个工作日内到账。"
          }
        ],
        "partial": false
      }
    },
    {
      "span_id": "2000000000000001",
      "parent_id": "1000000000000001",
      "span_type": "model",
      "span_name": "demoname",
      "start_time": 1784217600050000,
      "duration": 540000,
      "status_code": 0,
      "model_name": "demoname",
      "model_platform": "openai",
      "input_tokens": 42,
      "output_tokens": 18,
      "total_tokens": 60,
      "latency_first_resp": 160000,
      "call_options": {
        "temperature": 0.2,
        "max_tokens": 256
      },
      "input": {
        "messages": [
          {
            "role": "user",
            "content": "退款多久到账?"
          }
        ]
      },
      "output": {
        "choices": [
          {
            "index": 0,
            "finish_reason": "stop",
            "message": {
              "role": "assistant",
              "content": "退款通常在 1~3 个工作日内到账。"
            }
          }
        ]
      }
    }
  ]
}

示例 2:RAG 与工具调用 Trace

拓扑:Agent Root 下包含 Retriever、第一次 Model、Tool 和第二次 Model。第一次 Model 通过 finish_reason=tool_calls 产生工具请求;tool_call_id 在 Model 输出、Tool Span 和第二次 Model 输入中保持一致。

order_support_agent [agent, parent_id=0]
├── search_order_faq [retriever]
├── chat plan_order_query [model]
├── get_order_status [tool, tool_call_id=call_order_01]
└── chat answer_order_query [model]

{
  "space_id": "era_space_001",
  "agent_id": "agent_order_support",
  "thread_id": "thread_9901",
  "user_id": "user_20088",
  "trace_id": "af4c6e8b2d3f507192a4b6c8d0e2xxxx",
  "spans": [
    {
      "span_id": "a000000000000001",
      "parent_id": "0",
      "span_type": "agent",
      "span_name": "order_support_agent",
      "start_time": 1784218200000000,
      "duration": 1150000,
      "status_code": 0,
      "input": {
        "contents": [
          {
            "content_type": "text",
            "text": "订单 A1024 到哪里了?"
          }
        ]
      },
      "output": {
        "contents": [
          {
            "content_type": "text",
            "text": "订单 A1024 已发出,预计明天送达。"
          }
        ],
        "partial": false
      }
    },
    {
      "span_id": "b000000000000001",
      "parent_id": "a000000000000001",
      "span_type": "retriever",
      "span_name": "search_order_faq",
      "start_time": 1784218200030000,
      "duration": 120000,
      "status_code": 0,
      "retriever_provider": "knowledge_base",
      "collection": "order_faq",
      "input": {
        "query": "订单物流状态查询",
        "call_options": {
          "top_k": 2
        }
      },
      "output": {
        "documents": [
          {
            "id": "faq_1024",
            "index": "order_faq",
            "content": "可通过订单编号查询最新物流状态。",
            "score": 0.92
          }
        ],
        "returned_count": 1
      }
    },
    {
      "span_id": "c000000000000001",
      "parent_id": "a000000000000001",
      "span_type": "model",
      "span_name": "demoname",
      "start_time": 1784218200160000,
      "duration": 280000,
      "status_code": 0,
      "model_name": "demoname",
      "model_platform": "openai",
      "input_tokens": 68,
      "output_tokens": 14,
      "total_tokens": 82,
      "input": {
        "messages": [
          {
            "role": "user",
            "content": "订单 A1024 到哪里了?"
          }
        ]
      },
      "output": {
        "choices": [
          {
            "index": 0,
            "finish_reason": "tool_calls",
            "message": {
              "role": "assistant",
              "tool_calls": [
                {
                  "id": "call_order_01",
                  "type": "function",
                  "function": {
                    "name": "get_order_status",
                    "arguments": "{\"order_id\":\"A1024\"}"
                  }
                }
              ]
            }
          }
        ]
      }
    },
    {
      "span_id": "d000000000000001",
      "parent_id": "a000000000000001",
      "span_type": "tool",
      "span_name": "get_order_status",
      "start_time": 1784218200450000,
      "duration": 180000,
      "status_code": 0,
      "tool_call_id": "call_order_01",
      "input": {
        "arguments": {
          "order_id": "A1024"
        }
      },
      "output": {
        "result": {
          "status": "shipped",
          "eta": "2026-07-17"
        }
      }
    },
    {
      "span_id": "e000000000000001",
      "parent_id": "a000000000000001",
      "span_type": "model",
      "span_name": "chat answer_order_query",
      "start_time": 1784218200640000,
      "duration": 470000,
      "status_code": 0,
      "model_name": "demoname",
      "model_platform": "openai",
      "input_tokens": 86,
      "output_tokens": 22,
      "total_tokens": 108,
      "latency_first_resp": 150000,
      "input": {
        "messages": [
          {
            "role": "user",
            "content": "订单 A1024 到哪里了?"
          },
          {
            "role": "tool",
            "tool_call_id": "call_order_01",
            "content": "{\"status\":\"shipped\",\"eta\":\"2026-07-17\"}"
          }
        ]
      },
      "output": {
        "choices": [
          {
            "index": 0,
            "finish_reason": "stop",
            "message": {
              "role": "assistant",
              "content": "订单 A1024 已发出,预计明天送达。"
            }
          }
        ]
      }
    }
  ]
}

示例 3:Skill 与 CLI Trace

拓扑:Agent Root 激活 code-review Skill;Skill 内部通过 CLI Span 执行 git diff 获取材料,再由 Model Span 完成安全审查。Skill Span 只记录父节点传入的任务和最终返回结果,不复制 CLI stdout 或 Model choices。

coding_assistant [agent, parent_id=0]
└── code-review [skill, trigger=user]
├── git [cli, exit_code=0]
└── chat review_security_diff [model]

{
  "space_id": "era_space_001",
  "agent_id": "agent_coding_assistant",
  "thread_id": "thread_7702",
  "user_id": "user_30099",
  "trace_id": "c17e39a25b6d4f708192a4c6e8b0xxxx",
  "spans": [
    {
      "span_id": "f000000000000001",
      "parent_id": "0",
      "span_type": "agent",
      "span_name": "coding_assistant",
      "start_time": 1784218800000000,
      "duration": 1280000,
      "status_code": 0,
      "input": {
        "contents": [
          {
            "content_type": "text",
            "text": "检查最近一次提交中的安全问题"
          }
        ]
      },
      "output": {
        "contents": [
          {
            "content_type": "text",
            "text": "发现 1 个高风险问题:日志中可能泄露访问令牌。"
          }
        ],
        "partial": false
      }
    },
    {
      "span_id": "f100000000000001",
      "parent_id": "f000000000000001",
      "span_type": "skill",
      "span_name": "code-review",
      "start_time": 1784218800030000,
      "duration": 1190000,
      "status_code": 0,
      "skill.name": "code-review",
      "skill.version": "1.3.0",
      "skill.source": "local",
      "skill.trigger": "user",
      "skill.operation": "invoke",
      "input": {
        "contents": [
          {
            "content_type": "text",
            "text": "检查最近一次提交中的安全问题"
          }
        ],
        "arguments": {
          "scope": "security",
          "severity_threshold": "medium"
        }
      },
      "output": {
        "summary": "发现 1 个高风险问题",
        "contents": [
          {
            "content_type": "text",
            "text": "日志语句可能输出明文访问令牌。"
          }
        ],
        "result": {
          "issue_count": 1,
          "high": 1,
          "medium": 0,
          "low": 0
        },
        "partial": false
      }
    },
    {
      "span_id": "f200000000000001",
      "parent_id": "f100000000000001",
      "span_type": "cli",
      "span_name": "git",
      "start_time": 1784218800060000,
      "duration": 140000,
      "status_code": 0,
      "process.executable.name": "git",
      "process.executable.path": "/usr/bin/git",
      "process.command_args": [
        "git",
        "diff",
        "--unified=0",
        "HEAD~1",
        "HEAD"
      ],
      "input": {
        "command": "git",
        "args": [
          "diff",
          "--unified=0",
          "HEAD~1",
          "HEAD"
        ],
        "cwd": "/workspace/order-service"
      },
      "output": {
        "exit_code": 0,
        "stdout": "@@ auth.go @@\n+logger.Info(\"token=%s\", accessToken)"
      }
    },
    {
      "span_id": "f300000000000001",
      "parent_id": "f100000000000001",
      "span_type": "model",
      "span_name": "chat review_security_diff",
      "start_time": 1784218800210000,
      "duration": 920000,
      "status_code": 0,
      "model_name": "demoname",
      "model_platform": "openai",
      "input_tokens": 176,
      "output_tokens": 44,
      "total_tokens": 220,
      "latency_first_resp": 270000,
      "input": {
        "messages": [
          {
            "role": "user",
            "content": "检查下面的代码差异是否存在安全问题。"
          },
          {
            "role": "user",
            "content": "@@ auth.go @@\n+logger.Info(\"token=%s\", accessToken)"
          }
        ]
      },
      "output": {
        "choices": [
          {
            "index": 0,
            "finish_reason": "stop",
            "message": {
              "role": "assistant",
              "content": "存在高风险:访问令牌可能被写入日志,应移除或脱敏。"
            }
          }
        ]
      }
    }
  ]
}

框架与多模态

框架接入选择

场景

入口

退出前操作

Native 手动控制父子关系

new_trace()、Trace.*_span()

client.flush()、client.close()

普通函数、协程和 stream

trace_context()、start_span()、@client.observe()

client.flush()、client.close()

OpenAI 或兼容接口

client.wrap_openai(openai_client)

client.flush()、client.close()

LangChain

instrument_langchain() 或每请求独立 Callback

包装器结束时 flush;进程结束时 close

LangGraph

instrument_langgraph() 或每请求独立 Callback

包装器结束时 flush;进程结束时 close

已有 OpenTelemetry

eraotel.new_tracer_provider()

provider.force_flush()、provider.shutdown()

OpenAI wrapper

import secrets
from openai import OpenAI
from bytedance import tea_era as era

client = era.Client(era.config_from_env())
model_client = client.wrap_openai(OpenAI(
    api_key="MODEL_API_KEY",
    base_url="https://MODEL_API_HOST/v1",
))

with client.trace_context(era.TraceConfig(
    user_id="customer-user-123",
    thread_id="conversation-456",
    trace_id=secrets.token_hex(16),
)):
    response = model_client.chat.completions.create(
        model="MODEL_ENDPOINT_OR_NAME",
        messages=[{"role": "user", "content": "你好"}],
    )

client.flush(timeout=30)
client.close(timeout=30)

Wrapper 是实例代理,不修改全局 OpenAI 模块或原始 client。SDK 会采集模型名、输入输出、token、错误和流式生命周期;模型 API Key 应只交给模型 client,不应放入 Agent 运营分析 tags 或 payload。

多模态上传开关

默认关闭。​Data URI 作为 Model Span input 的普通 payload 随 ingest 上报,不额外调用媒体上传接口。适合小尺寸内容或客户明确允许内联传输的场景。

config = era.Config(
    workspace_id="CUSTOMER_WORKSPACE_ID",
    agent_id="CUSTOMER_AGENT_ID",
    base_url="https://CUSTOMER_ERA_HOST",
    api_token="CUSTOMER_API_TOKEN",
    media_config=era.MediaConfig(enabled=False),
)

显式开启。​SDK 识别标准图片、视频、音频和文件节点,先调用 /v1/loop/files/upload;只有服务端返回 ready 且 size/SHA-256 校验通过后,才删除 Data URI、写入服务端权威 reference_id 和 attachment,并调用 /v1/loop/traces/ingest。

config = era.Config(
    workspace_id="CUSTOMER_WORKSPACE_ID",
    agent_id="CUSTOMER_AGENT_ID",
    base_url="https://CUSTOMER_ERA_HOST",
    api_token="CUSTOMER_API_TOKEN",
    media_config=era.MediaConfig(
        enabled=True,
        upload_concurrency=2,
        upload_timeout=120,
        max_upload_bytes=100 * 1024 * 1024,
        deduplicate=True,
    ),
)

兼容配置 multimodal_attachment_upload_enabled=True 也会开启共享媒体上传。外部 HTTP(S) URL 保持原样,SDK 不会主动下载。可通过 client.media_stats() 查看 uploaded_files、uploaded_bytes、deduplicated_files 和 failed_uploads。

采集与脱敏

policy = era.CapturePolicy(
    redacted_keys={"authorization", "password", "token"},
    redacted_paths={"customer.cards.*.number"},
    redacted_key_patterns={r"credential$"},
    max_payload_bytes=768 * 1024,
    semantic_projection=True,
)

client = era.Client(era.Config(
    workspace_id="CUSTOMER_WORKSPACE_ID",
    agent_id="CUSTOMER_AGENT_ID",
    base_url="https://CUSTOMER_ERA_HOST",
    api_token="CUSTOMER_API_TOKEN",
    capture_policy=policy,
))

SDK 默认按常见敏感字段名和值模式脱敏,但您仍需根据自己的数据分类补充规则。不要依赖 SDK 替代业务侧最小化采集。开启完整 State 调试或超大文本上报会扩大数据范围,只建议在经过安全评审后短期启用。

验证与排障

接入验收

  1. 使用 32 位小写 hex trace_id 发送一条最小 Agent Trace。
  2. 确认 flush.ok=True、failed=0、pending=0,且 Snapshot 守恒。
  3. 短进程最后调用 close(),确认 close.ok=True 和 closed=True。
  4. 等待平台异步处理后,在产品页面用 exact trace_id 查询。
  5. 核对预期 Span 数量、根节点、parent_id、类型、输入输出、错误和模型字段。

多模态开启时还应确认媒体上传发生在 ingest 之前,最终 Model Span 中已移除 Data URI,并能看到 reference/attachment。关闭时应确认没有媒体上传请求。

常见问题

问题或报错

解决方案

初始化失败

检查 base_url 是否为绝对 HTTPS 根地址,是否误传完整 ingest path,以及 Bearer token 是否为空。AuthMode.NONE 只能用于您明确配置的无鉴权私有环境。

TLS 失败

检查域名证书、SNI、完整证书链、私有 CA 和代理。不要使用 tls_verify=False 或 curl --insecure 绕过生产证书错误;这会使 API Token 发送给身份无法验证的服务端。

flush.ok=True 但页面查不到

先确认使用的是 32 位小写 hex trace_id,Workspace/Agent/产品项目映射正确,页面时间窗覆盖上报时间。接收端成功只证明 ERA ingest 已接收,异步消费和索引仍需产品页面验证。

短进程退出后丢数据

退出前调用 client.flush() 和 client.close();OTel 使用 provider.force_flush() 和 provider.shutdown()。

队列压力或丢弃

检查 snapshot().reasons、health().queue_items 和 queue_bytes。默认 overflow 策略是 drop_newest;业务线程不会等待网络发送。

HTTP 错误

401/403 通常是 Agent token、Workspace/Agent 映射或权限问题;429/5xx 会按策略重试;其他 4xx 通常不会重试。不要在日志中打印完整响应正文或 Authorization。

安全、失败留存与交付边界

本地死信文件

client = era.Client(era.Config(
    workspace_id="CUSTOMER_WORKSPACE_ID",
    agent_id="CUSTOMER_AGENT_ID",
    base_url="https://CUSTOMER_ERA_HOST",
    api_token="CUSTOMER_API_TOKEN",
    dead_letter_config=era.DeadLetterConfig(
        directory="./era-dead-letter",
        max_file_bytes=512 * 1024 * 1024,
        queue_length=1024,
    ),
))

目录为空时死信完全关闭,不创建线程或文件。启用后,每个 Client/进程写独立的 era-failed-spans-PID-INSTANCE.ndjson。网络重试耗尽、不可重试终态、队列溢出和已创建 Span 的序列化失败可以留存;采样过滤、SDK disabled 和创建前身份校验拒绝不会留存。
死信写入是独立有界队列,不阻塞业务线程。落盘成功不代表远端上报成功,原 Span 仍计为 failed 或 dropped。SDK不提供重放、轮转、压缩、加密、自动清理或目录总量限制;您需要自行配置磁盘配额、告警、保留周期和处置流程。即使 SDK 会移除鉴权信息和媒体字节,文件仍可能包含业务 input/output,应按敏感数据管理。

上线检查清单

  • 使用交付的正式 wheel,并核对版本为 1.1.0+tob.1。
  • 通过密钥管理系统注入 API Token,并验证轮换流程。
  • 验证 HTTPS、证书链、私有 CA、代理和 DNS 在所有目标部署区可用。
  • 根 Trace 提供有效 user_id、thread_id 和 32 位 hex trace_id。
  • 确认 CapturePolicy 满足客户数据安全和合规要求。
  • 使用 exact trace ID 完成产品页面 read-back,核对数量、父子关系和语义。
  • 验证网络失败、限流、进程退出和队列压力下的行为。
  • 若开启死信,配置目录权限、磁盘上限、告警和外部清理流程。
  • 若开启多模态,确认 ready-before-ingest、reference rewrite 和媒体容量预算。

能力边界

SDK 不承诺 exactly-once,不提供默认磁盘 spool、自动重放、多目标原子双写或内置告警平台。Idempotency-Key 和稳定 Trace/Span ID 用于降低模糊重试风险,但您仍应按至少一次投递语义设计业务监控。死信文件只用于留存和审计,不能视为远端成功。
当 SDK 返回成功但产品页面最终不可见时,请保留 SDK 版本、发生时间、Workspace ID、Agent ID、exact trace_id、Snapshot/FlushResult、request ID/logid(若有)及脱敏后的网络错误类型,再联系火山引擎技术支持团队。不要提供 API Token、Authorization、完整业务 payload 或媒体字节。

最近更新时间:2026.10.28 16:40:44
这个页面对您有帮助吗?
有用
有用
无用
无用