1. 为什么单看 Trajectory 还不够:多层 Subagent 的观测盲区
DeepSeek Harness 发布之后,很多人的第一反应是「自带 Trajectory 已经够用了」。我一开始也这么想:一次运行里的输入、LLM 调用、工具调用、Token、耗时都能在本地视图里翻到,单会话调试确实不缺东西。但真正把 Agent 跑复杂之后,问题就冒出来了——当主 Agent 开始委派 Subagent,Subagent 又继续往下委派,Trajectory 那种按时间平铺的事件账本会把层级关系拍平,你看到的是「第 3 行调了一个 tool,第 4 行又调了一个 tool」,却很难一眼看出「这个 tool 到底属于哪一层 Subagent、这一层花了多少钱」。
这就是 Agent 可观测和单次 LLM 调用可观测的本质区别。前者要回答的是调用图、成本归因、跨会话聚合和评估闭环,后者只要把一次请求的输入输出记清楚就够了。Litefuse 的定位正好补上这一块:它把 DeepSeek Harness 的 session/event 事件流重新组织成嵌套的 Trace Tree,用 AGENT / GENERATION / TOOL 三类 span 的父子关系还原真实的委派链。本文就聚焦 DeepSeek Harness 接入 Litefuse 的配置骨架与验证路径,给出可复制的 config.toml / settings.json 骨架、插件挂载步骤,以及一次最小运行怎么确认链路真的生效。适合已经在用 DeepSeek Harness、想让 Agent 运行过程变得可计费、可聚合、可评估的开发者。
2. 前置准备:TaoToken 与 Litefuse 的账号与 Key
在动配置文件之前,先把两边的凭证准备好,否则后面插件挂载完发现没有 Key,还得回头补。
TaoToken 这边主要是给模型调用提供统一的接入入口。你可以先到官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 了解整体能力,然后在控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 里创建 API Key。如果你后面要跑长期编码或 Agent 任务,可以顺手看下 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它更适合高频调用的场景。API 的基础地址是 https://taotoken.net/api ,注意这个地址不带 UTM 参数,配置里直接写它就行。
Litefuse 这边需要的是两个 Key:LITEFUSE_PUBLIC_KEY(形如pk-lf-...)和LITEFUSE_SECRET_KEY(形如sk-lf-...)。这两个值在 Litefuse Cloud 注册账号、创建项目后就能拿到。它们的作用是让插件把 trace 数据上报到 Litefuse 的观测后端,所以务必保管好,不要提交到公开仓库。
注意:TaoToken 的 Key 和 Litefuse 的 Key 是两套独立凭证,前者用于模型调用鉴权,后者用于 trace 上报鉴权,不要混用,也不要写进同一个变量名里。
把这两组 Key 准备好之后,我们进入配置环节。下面给出的骨架你可以直接复制,只需要替换成自己的真实值。
3. 可复制配置:config.toml 与 settings.json 骨架
DeepSeek Harness 的插件体系是「everything is a plugin」,所以接入 Litefuse 的核心就是挂载dsh-litefuse-plugin并给它喂配置。配置分两层:一层是 Harness 自身的config.toml,负责声明插件和 profile;另一层是settings.json,负责插件运行时的具体参数。
先看config.toml的骨架。这个文件通常放在项目根目录或~/.dsh/下,取决于你的 profile 管理方式:
# ~/.dsh/config.toml [profile.web] plugins = [ "dsh-litefuse-plugin" ] [profile.web.plugin.dsh-litefuse-plugin] enabled = true endpoint = "https://litefuse.cloud" service_name = "deepseek-harness" capture_context = true capture_subagent = true flush_interval_ms = 2000这里几个参数值得说明。endpoint指向 Litefuse 的观测后端,默认就是https://litefuse.cloud;service_name会写进 OTel 的resourceAttributes.service.name,方便你在 Litefuse 里按服务筛选;capture_context决定是否把实际发送给模型的上下文一并上报,调试 Prompt 时很有用;capture_subagent是这次接入的重点,开启后 Subagent 的嵌套调用才会被建模成独立的 AGENT span;flush_interval_ms控制上报批量刷新的间隔,本地调试可以调小一点,比如 1000,让 trace 更快出现。
再看settings.json,它负责把 Key 和更细的开关传进去:
{ "dsh-litefuse-plugin": { "publicKey": "${LITEFUSE_PUBLIC_KEY}", "secretKey": "${LITEFUSE_SECRET_KEY}", "traceSpec": "https://litefuse.ai/litefuse-agent-trace-spec.md", "spanMapping": { "turn": "AGENT", "generation": "GENERATION", "tool": "TOOL", "run_code": "TOOL" }, "costAttribution": true, "evalHooks": { "scores": true, "datasets": true } } }spanMapping这一段是理解整个 Trace Tree 的钥匙:turn/start到turn/end对应一条 Trace 及其根 AGENT span,每次模型调用映射为 GENERATION,每次工具调用映射为 TOOL,run_code内部触发的调用则作为嵌套 span。普通 Generation 和 Tool 保持同层,真正产生层级的是 Subagent,所以 Trace Tree 的深度基本等于实际的 Agent 委派深度。costAttribution打开后,每个 span 会有独立单价和calculatedTotalCost,并自动向上汇总。evalHooks则是给后续 Agent Evals 留的挂载点。
Key 的存放建议单独放一个~/.dsh/.env,不要写死在settings.json里:
# ~/.dsh/.env LITEFUSE_PUBLIC_KEY=pk-lf-你的公钥 LITEFUSE_SECRET_KEY=sk-lf-你的私钥 TAOTOKEN_API_KEY=你的TaoToken密钥 TAOTOKEN_BASE_URL=https://taotoken.net/api这样settings.json里的${LITEFUSE_PUBLIC_KEY}就能被环境变量替换,既安全又方便切换环境。
4. 插件挂载与最小运行验证
配置写完之后,挂载插件并跑一次最小运行,确认链路真的通了。挂载命令用 Harness 自带的 plugin 子命令:
npx @deepseek-ai/dsh plugin --profile web add -w dsh-litefuse-plugin这条命令会把dsh-litefuse-plugin装到web这个 profile 下,-w表示写入工作区配置。装完之后启动 Harness:
npx @deepseek-ai/dsh web启动日志里如果出现插件加载成功的提示,说明挂载这一步没问题。接下来做最小验证:在 Harness 里发一条会触发工具调用的指令,比如让它读一个文件再总结。等这一轮结束后,打开 Litefuse 的 Tracing 页面,你应该能看到一条新的 trace。
验证是否生效,重点看三个信号。第一,trace 的resourceAttributes.service.name是不是deepseek-harness,scope.name是不是dsh-litefuse-plugin,这两个对上了说明上报来源正确。第二,trace 里是否出现了 AGENT / GENERATION / TOOL 三类 span,并且根 span 是一次 turn。第三,如果你这次运行触发了 Subagent,检查 Trace Tree 里有没有嵌套的 AGENT span,父子关系是否正确。
一个多层 Subagent 的典型结构长这样,你可以对照自己的 trace 看层级是否还原:
AGENT DeepSeek Harness — Turn 1 (root) ├─ GENERATION plan (2 tools) ├─ TOOL todo_write ├─ TOOL tool (1 subagent) │ └─ AGENT subagent 1 │ ├─ GENERATION plan (2 tools) │ ├─ TOOL tool (1 subagent) │ │ └─ AGENT subagent 2 │ │ └─ GENERATION subagent response │ └─ GENERATION subagent response └─ GENERATION response如果这个嵌套结构出来了,说明capture_subagent和父子绑定逻辑都工作正常。这里有个实现细节值得知道:Harness 给子会话提供新的session_id和父会话信息,但不会直接标明它由哪一次调用创建,而并发委派又很常见。插件是利用委派时原样传递到子会话中的description和prompt建立关联,并尽早完成父子绑定。因为 OTel Span 一旦导出,Parent 关系就不能再修改,父子关系如果一开始判断错误,后续 Trace Tree 也会随之失真。所以验证时如果发现某个 Subagent 挂错了父节点,优先检查委派时的description是否被透传。
5. 本篇常见错排查
接入过程中最容易踩的坑集中在配置和父子绑定两块,下面按现象给出排查路径。
现象一:Litefuse 里完全看不到 trace。先确认~/.dsh/.env里的两个 Key 是否被正确加载,可以在启动 Harness 前echo $LITEFUSE_PUBLIC_KEY看有没有值。如果 Key 没问题,检查config.toml里enabled是否为true,以及endpoint是否写成了https://litefuse.cloud。还有一种情况是flush_interval_ms设得太大,trace 还没上报,等几秒或调小到 1000 再试。
现象二:trace 出来了,但只有根 span,没有 GENERATION 和 TOOL。这通常是spanMapping没生效,检查settings.json里的映射键名是否和 Harness 实际发出的事件名一致。另外确认插件版本,早期版本对run_code的嵌套处理可能不完整,升级到最新版再试。
现象三:Subagent 的层级是平的,没有嵌套。这是最典型的问题,根因是父子绑定失败。先确认capture_subagent为true,然后检查委派时description和prompt是否被原样传递到子会话。如果并发委派很多,绑定可能发生竞争,可以适当降低并发度复现一次,确认是绑定逻辑问题还是并发时序问题。
现象四:成本显示为 0 或缺失。检查costAttribution是否开启,以及模型单价是否在 Litefuse 的计价表里能匹配到。如果用的是自定义模型名,可能需要在 Litefuse 侧补充单价配置,否则calculatedTotalCost无法计算。
现象五:TaoToken 侧调用报鉴权失败。确认TAOTOKEN_BASE_URL写的是https://taotoken.net/api,不要带多余路径;Key 是否在控制台正确创建且未过期。如果要在代码里直接调模型,可以参考接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里的示例,Key 管理在 API Keys 页面 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。
排查时建议按「Key → 插件加载 → span 映射 → 父子绑定 → 成本计算」的顺序逐层往下,不要一上来就怀疑插件本身,大部分问题都出在配置层。
6. 从 Trace 到 Evals:把观测闭环用起来
链路跑通只是第一步,Litefuse 真正的价值在于把 trace 变成可评估、可迭代的资产。当你的 trace 里已经稳定出现嵌套的 AGENT span 和带成本的 GENERATION span 之后,就可以在 trace 上挂 scores、关联 datasets 和 prompt 版本,形成「运行 → 评估 → 迭代」的闭环。这一步是纯本地 Trajectory 做不到的,因为本地账本是一次性的,没有导出入口,也无法跨会话聚合。
具体操作上,你可以先在 Litefuse 里挑几条有代表性的 trace,给它们打上评估分数,标记出哪些运行结果符合预期、哪些偏离。然后把这些 trace 关联到同一个 dataset,作为后续 Prompt 调整的回归基线。每次改完 Prompt 或上下文管理策略,重新跑一轮,对比新旧 trace 的分数和成本分布,就能判断这次改动到底是优化还是退化。
如果你想让 Agent 自己按规范完成插件开发或扩展,可以让它参考 Litefuse 的 SKILL 文档 https://litefuse.ai/SKILL.md ,里面给出了面向 Agent 集成的规范。Litefuse 团队在对接 Claude Code、Codex、Hermes、OpenClaw、Kimi Code 等多个 Agent 的过程中,也总结了一套 Agent Trace 规范 https://litefuse.ai/litefuse-agent-trace-spec.md ,你可以基于这套规范接入,也可以直接让 Agent 照着实现。
对于需要长期跑编码或 Agent 任务的场景,模型调用侧可以配合 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 来降低高频调用的成本压力;日常想快速验证某个模型在 Agent 里的表现,可以直接用模型对话 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=chat&utm_campaign=rewrite 试一轮,再决定要不要写进正式配置。
最后提醒一个实操细节:dsh-litefuse-plugin已经开源并发布到 npm,第一个版本覆盖了 Session/Event 接入和 Subagent 嵌套建模,但 Agent 可观测本身还在快速演进。建议你在验证通过后,把config.toml和settings.json纳入版本管理,但 Key 始终走环境变量,这样升级插件或切换环境时不会因为凭证泄漏或硬编码而返工。