它不是聊天壳,而是 Agent 产品运行时
判断一个 AI 项目,最容易犯的错误,是按界面给它分类。
能对话、能选模型、能展示工具卡片,于是我们把它叫“AI 客户端”;能读写文件、运行 Bash,于是再加一个“编程 Agent”的标签。但这些标签解释不了 DeepSeek Harness 仓库里 219 个 package、三类事件域、Profile/Bundle 组合、Host/Client 合同生成、子 Agent continuation 和原生沙箱的工程投入。
更准确的说法是:DeepSeek Harness,简称 dsh,是一套用于组装 Agent 产品的运行时。它提供的不是某个固定 Agent 的完整答案,而是一组可以被组合、替换、隔离和回收的基础能力。
第一层:用户看是聊天,系统处理的是持续工作的生命周期
普通聊天应用的闭环很短:用户输入,调用模型,显示文字。
Agent 产品的闭环要长得多。一次任务可能包含多次模型请求、多个工具调用、人类审批、文件修改、后台工作、上下文压缩、会话恢复和子 Agent 协作。界面上的一条回复,只是这条链路的一个投影。
dsh 的公开入口包括 Web profile、headless runner、JS/Python SDK 和 ACP。默认 Base bundle 还装配了模型适配器、Session、工具、文件与命令、沙箱、审批、Skills、Goal、Compaction、Subagent、Workflow、Telemetry 等能力。
这时真正重要的问题不再是“如何显示一条消息”,而是:
一条输入究竟进入当前步骤还是下一轮? 模型看到的历史能否在重启后重建? 工具调用的参数、权限判断与实际执行是否一致? 可以并行的工具如何加速,又怎样保持确定的提交顺序? 本地文件与进程换成远程沙箱时,要不要重写所有工具? 子 Agent 暂时退出进程后,怎样继续原来的会话?
这些问题的共同答案,不在模型 API,而在运行时。
第二层:从源码看,它由四个平面组成
第一是组合平面。
dsh 运行的是一棵 Cordis 插件树。CLI 读取 profile,按顺序叠加 bundles,再应用 profile patch、Harness home patch 和命令行 --patch。dsh-base 是所有 profile 的第一层,Web 和 headless 在它上面形成不同产品。最终运行的不是“仓库里有哪些包”,而是这棵求值后的插件树。
第二是执行平面。
core/agent 定义 Agent 接口、inbox 和 live registry,core/agent-loop 提供默认 driver。输入进入 inbox 后,driver 打开 Turn;每个 Step 组装系统提示和工具 schema,从 Session 派生消息历史,调用 LLM,记录流式 chunk 和最终消息,再调度工具。一个 Turn 可以没有 Step,也可以因工具或 steering 产生多个 Step。
第三是事实平面。
core/session 持有 append-only 事件日志。模型历史由 deriveMessages() 从日志的 surface 投影而来;UI、持久化、fork、resume、query 和 telemetry 也消费这条事实流。仓库根级不变量写得非常明确:model-visible iff logged——模型可见的内容必须已经记录,不能只藏在运行内存里。
第四是能力平面。
文件、子进程、Shell、Sandbox、Web、Subagent、Workflow 都被定义成能力接缝。一个接缝由 Service Definition、Provider 和 Consumer 组成。比如替换 ctx.fs 和 ctx.subprocess Provider,可以把文件工具、Bash、PTY 与 LSP 一起迁入远程执行环境,而不必为每个工具复制一套远端版本。
这四个平面通过 Cordis Context 连接,却不互相吞并:组合平面决定装什么,执行平面决定怎样工作,事实平面决定发生过什么,能力平面决定在哪里完成。
第三层:它创造的价值,是把变化约束到可定位的边界
对 AI 学习者,dsh 的价值是展示一个真实 Agent 的完整结构。Agent 不是“Prompt + while(tool_calls)”,而是 inbox、状态、模型适配、工具事务、事实日志和恢复边界的组合。
对开发者,最值得借鉴的不是 package 数量,而是约束变化的方法:
新模型进入 LLM adapter registry; 新能力通过工具或 service seam 接入; 新策略监听 pre-step、request 或 tools waterfall; 单 Agent 差异通过 scope 与 preset 表达; 新 UI 从 Session facts 投影,而不是解析某个前端专用文本流; 新产品通过 bundle/profile 组合,而不是 fork 主循环。
对老板或技术负责人,价值在产品族复用和供应商替换。同一套运行时可以装成 Web、headless 或 SDK 产品;模型、存储、搜索、子 Agent 和执行环境不是写死的单一供应商。真正需要评估的是:这些替换点是否对应公司的长期变化,而不是“功能清单比别人多几个”。
代价同样明显。219 个细粒度 package、Cordis effect/fiber/scope、Host/Client 双面和大量生成合同带来很高的学习与治理成本。项目仍是 0.1.0-rc.5 Developer Preview,官方明确允许破坏性变化;Session format v0 也没有一般性兼容承诺。
所以,dsh 适合两类团队:一类用它学习 Agent 基础设施;另一类确实要构建多宿主、多模型、多执行环境的 Agent 平台,并愿意投资组合治理。若目标只是做一个固定 FAQ Bot,它很可能过重。
最终,dsh 最有价值的不是“DeepSeek 出了一个聊天产品”,而是一种工程判断:Agent 产品的长期资产不只在模型能力,更在模型之外的组合、事实、权限、执行和恢复边界。
源码核验索引
项目定位与成熟度: README.zh.md全仓不变量: AGENTS.md四平面依据: docs/architecture.md默认产品组合: packages/bundle/base/cordis.patch.ymlAgent 主循环: packages/core/agent-loop/src/agent.tsSession 投影: packages/core/session/src/index.ts能力接缝: docs/capability-seams.md
本文基于指定 commit 的静态源码分析。
夜雨聆风