📌 本文为实战复盘原创文章,发布于本站:haifeiWu.github.io
建站那篇里我说"从想搭博客到博客跑起来,隔了整整一个夏天";这次不一样,两天,44 个会话,2324 步执行——只隔了一个周末。
缘起:agent 的工作日志长什么样#
用 DeepSeek Harness(下文简称 dsh)干了两天活,攒了一堆会话。写代码前有个习惯:先搞清楚数据在哪。翻了一下发现,dsh 把每个会话都落在了本地:
~/.dsh/sessions/<工作区路径编码>/<会话ID>/session.jsonl.zstd每个会话是一个 zstd 压缩的 JSONL 事件流,从创建到结束,每一步都有记录:用户消息、助手消息、turn/step 的开始结束、每次工具调用、审批策略变更,甚至自动生成的会话标题。解压之后长这样:
{"type":"turn/start","seq":11,"time":1786778276273,"data":{"turn":1}}
{"type":"step/start","seq":14,"time":1786778276365,"data":{"turn":1,"step":1}}
{"type":"tool/call","seq":...}这哪里是日志,这就是 agent 的工作日报。于是写了个小脚本把全部会话扫了一遍,数字如下:
| 指标 | 数值 |
|---|---|
| 会话总数 | 44(其中 40 个非空) |
| 对话轮数 | 141 |
| 执行步数 | 2324 |
| 用户消息 | 265 条 |
| 助手消息 | 1019 条 |
| 时间跨度 | 2026-08-14 09:26 ~ 08-15 15:30 |
44 个会话分布在 12 个工作区目录下,最大的单会话 418 步、28 条用户消息。下面按主线拆开看。
主线一:从 pi 到 dsh,飞书桥接的诞生#
一切要从一个调研会话说起(13 轮、60 步):当时项目的架构是 lark-cli + pi,想用 dsh 顶替 pi,于是先让 dsh 自己评估"DeepSeek Harness 替换 pi 的技术方案与可行性"。结论很务实:不硬替换,直接基于 dsh + lark-cli 新建一个项目 feishu-dsh-bridge。
随后就是本次复盘里最大的一仗:一个 418 步、28 条用户消息的会话,按照设计文档把桥接完整实现出来。核心是一个 NDJSON RPC(stdin/stdout) 协议,对齐了 prompt / cancel / ping / resume / get_last_assistant_text 这些原语,让飞书侧的消息能驱动 dsh 干活。
这仗打得并不顺利,踩了两个印象深刻的坑:
坑 1:发一条飞书消息,回了两条#
“发一条飞书消息,但是会回复两条,其中一条执行失败。“排查半天,真相是本地和 Docker 各跑了一个 bridge 实例,消息被两个实例同时消费,一个成功一个失败。解法简单粗暴:停掉本地的,只保留 Docker 的。双实例是最难排查的 bug 之一,因为它看起来像逻辑问题,其实是拓扑问题。
坑 2:容器只读,挂载点建不出来#
容器根文件系统是 read_only: true,/app 整树又被项目根目录只读 bind,运行期想新建挂载点直接报 read-only file system。最后方案是把宿主机目录以只读卷的形式挂进容器:
- ${HOME}/work:/app/host-work:ro桥接上线后还有个收尾会话:README 全面去 pi 化、仓库打上 dsh 标签,从此这个项目只属于 dsh。
主线二:给 dsh 写插件,一写就是五个#
dsh 的扩展方式是 cordis 插件:声明 name / inject / Config / apply,可以注入 tools / agents / sessions / systemPrompt。这两天围绕它写了五个插件,正好覆盖了"一个 Agent 平台插件生态"的各种形态:
computer use:让 dsh 拥有"手”#
在 dsh 主仓库的会话里从零写的桌面控制插件(173 步):鼠标点击/拖拽/滚动、键盘输入、截图、屏幕 OCR 一整套工具。做完直接装进 web profile 实机验证,还跑了一个 e2e 冒烟会话——让插件打开 example.com 并汇报页面内容,一次通过。
dsh-ocr:让 dsh 拥有"眼”#
这是个完整的"调研 → 验证 → 开发"三部曲(225 步)。先调研"为 dsh 开发一个可以看图的插件"的实现方案,结论是两条路:
- macOS Vision 做 OCR:毫秒级,返回文本+像素坐标,任何模型都能消费,不花 token;
- Ollama 本地 VLM 看图:默认 qwen2.5vl:3b,中文描述,离线可用。
为了验证"给 Mac 装识图小模型可行么",专门装 Ollama 跑了一轮基准测试,确认这台电脑带得动。最终交付 ocr_image + view_image 两个工具,12 个 commit,TDD 全绿。这轮的感悟是:能本地跑就本地跑,能用系统能力就不用大模型——OCR 这种高频操作,用系统 API 一毫秒搞定,何必去烧 API 额度。
DeepSeek API 用量监控:让 dsh 学会"记账"#
这个会话最久(10 轮、347 步),需求也最"产品化":实时显示 DeepSeek API 的 token 消耗、金额花费和账户剩余金额。中途的迭代很能说明 agent 协作的节奏:
- 先做出来 → 要求"显示位置像上下文组件,集成进一个按钮";
- 再要求"展示今天的消费、按模型拆分、最近 7 天趋势";
- UI 优化:参考上下文组件,能用图标就不写字,v4 flash / v4 pro 做成简称;
- 最后一轮返工:“最近 7 天的金额算得不对,你是怎么计算的?"——账目核对到 ¥61.85,一分不能差。
飞书互通 + 配置迁移:打通边界#
飞书互通插件(70 步):把 dsh 的会话结果和待审批消息通过 feishu-dsh-bridge 推到飞书,同时能接收飞书消息回来执行——让 dsh 变成了一个可以远程遥控的 agent。配置迁移插件则是一键把 claude / pi / codex / workbuddy / qcoder 的配置搬到 dsh(这个会话 8 月 15 日刚开,还是子代理在推进)。
另外还有个没打完的仗:给 dsh 配置 GitHub MCP(92 步),最后卡在 loader 的插件实例语法上,会话结束时的原话是"查 loader 源码里正确的『新增插件实例』语法”——给 agent 配 MCP 也需要查源码,这很真实。
主线三:跨会话通信,完整跑了一遍"开发流水线"#
要说这两天最有价值的一件事,是一个 27 轮、185 步的调研会话,第一句话是:
“如果想要实现在 dsh 中的跨会话通信,我该怎么做?”
从这个问题长出了一个独立仓库 dsh-courier。架构并不复杂,但很扎实:
| 模块 | 职责 |
|---|---|
| Mailbox 信箱 | JSONL 持久化的消息队列,重启不丢 |
| RoleRegistry 角色注册表 | 角色到会话的持久化映射 |
| Courier 投递服务 | 唤醒、排队、补投、FIFO |
| 工具三件套 | courier_send / courier_register / courier_list |
| 角色协议 prompts | 按角色注入系统提示词 |
真正有意思的不是架构,是过程。这次走了自研的 dev-pipeline 流水线:8 个任务,每个任务一个"实现子代理"配一个"评审子代理",评审发现问题就派"修复子代理",最后整支终审再修一轮。44 个会话里 20+ 个是这条流水线的子代理,每个子代理都有独立的会话记录——这就是为什么会话数这么多。
流水线的效果是实打实的:终审阶段真的揪出了两个隐藏 bug——给自己发消息(self-send)没有拦截、角色重绑后旧的逆向映射没清理。修复会话先写回归测试复现 RED,再修到 GREEN,最后 40/40 全绿、10 个 commit 收尾。子代理的 review 不是走过场,它是真能抓到问题的那种。
主线四:生活类的自动化#
除了写代码,dsh 还被用来干了不少"生活杂活":
- 考勤打卡(133 步):先让 dsh 查飞书文档总结考勤规则,再把打卡绑定到对应的命令行,最后更新打卡时间窗口(上班 08:50
09:30、下班 18:0021:00,闭区间含边界)。期间它还试图帮我办进京证……连进京证 API 都接上了。 - 持仓分析文档:把"纳指分批止盈 1/3~1/2"这种拍脑袋表述,修正成"按目标仓位再平衡",止盈资金去向、溢价率执行条件写得明明白白——让 agent 帮忙复核投资结论,它给的逻辑比原文档严谨。
观察:两天下来的一些总结#
- 会话即日志。
~/.dsh/sessions下的 JSONL 事件流记录了 agent 的每一步,复盘成本几乎为零。给团队写周报?先解压会话文件。 - 插件的核心是注入。dsh 插件能注入 tools、agents、sessions、systemPrompt,能力边界一下子就打开了——从"对话"变成"可编程的平台"。
- 本地优先。OCR 用系统 Vision、看图用 3B 小模型,能省 token 的地方绝不动大模型;API 用量监控插件上线后,每一分钱都看得见。
- 流水线化开发可行。实现 + 评审 + 修复的子代理循环,TDD 红线先行,质量有保障,规模可复制。8 个任务并行推进,两天交付一个完整的 npm 插件。
- 信任是逐步建立的。8 月 15 日中午,我把 dsh 的审批策略从 ask 改成了 never——会话日志里清晰地记录着这一刻。从"每步都要问"到"放手去干",是 agent 从玩具变成工具的标志。
结语#
两天,44 个会话,2324 步。回头看,dsh 给我的不是"自动补全代码",而是一个可以无限并行的开发团队 + 生活助理:桥接、插件、流水线、打卡、记账,全都发生在同一天。
如果你也想看看自己的 agent 都干了什么,其实很简单:
unzstd ~/.dsh/sessions/*/*/session.jsonl.zstd | jq -r '.type' | sort | uniq -c下一篇文章,准备把 dsh-courier 的架构和子代理流水线拆开细讲,先挖个坑。