第 21 卷
> 安全配置的深度话题超出本白皮书范围;核心认知:**dsh 的工具执行默认有隔离与审批层**,不是裸执行。
8.6 新手最该记住的三件事
- **工具名是简短动词**(read/write/grep/glob/edit/bash)——写提示词/插件时直
接说"读文件""搜索"即可
- **工具返回 locations → 产物追踪**——模型改的文件会出现在对话产物区
- **长对话自动压缩**——不必手动清理历史(但重要信息要写进提示词)
8.7 插件运行时验证方法论(零成本)
> 出处:官方讨论区 [#462](https://github.com/deepseek-ai/deepseek-harness/discussions/462)「DSH 插件运
行时验证方法论:无 API Key 验证 waterfall 行为」(实证 74 事件 / 12 waterfall)。FAQ 已有一句话版本,本节展开。
**痛点**:静态检查只能证明"插件能加载",证明不了"插件在真实 agent 循环里不破坏行为"。
尤其 waterfall 事件监听器(`tools/execute`、`approval/request`、`fs/write-intent` 等)
必须正确透传 `next()`,否则会**静默吞掉下游默认行为**——这类错误只在运行时暴露;而传统验证要真实 LLM API key + token 成本。
**零成本方案**(dsh 仓库自带,无需 API key):
- **mock llm**:脚本化返回——让第一个请求返回"调用 bash 工具"、第二个正常回
复(`--sequence tool_call_success,success`),以此注入工具调用
- **headless profile**:走真实 agent 循环,你的插件挂监听
- **审计 dump**:`DSH_EVENT_AUDIT_DUMP` 导出事件审计快照
# 1. 启动 mock-llm(脚本化注入"调用 bash 工具") pnpm run mock:llm --port 8000 --api-key mock-key \--sequence tool_call_success,success --repeat-last \--tool-name bash --
tool-arguments '{"command":"ls"}' # 2. 跑 headless agent(指向 mock-llm,导出审计)
DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1 \ DEEPSEEK_API_KEY=mock-key \ DSH_EVENT_AUDIT_DUMP=/tmp/audit.json \ pnpm dsh --profile headless "run the bash tool once
and report"
**判定通过**:审计快照 `byMode` 同时含 emit + waterfall、waterfall 链完整出现、agent 正常跑完(`mock response recovered`)。实证:74 事件 / 12 waterfall 全部捕获,完整
生命周期 `session/created → … → tools/pre-execute(wf) → tools/execute(wf) → tools/post-execute(wf) → tools/result`;关键安全证明是**所有 waterfall 监听器正确透传
`next()`、零副作用**——插件既不吞默认行为,mock 注入的工具调用也完整走完链路。
**从源码跑的三点提醒**(#462 作者实测踩坑):sparse clone 一次加全(缺 `vendor/` 会报 `Cannot find package '@deepseek-ai/cordis'`);`build:lib:host` + `build:lib:client`
- web-frontend dist 三层构建缺一不可;`mock:llm` 参数前不要多传 `--`(会被当位置参
数)。
8.8 工具链踩坑
rc.6 时代的工具链已知坑(坑 1/2 已入 [FAQ](./faq.md)):
**坑 1:code 模式 `run_code`/`bash` 的 description required 死循环**([#558] (https://github.com/deepseek-ai/deepseek-harness/discussions/558)
[#581](https://github.com/deepseek-ai/deepseek-harness/discussions/581) [#689] (https://github.com/deepseek-ai/deepseek-harness/discussions/689))
`code` 模式下 `run_code` 与 `bash` 都把 UI 摘要字段叫 `description` 且标成 required:模型常把内层 `bash.description` 当成已传过,外层 JSON 只剩 `{"code":"..."}` → 反复报
`missing required property "description"`,看起来像"随机丢参数"。`#581` 补根因:
`ToolArgsError` 不带工具名,模型无法定位错在哪个工具 → 死循环重试(附可 cherry-pick 修复);`#689` 显示同族问题让 run_code 内所有 `tools.*` 调用都被拒绝。规避:手动补外
层 description 或换标准模式。
**坑 2:流式下工具调用被抹空名**([#725](https://github.com/deepseek-ai/deepseekharness/discussions/725) 同族,已入 [FAQ](./faq.md))
现象:所有工具调用报 `Error: unknown tool ""`。根因:SSE 流式解析用覆盖赋值而非累加,把工具名/ID 抹成空串
([#725](https://github.com/deepseek-ai/deepseek-harness/discussions/725) 根因 + 修复;[#161](https://github.com/deepseek-ai/deepseek-harness/discussions/161)
[#615](https://github.com/deepseek-ai/deepseek-harness/discussions/615) [#694] (https://github.com/deepseek-ai/deepseek-harness/discussions/694)
[#741](https://github.com/deepseek-ai/deepseek-harness/discussions/741) 同族)。
官方修复前只能降级/等版本;模型会反复重试,注意及时中止。
**坑 3:`run_code` 内调用交互式工具被"吞"**([#1476](https://github.com/deepseekai/deepseek-harness/discussions/1476))
`run_code` 程序内调用交互式工具(如 `ask_user_question`)时:同步执行不等异步—— 4ms 就返回空;异步结果约 12s 后回来时会话帧已结束,被直接丢弃。判断为 `run_code`
执行模型的问题(应支持异步工具回调或返回 pending 状态),AGENTS.md 里"别在代码里调交互式工具"的约定只能治标。
---
> **记忆方向提案(#1822 社区设计)**:社区提出"记忆体"(Memory Body)——跨会话、隔离、用户显式挂载的记忆单元,解决"记忆一锅乱炖"(会话结束日志即失效 / session-reference
仅 @提及 3 源且不搜正文)。与记忆家族(dsh-sgme 按场景注入 / dsh-memory / AgentSoul)同向互补:记忆体做底层挂载单元,上层插件可复用。
动手练习(检验你是否真懂了)
- **理解题**:不看原文,列出 dsh 内置的 8 个工具名(简短动词)及各自作用
> 自查:参考本章 8.2 节工具表格
- **理解题**:解释"工具返回 locations → 产物追踪"是什么意思。模型改了什么文件,
UI 怎么知道?
> 自查:参考本章 8.2 节"工具结果与产物追踪"段落
- **动手题**:在 `dsh web` 里发一个"创建一个 hello.py 文件"的任务,观察对话末尾
的"产物 chips",点击打开文件,验证产物追踪是否工作 > 自查:参考本章 8.2 节"产物文件行"说明
- **动手题**:在 `dsh web` 里进行一个长对话(20+ 轮),观察是否触发
compaction(看会话日志有没有"上下文溢出"或"压缩"相关日志)
> 自查:参考本章 8.4 节"长对话自动压缩"段落
- **思考题**:为什么"重要信息要写进提示词"而不是依赖对话历史?compaction 压缩
时会丢什么?
> 自查:参考本章 8.4 节"压缩会丢细节"警告
- **思考题**:本章 8.5 节说"dsh 的工具执行默认有隔离与审批层"。如果你要做一
个"允许模型自动执行所有 bash 命令"的插件,应该用哪个扩展点?有什么安全风险?
> 自查:参考本章 8.5 节"交互审批" + `interaction/*` 包说明
常见疑问 FAQ
> 本章针对工具/上下文的高频问答见下;更多通用问题见 [FAQ 速查](./faq.md)。
**Q1:工具名是 `read`/`write` 这些简短动词,我写提示词时也要用这些名字吗?**
不需要。你写"读一下这个文件""搜索包含 foo 的行",模型会自动映射到对应工具。简短动词名是插件内部实现细节,提示词用自然语言即可。
**Q2:`edit` 和 `str_replace_editor` 是同一个工具吗?**
是。`str_replace_editor` 是内部包名,模型调用时可能显示为 `edit`。功能一样:精准替换文件中的某段文本。工具结果里的 `locations` 用于产物追踪。
**Q3:compaction 压缩后,模型还能记得之前对话的内容吗?**
记得"摘要",但会丢细节。compaction 会修剪历史 + 可选生成摘要,关键信息保留,细节丢失。所以重要上下文(如项目约束、特殊要求)建议写进系统提示或提示词,不要只依赖对
话历史。
**Q4:`context/*` 和 `compaction/*` 有什么区别?**
全站分卷索引 · 43 卷
- 1第 1 卷
- 2第 2 卷
- 3第 3 卷
- 4第 4 卷
- 5第 5 卷
- 6第 6 卷
- 7第 7 卷
- 8第 8 卷
- 9第 9 卷
- 10第 10 卷
- 11第 11 卷
- 12第 12 卷
- 13第 13 卷
- 14第 14 卷
- 15第 15 卷
- 16第 16 卷
- 17第 17 卷
- 18第 18 卷
- 19第 19 卷
- 20第 20 卷
- 21第 21 卷
- 22第 22 卷
- 23第 23 卷
- 24第 24 卷
- 25第 25 卷
- 26第 26 卷
- 27第 27 卷
- 28第 28 卷
- 29第 29 卷
- 30第 30 卷
- 31第 31 卷
- 32第 32 卷
- 33第 33 卷
- 34第 34 卷
- 35第 35 卷
- 36第 36 卷
- 37第 37 卷
- 38第 38 卷
- 39第 39 卷
- 40第 40 卷
- 41第 41 卷
- 42第 42 卷
- 43第 43 卷