# 第 6 章:进阶与性能调优 > 本章目标:从"能跑"到"跑得好"——推理档位策略、工具调用耗时分析、真实踩坑清单。 ## TL;DR(本章核心,30 秒版) 1. **时间花在哪**:模型思考占 ~90%,工具执行 <1%,网络/渲染 ~10%——优化思考时间是性价比最高的提速 2. **三档策略**:`low`(简单/批量轮次)、`high`(日常默认)、`max`(复杂推理/debug)——手动 UI 选或插件自动调 3. **耗时可视化**:Web UI 底部统计行(LLM Xs / 工具调用 Ys)是最快的瓶颈定位手段 4. **8 个真实坑**:rc.1 依赖断裂、插件缺 main、next() 忘 await、事件类型不识别、client 测试跑不了、缓存命中误判、端口占用、推理序列化丢 reasoning(#739) 5. **评测三问**:谁测的、什么 harness、验证器多严——跑分要带条件看
本章导航 - [6.1 性能模型:dsh 的时间花在哪](#61-性能模型dsh-的时间花在哪) - [6.2 reasoning_effort 策略(官方三档)](#62-reasoning_effort-策略官方三档) - [6.3 工具调用耗时可视化](#63-工具调用耗时可视化) - [6.4 常见坑清单(真实踩过,含解法)](#64-常见坑清单真实踩过含解法) - [6.5 评测视角:官方成绩单 vs 独立实测](#65-评测视角官方成绩单-vs-独立实测) - [6.6 缓存策略:让每次调用都更便宜](#66-缓存策略让每次调用都更便宜)
## 6.1 性能模型:dsh 的时间花在哪 实测一个"创建文件"任务的耗时分布: | 阶段 | 占比 | 说明 | |---|---|---| | 模型思考(Think) | ~90% | **每次工具调用前**都会重新思考,是绝对大头 | | 工具执行 | <1% | 文件写入等毫秒级 | | 网络/渲染 | ~10% | API 往返 + UI 更新 | **推论**: - 简单任务 → 优化思考时间(降推理档) - 长工具链任务 → 每步都省思考时间,累计收益最大 - 工具本身慢(搜索/大文件)→ 优化工具实现,不是调档 ## 6.2 reasoning_effort 策略(官方三档) | 档位 | 场景建议 | |---|---| | `low` | 简单/确定性轮次:文件操作、批量、工具链中的廉价步 | | `high` | 日常 Agent 任务(默认) | | `max` | 复杂推理、长链规划、debug | **手动**:UI 的"推理等级"选择器,或 `~/.dsh/settings.yaml` 的 `reasoningEffort`。 **自动**:插件按工具轮次动态降档(示例提速插件,第 4 章)。 ## 6.3 工具调用耗时可视化 dsh 的会话统计行(Web UI 底部)显示:`N 轮 · M 步 | LLM Xs · 工具调用 Ys | 首 token 平均 ...`——这是最快的瓶颈定位手段。 进阶:host 插件监听工具事件做 per-tool 计时(提速插件示例已内置 host 日志版本),把"哪个工具最慢"暴露出来。 ## 6.4 常见坑清单(真实踩过,含解法) | # | 坑 | 现象 | 解法 | |---|---|---|---| | 1 | rc.1 依赖断裂 | `pnpm install` 404(`dsh-type-meta` 等从未发布) | 依赖用 `^0.1.0-rc.6` 线 | | 2 | 插件缺 main | `No "exports" main defined` | 暴露 `.` 入口;`"main": "src/index.ts"` 可被 tsx 加载 | | 3 | `next()` 忘 await | provider/model 丢失报错 | `agent/request` 的 `next()` 返回 Promise,必须 await | | 4 | 事件类型不识别 | `'agent/request' is not assignable to keyof Events` | npm 未 re-export 类型增强,边界放宽签名 | | 5 | client 测试跑不了 | jsdom 报 `window.__ModuleLoader__` undefined | client 产物依赖 dsh 引导机制,组件测试在官方 CI 跑 | | 6 | 简单任务"突然变快"的误判 | 1s vs 110s 差异被误归因 | DeepSeek context cache 命中也会提速——A/B 测试要用全新 prompt | | 7 | 端口占用 | `dsh web` 起不来 | `netstat -ano \| findstr 3080` 找 PID kill | | 8 | 推理序列化省略空 reasoning([#739](https://github.com/deepseek-ai/deepseek-harness/discussions/739)) | **验证点**:`off`(thinking:disabled)档正常(仅 `high`/`max` 触发);`high`/`max` 下工具调用轮次**没有思考内容**时,serializeAssistant 里 `toolCalls.length > 0 && reasoning.length > 0` 条件把空的 reasoning 字段省略 → 下一轮请求报 400(invalid pi-ai replay state) | 判断为 bug(应保留 reasoning 占位):修复方向是序列化时**始终保留**该字段 | ## 6.5 评测视角:官方成绩单 vs 独立实测 (结合 0813 正式版发布)看 Agent 模型成绩单要三问: 1. **谁测的**?官方自测(自家 Harness)vs 独立第三方(AA 等) 2. **什么 harness**?框架不同分数差很大(官方 Terminal-Bench 87.9 vs AA 独立 79) 3. **验证器多严**?宽松验证器(SWE-bench Verified 8.5% 假阳性)vs 严格(DeepSWE 0.3%) dsh 的 `agent/request` waterfall 让模型跑分可复现——这是它相比闭源产品的工程优势。 ## 6.6 缓存策略:让每次调用都更便宜 第 5 章讲了高缓存命中率的价值(实测会话缓存命中率 97%;缓存折扣 Flash 档 98% / Pro 档 99%+),这里给出**可操作策略**: | 目标 | 做法 | |---|---| | 提高命中 | 长任务**保持会话延续**(避免频繁新建会话) | | 提高命中 | 系统提示/技能目录等**前缀保持稳定**(不要频繁改配置) | | 提高命中 | 批量任务放同一会话/同前缀(如同一批文件分析) | | 降低成本 | 简单轮次用 `low` 档(思考 token 减少 → 总 token 下降) | | 监控 | 会话统计行看"缓存命中 %"(Web UI 底部)——低于预期就检查前缀稳定性 | **成本模型速记**:`总成本 ≈ 输出token×输出价 + 输入未命中×未命中价 + 输入命中×命中价`——Agent 工作负载输入占比高,**缓存命中率是成本的第一变量**。 --- ## 动手练习(检验你是否真懂了) 1. **理解题**:不看原文,说出 dsh 任务耗时的三个组成部分及各自占比。为什么"优化思考时间"是性价比最高的提速手段? > 自查:参考本章 6.1 节耗时分布表格 2. **理解题**:解释 `low` / `high` / `max` 三个推理档位分别适合什么场景。如果一个任务"需要读 10 个文件然后做简单汇总",应该用哪个档位? > 自查:参考本章 6.2 节三档策略表格 3. **动手题**:打开 `dsh web`,跑一个"创建 3 个文件"的任务,观察 Web UI 底部的统计行(LLM Xs / 工具调用 Ys),记录数据并分析瓶颈在哪 > 自查:参考本章 6.3 节"耗时可视化"段落 4. **动手题**:把 `~/.dsh/settings.yaml` 的 `reasoningEffort` 从 `high` 改为 `low`,跑同一个简单任务,对比耗时差异。再改回 `high`,跑一个复杂推理任务,对比差异 > 自查:参考本章 6.2 节"手动"段落 5. **动手题**:模拟"端口占用"坑(先起一个服务占 3080 端口),用 `netstat -ano | findstr 3080` 找到 PID 并 kill,然后正常启动 `dsh web` > 自查:参考本章 6.4 节坑 #7 6. **思考题**:本章 6.5 节说"评测要三问:谁测的、什么 harness、验证器多严"。请用一个具体例子解释:同一个模型,在不同 harness 下跑分为什么会差很多? > 自查:参考本章 6.5 节"官方 Terminal-Bench 87.9 vs AA 独立 79"的例子 ## 常见疑问 FAQ **Q1:为什么我的 dsh "有时候特别快,有时候特别慢"?** 两个主要原因:① DeepSeek context cache 命中时,首轮上下文注入会快很多(1s vs 110s 的差异可能来自这里);② 推理档位不同,思考时间差几倍。做 A/B 对比测试时,要用全新 prompt(避免缓存命中)+ 固定档位。 **Q2:示例提速插件真的能提速多少?有没有实测数据?** 提速收益取决于任务类型。简单任务(1-3 步)dsh 本来就快,插件效果不明显。**长工具链任务(20-50 步)收益最大**,因为每步思考降档的累计效果显著。具体数据参考第 4 章示例代码的实测日志。 **Q3:我把推理档位设为 `low`,模型质量会下降很多吗?** 取决于任务。简单文件操作、批量处理、确定性任务用 `low` 质量几乎无差别。复杂推理、长链规划、debug 用 `low` 可能漏掉关键步骤。建议:日常用 `high`,批量/简单任务手动切 `low` 或用提速插件自动降档。 **Q4:坑 #6 说的"context cache 命中"是什么?怎么判断是否命中?** DeepSeek API 会对重复/相似的上下文做缓存,命中时首 token 时间大幅缩短。判断方法:看 dsh 会话日志里的"首 token 平均"指标,如果某次突然从 10s+ 降到 1s 以下,大概率命中了缓存。做性能对比测试时,用全新 prompt 避免缓存干扰。 **Q5:rc 阶段的破坏性变更会影响性能吗?升级后需要注意什么?** 可能影响。rc 阶段的 agent-loop、waterfall 签名、插件 API 都可能变。升级后:① 跑一遍 `dsh --version` 确认版本;② 看官方 changelog 有没有 breaking changes;③ 跑一个你熟悉的任务对比耗时和行为;④ 自定义插件检查类型兼容性。 **Q6:我想做性能基准测试(benchmark),有什么建议?** 三个原则:① 固定环境(同模型、同网络、同档位);② 用全新 prompt 避免缓存;③ 多次运行取中位数(单次波动大)。记录:墙钟时间、LLM 耗时、工具调用耗时、首 token 时间。参考本章 6.1 节的耗时分布模型设计你的 benchmark。 --- **下一章**:[第 7 章:生态与资源](./07-ecosystem.md) —— 加入 dsh 生态的完整地图。