多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

DeepSeek Harness 设计解析:Agent Harness 的六个关键决策与 TaoToken 配置骨架

DeepSeek Harness 设计解析:Agent Harness 的六个关键决策与 TaoToken 配置骨架 1. 从「Agent 说做完了」到「测试真的跑过了」Agent Harness 的六个决策面如果你正在用 DeepSeek 做长程编码任务大概率遇到过这几个场景Agent 声称任务完成测试却没跑长任务跑了一阵开头的约束开始丢失重开会话需要反复交代背景想让它离线跑又频繁卡在权限确认上。这些问题的根源不在模型本身而在于包裹模型的 Agent Harness 有没有把执行生命周期管住。DeepSeek Harness下文简称 dsh是 DeepSeek 官方开源的 Agent 运行框架它把 Agent Loop、工具注册表、会话日志、上下文压缩、沙箱权限和任务验收拆成可组合的插件层。适合谁适合需要在本地或 CI 里跑长程编码 Agent、又希望执行过程可恢复、可审计、可验证的开发者。本文围绕六个关键决策面展开Loop 如何驱动、工具如何暴露、上下文如何组装、状态如何跨崩溃恢复、权限如何设防、任务如何验收并给出可直接复制的 TaoToken 配置骨架与验证动作。我试过把这六个面拆开逐个调发现真正卡人的不是模型能力而是配置层没对齐——尤其是 Key 通道和模型路由。下面先把 TaoToken 这一层铺好再进入 dsh 的配置骨架。2. TaoToken 前置统一 Key 与 API 通道dsh 的 Model Adapter 需要一个 OpenAI 兼容的 base_url 和 api_key。TaoToken 提供统一的 Key 管理和 API 通道把模型调用收敛到一个入口省去在多个供应商之间切换 base_url 的麻烦。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。你需要先拿到一个 Key。进入控制台创建https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 然后在 API Keys 页面生成https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。生成的 Key 形如sk-xxxxxxxx只显示一次复制后立刻写入本地环境变量不要硬编码进仓库。# 写入 shell 配置避免明文进 git export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api注意dsh 的 Model Adapter 走 OpenAI 兼容协议base_url 末尾不要多加/v1具体以 dsh 文档的 adapter 说明为准如果报 404先检查路径拼接。Key 就绪后先做一次最小连通性验证确认通道没问题再动 dsh 配置curl -s https://taotoken.net/api/v1/models \ -H Authorization: Bearer $TAOTOKEN_API_KEY | head -c 400返回模型列表 JSON 就说明 Key 和通道都通了。这一步别跳过后面 dsh 报错时能快速区分是通道问题还是 Harness 配置问题。3. 可复制配置config.toml 与 settings.json 骨架dsh 的配置分两层config.toml管 Harness 级行为Loop、工具、沙箱、会话后端settings.json管模型与通道。下面这份骨架对应六个决策面你可以按需裁剪。# config.toml —— Harness 级配置骨架 [agent] preset standard # minimal / standard / ptc 三选一 max_rounds 30 # 资源硬上限轮次 max_wall_time_sec 1800 # 资源硬上限实际运行时间 [loop] driver agent-loop # 默认 Loop 驱动 stop_condition tests_pass_and_app_boots # 停止规则别只信 Agent 自报 on_error restart_with_context # 异常分支携带失败信息重启 [context] watermark_tokens 350000 # 主动控制水位别等窗口溢出 compaction summary # 上下文压缩作为独立可选能力 pinned_rules_file .dsh/rules.md # 不可被压缩丢失的长期规则 [tools] registry scoped # 模型可见 Schema 与运行时实现分离 allow [bash, str_replace_editor, web_search] deny [session_search] # 默认不把会话搜索暴露给模型 [session] backend sqlite # jsonl / sqlite 两种持久化后端 full_text_index false # 全文索引默认关闭 [sandbox] mode workspace-write # read-only / workspace-write / danger-full-access on_unavailable fail_closed # 无法提供沙箱时失败即关闭不静默降级 [approval] policy ask # ask / never无处理器时不自动放行{ model: { provider: openai-compatible, base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, name: deepseek-chat, timeout_sec: 120 }, adapter: { stream: true, max_retries: 2 } }几个关键点值得单独说。stop_condition不要写成agent_says_done要写成可检查的条件比如「测试全部通过且应用正常启动」。pinned_rules_file指向的文件里放「不能操作生产环境」「不能提交密钥」这类硬规则每次上下文重置后重新读取。sandbox.on_unavailable设成fail_closed当策略要求受限执行而环境给不了沙箱时系统直接失败不会静默退化成不受限执行。工具层对应「系统拥有哪些能力、当前 Agent 能看到哪些、以什么形式交给模型」三个层次。allow/deny控制第二个层次preset控制第三个层次——minimal 只给 Bash 和 str_replace_editorstandard 给完整 Coding Agent 能力ptc 在 standard 基础上用 Code Mode SDK 暴露工具让模型用一个 TypeScript 程序组合多步操作。4. 验证请求跑通一次带验收的 Agent 任务配置写好后用一个最小任务验证整条链路。准备一个测试仓库放一个会失败的测试mkdir -p /tmp/dsh-demo cd /tmp/dsh-demo git init cat test_demo.py EOF def test_should_fail(): assert 1 1 3 EOF然后启动 dsh指定停止条件为测试通过dsh run \ --config ./config.toml \ --settings ./settings.json \ --task 修复 test_demo.py 中失败的断言使 pytest 全部通过 \ --stop-when pytest exits 0预期行为分三层观察。第一层Loop 驱动dsh 把任务和上下文提交给模型模型返回工具调用Harness 执行后把结果放回上下文循环推进。第二层上下文管理当累计 token 接近watermark_tokens触发一次摘要压缩被替换的原始事件仍保留在持久日志里。第三层验收pytest exits 0由确定性检查器判定而不是模型自报完成。成功时你会看到类似输出[turn 1] step 1: read test_demo.py [turn 1] step 2: str_replace_editor - assert 1 1 2 [turn 1] step 3: bash - pytest [turn 1] step 3: pytest exits 0 [verified] stop_condition satisfied如果中途崩溃重新打开会话时dsh 会检查事件日志某个轮次写了turn/start但没写turn/end系统补记一个interrupted的turn/end为异常中断补上边界然后从持久状态恢复。这就是「Model-visible means logged」的落地——凡是进入模型请求的信息都能从日志重建。想单独验证模型通道是否正常可以直接用模型对话页面发一条消息https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果那边正常而 dsh 报错问题就在 Harness 配置层。5. 本篇常见错排查报错一401 Unauthorized或invalid api key。先确认环境变量在当前 shell 生效echo $TAOTOKEN_API_KEY。如果为空说明 export 没写进当前会话重新 source 一下。如果 Key 正确仍报 401检查 settings.json 里api_key_env的变量名是否和实际 export 的一致大小写敏感。报错二404 Not Found或路径拼接错误。多半是 base_url 多写了/v1。TaoToken 的 API 端点是https://taotoken.net/apiadapter 会自己拼/v1/chat/completions。如果你手动写成https://taotoken.net/api/v1就会变成/api/v1/v1/...。报错三沙箱不可用导致任务直接失败。这是on_unavailable fail_closed的预期行为不是 bug。dsh 在 Linux 上用 bwrap / LandlockmacOS 用 SeatbeltWindows 用 ACL 和受限令牌。如果你的环境缺这些机制要么换到支持的环境要么显式把mode调成danger-full-access——但后者意味着放弃文件系统边界只建议在隔离容器里用。报错四长任务跑着跑着约束丢了。检查pinned_rules_file指向的文件是否存在且被系统提示词重复强调。探索过程中积累的事实可以被压缩但长期规则不能随普通历史一起消失。如果早期错误假设已经进入上下文并被后续推理当成既定事实继续追加信息只会放大偏差此时应主动重置会话从外部状态恢复。报错五Agent 说完成了但测试没跑。这是把 Stop 当成 Verified 了。Stop 只表示 Loop 停止Done 是执行 Agent 自报完成Verified 才要求系统根据验收条件和可检查证据确认。把stop_condition从自然语言改成确定性检查器能判定的条件比如pytest exits 0。报错六工具太多导致模型选择困难。挂载多个 MCP Server 后大量静态描述持续占用有效 Token。把工具描述保存为可按需读取的文件让 Agent 只加载当前任务需要的能力长期没用、职责重复或名称高度相似的工具直接从allow里删掉。6. 长期编码与 Agent 场景的下一步六个决策面里停止规则和外部持久状态是性价比最高的两项——实现成本低对具体模型版本依赖小。如果你要跑的是长时间无人值守、跨会话恢复、严格权限控制的任务建议从这两项开始再逐步补上工具作用域、上下文压缩和独立验收。对于需要长期跑编码 Agent 的场景Coding Plan 提供了更稳定的通道和额度管理https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入细节和 adapter 参数以官方文档为准https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果你在用 Claude Code 类的工具链Anthropic 兼容通道的说明在这里https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。最后留一个实操建议把SPEC.md、PLAN.md、PROGRESS.md、DECISIONS.md四个文件放进仓库每个能正常工作的修改做一次小粒度 Git 提交。这样崩溃恢复时新的 Agent 从PROGRESS.md就能接上进度git revert也能直接回滚。If it isnt in a file, it doesnt exist——这句话在长程 Agent 里比任何提示词都管用。
返回列表