夜雨聆风学习资料网

ARTICLE · 1197257

一切皆插件:搭 Agent 从写代码变成装配

一切皆插件:搭 Agent 从写代码变成装配

DeepSeek Harness(命令行里叫 dsh)2026 年 8 月建仓,TypeScript 写的,MIT 许可。这阵子写它的中文技术号几乎都是同一套:一行命令装起来、配个 API Key、装几个插件、再感叹一句「一切皆插件」。口号谁都会念,底下的问题没人回答。

这篇把「一切皆插件」当成一道待验证的命题,去它自己的仓库和文档里找证据,也找代价。基准是官方仓库 deepseek-ai/deepseek-harness 的 0.2.1-alpha.4,对照前一版 0.2.1-alpha.2,依据是仓库内的 docs/ 中文原文与仓库结构。

一、命题一:一切真的都是插件吗

先去仓库看它把东西怎么切。packages/ 底下按能力分目录,面向用户的能力各占一个包:

包
能力
core
agent loop 主干
session
会话与事件
llm
模型适配
storage
持久化
sandbox
进程沙箱
subagent
子代理
workflow
工作流编排
ptc-runtime
程序化工具调用
guard
守卫
goal
长期目标
skill
技能
mcp
外部工具协议
fs
文件系统
terminal
终端
jobs
后台任务
schedule
定时任务

再往下还有 web、document、deliverables、browser-use、computer-use 等等。

清单长不等于零件多。判断它有没有真的拆开,要看这些包之间怎么接。把核心包和它们在共享上下文里的落点摆到一起,接法就出来了:

图 1|核心组件图。左边每个包在右边共享上下文 ctx 上有一个对应服务,消费方只认这个键,不认包。

来源:据官方文档 docs/architecture.zh.md 的「核心包」表自绘。

右边那一列才是重点。模型、工具、会话、活跃 agent 注册表、文件系统,全都是 ctx 上的一个键位。这就把「一切皆插件」从口号变成了一个可以检查的问题:能不能只替换其中一格,而不动别的。

回到清单,先看 core。架构文档的原话是:

“

产品的每一部分都是插件,包括模型适配器、工具注册表、会话日志,以及 agent loop(智能体循环)本身,因此每个都可以从配置替换。

循环确实住在 packages/core 这个目录里,但 core 只是个目录名。同一份文档紧接着还有一句:不存在需要打补丁的特权内核,扩展 dsh 的方式是把插件挂载到其他插件旁边。

模型适配器是插件,这个常见;工具注册表是插件,也不稀奇;但连 Agent 循环本身都是插件,这就是另一回事了。对比第 1 篇里那两家:Qoder CN 的边界在「SDK ↔ 闭源 CLI 子进程」,你改不了循环;Qwen Code 的循环虽然开源可改,但它是 packages/core 里的一段代码,改它意味着你 fork 之后自己维护。dsh 的做法是把这个循环做成了配置项。

命题一成立,而且成立得比 slogan 更彻底。

二、命题二:插件化靠什么撑住

插件架构谁都会画,难的是卸载时不留残余。dsh 底下用的是 Cordis,一份 Koishi 生态里打磨过的插件内核。它的设计约定只有三条,但每条都指向同一个目标:

“

插件向共享上下文贡献服务、类型化事件和可逆的副作用。

关键词是最后一条,可逆的副作用。提示词片段、工具 schema、适配器、提供方和监听器,全部通过 ctx.effect() 或 ctx.on() 安装,reload 和 teardown 时按注册顺序撤销。插件的卸载在这里不是「尽力清理」,而是框架层面的契约。

上面那句「贡献服务」落到代码里,是一个叫能力接缝(capability seam)的结构。官方把一项可替换能力拆成三个角色:声明接口的 Service Definition、实现它的 Service Provider、使用它的 Consumer。三个角色可以分在三个包里,而且互相不认识:

图 2|能力接缝的三个角色。定义包只放接口,实现包和消费包各占一边,彼此没有依赖。

来源:据官方文档 docs/architecture.zh.md 的「能力 seam」一节自绘。

这张图解释了替换为什么便宜:换提供方,动的只是实现包,消费方一行都不用改。官方在文档里把话说到更满一层:文件系统和进程的提供方共享同一个执行世界,所以把这两者指向远程沙箱,Bash、PTY 和 LSP 会跟着一起搬过去,不需要为某个提供方单独 fork 一份。

再往上是一套三层配置:

层
作用
谁写
bundle
官方成套插件组合
DeepSeek 官方
profile
你这台机器上的具名组装清单
你(或模板初始化)
patch
覆盖层,可精确定位到某个插件条目
你

上层覆盖下层,你不动源码就能换掉任意一个能力。官方随仓库发的成套组合包有这几套,也能看出它的分层意图:

组合包
用途
@deepseek-ai/dsh-base
基础
@deepseek-ai/dsh-web-app
Web UI
@deepseek-ai/dsh-headless
无界面执行
@deepseek-ai/dsh-sdk-app
SDK
@deepseek-ai/dsh-sdk-minimal
SDK 极简示例
@deepseek-ai/dsh-acp-app
ACP 服务端

从命令行到一棵跑起来的插件树,中间隔着一串调用。把这条链路摊开看:

图 3|启动装配链路。从 CLI 启动器一路到运行中的 dsh 实例,中间每一步都是官方某个包里的一个函数或加载器。

来源:据官方文档 docs/architecture.zh.md 的「Profile 与组合包」一节自绘,该节给出每一步对应的声明字段。

链路上真正属于你的只有一层:profile 各层。按官方文档,各层依次应用在一个空条目列表之上,顺序是 profile 里有序列出的组合包、它自己的 cordis.patch.yml、home patch,最后是命令行的 --patch overlay。一条 patch 按 id 定位到某个条目,把它的整个 config 换掉,也可以插入新条目。所以「不碰源码也能换」不是宣传语,它是配置层叠的必然结果。

撑起这套设计的形式化依据,仓库 README 是直接点名的:Cordis 的设计写在论文《A Programming Paradigm for Spatiotemporal Composability》(arXiv 2608.25512)里。也就是说,「一切皆插件」不是 dsh 发明的,它把一个已有论文描述的设计拿来当运行时底座,然后在上面盖了一整栋楼。

三条约定加三层配置还有个直接的副产品:SDK 和 ACP 在这里不是独立命令,而是两个 profile。web、headless、sdk、sdk-minimal、acp 是随发行版交付的模板 profile;desktop 由 Electron 桌面应用初始化并占用保留目录 $DSH_HOME/profiles/desktop,与 npm CLI 共享产品数据,但包、启用选择与锁文件各管各的。这些入口共用同一套启动器,差别只在装了哪些插件;连 SDK 都默认绑定 sdk 这个 profile,官方极简示例用的是 sdk-minimal,Python 的运行时 wheel 里装的也是同一个命令。第 1 篇比较过「SDK 与 daemon 的形态差异」,在这里它只是同一份配置的两个取值。

三、命题三:插件市场从哪来

命题一证明了零件可以换,命题二说明了靠什么撑住。但还有个没人问的问题:这些插件,从哪来?

0.2.1-alpha.4 给出了答案,也是这一版最实质的变化:插件市场。

它的机制朴素得有点反直觉:插件市场就是一个 JSON 索引文件,列出可安装的 DSH 组合包及其标题、图标、作者和版本。索引里每一条指向一个 npm 包,或者一个 Git 仓库里的具体目录。而最关键的半句是:

“

DSH 不内置任何索引源。

没有官方市场,没有默认源。你要用,得先去「插件 → 实验性插件 → 更多」里打开自定义插件市场这个实验开关;打开之后,「已安装」旁边才会出现发现标签页,Creator 模式同时获得一个只读的 plugin_market 工具。关掉开关,两者一起消失。

发布端也一样轻。索引是一份 UTF-8 的 JSON,默认不超过 128 MiB,以 2xx 状态码返回、不经重定向即可,放到任意静态主机上就算发布了,GitLab Pages、GitHub Pages、任何能走 https 的对象存储都行。图标可以内联成 base64,也可以并排放一个 icons/ 目录、用相对路径引用。每个索引源只属于当前 profile,不跨环境串门。

至于内容可信度,官方把话说在了前面:

“

市场是第三方内容。每个插件的标题、描述、图标、作者和来源都由市场决定;DSH 检查文件格式,但不验证这些声明。

这句话单独看是免责声明,放在这里就是另一回事了:它和后面沙箱「只做到一半就直说」是同一套语气。

而这件事最有说服力的地方,是它在仓库里留下了时间戳。0.2.1-alpha.2 时,这功能还只是一份提案文档,躺在 .agents/notes/proposed/feature/2026-10-02-plugin-market-index-format.md;到 0.2.1-alpha.4,同一份文件已经挪进了 .agents/notes/implemented/feature/。同期新增的包里,boot/plugin-market、client/ui-plugin-market、util/plugin-market-index、experimental/plugin-market-bundle 都和市场有关。

所以「官方做得越少,社区越繁荣」这句话在这里有工程上的落点:主循环是插件,谁都能替换;插件市场不自建索引源,谁都能开一个。框架只负责定义索引格式,然后退到一边。

四、拉近看:扩展点挂在哪

前三节回答的是「拆得开吗」「靠什么撑住」「从哪来」。但还有个更实际的问题:你要往这套东西里加自己的行为,具体加在哪?

官方把一次轮次(turn)拆成零个或多个步骤(step),一个步骤是一次模型请求加上它调用的工具。整个过程不是一串函数调用,而是一条事件链,从轮次打开、组装提示词、发起模型请求、执行工具,一直到轮次关闭:

图 4|轮次与步骤生命周期。持久的回放事实落在 session/event 里,实时控制与状态走 agent/*。

来源:据官方文档 docs/agent-lifecycle.zh.md 自绘。

图里那几个 agent/pre-step、agent/request、llm/stream 和三个 tools/* 事件是 waterfall(瀑布式事件),监听器必须调用 next() 才能把控制权交下去;agent/turn-stopping 则是 serial 事件,没有 next()。所以「改 agent loop」在 dsh 里通常不是改循环的代码,而是把监听器挂到某个事件上。官方文档对这个机制只有一句话:「事件就是扩展点」,而选对事件域是大多数改动的第一个决定。

工具这一侧还有一张更细的图。一次工具调用要依次穿过策略、钩子、审批、沙箱和结果重写,而这些全都不是循环里的分支:

图 5|工具执行流水线。三个 waterfall 各自可以改写一次调用,任何一环抛错都会被归一化成 isError。

来源:据官方文档 docs/tool-execution-pipeline.zh.md 自绘。

按顺序走一遍:tools/pre-execute 瀑布先跑,钩子、权限和沙箱策略在这一步介入;接着是注册的单调守卫,它只能拒绝或弃权,不能改身份;守卫放行之后进入 tools/execute 瀑布,超时、重试、指标这类环绕分发的关注点包在这一层;再往里才是工具本体。工具跑完,tools/post-execute 瀑布可以接受、阻断、替换结果或补充上下文,finalizeContent 收最后一道仅限内容的不变式,tools/result 再把冻结的权威结果同步通知出去。

官方给这张图的说明是:它要展示的是「策略、钩子、沙箱、文件系统守卫、结果重写、最终结果观察和 UI 渲染在不改变循环的情况下何时运行」。这句话就是「一切皆插件」的工程版本:扩展点被固定成事件,而不是被写进循环里的条件分支。

五、代价一:工程约束变硬了

插件化不是白拿的。要让任意组合都能成立,工程上必须付出代价,而 dsh 把代价明明白白写进了开发文档。

第一条,注册必须是可逆的副作用。任何插件注册东西时,必须同时声明撤销路径,否则重载就会泄漏。

第二条,配置错误必须在加载时报错,不能静默跳过。缺失的 host 值不许提供默认值,注册表或必需 key 缺席就明确失败。这条听起来只是严格,实际是在防一类很难查的 bug:插件树里某处悄悄降级,运行几天之后才以奇怪的方式暴露。

第三条最关键,覆盖率门禁是逐文件 100%:

“

覆盖率门禁(pnpm run test:coverage):门禁级运行,对 packages/*/*/src 按文件 100% 覆盖。未覆盖的行往往是门禁正确标记出的死代码(应删除),而非需要补写的测试。

官方在这一条后面还补了一句:

“

行覆盖率是必要条件,但永远不是充分条件:它证明行被执行过,不证明功能按交付预期工作。

除此之外,普通包只能登记进 Host 或 Client 其中一个 aggregate,跨边界的标识符要用品牌类型(typert),lint 之外还单有一道 pnpm run doc-typecheck 检查文档代码块。这套门禁指向的是同一个目的:让仓库在大量外部分叉与快速迭代下保持稳定。装配式架构的自由度越大,约束就必须越硬,两者是一笔交易。

六、代价二:文档本身成了基础设施

第二个代价是文档。

docs/subsystems/ 下面按主题分文件,从 core、session、sandbox,到 voice-input、sidebar-right、worktrees,每个主题都配齐三份:英文、中文、翻译元数据。其中几份中文文档体量都大得需要分节跳读:配置目录、持久化目录(另附一份完整的 schema JSON)、模块图、工具目录、能力接缝,各自都是独立成篇的长文。

还有两个细节,比体量更说明问题:

一是 docs/postmortem/,事故复盘目录,逐篇编号归档,从 ACP 的默认导出丢注入,到 JS 表达式把文件系统工具关掉。一个刚开源不久的项目,把踩过的坑归档进文档结构里。

二是文档过期会直接阻断 CI。文档站构建前先跑 doc-sync,它用 TypeScript 解析器从源码里提取声明和对应的 JSDoc,断言文档中的代码块与两者同时匹配;改了一个已记录的类型却忘了同步文档,合并就会被卡住。

站在「搭 Agent」的视角看,这件事的含义是:你装配时依赖的不是 API 文档,而是一份把内部接缝也写出来的说明书。capability-seams.md 讲的就是「这个能力从哪接、换掉它要动什么」。要自己组装一个 Agent,这种文档比示例代码值钱。

七、代价三:自由,但不可回退

第三层代价出现在使用姿势上。dsh 同时提供四种运行模式(官方站点定义):

模式
装了什么
适合
Standard
文件编辑、Shell、检索、Skills、计划、子代理、工作流
日常主力
Code
Standard 全部能力,工具通过 Code Mode SDK 暴露
多步任务、大数据量中间结果
Minimal
只有持久化 bash 加一个文本编辑器
基准测试、教学
Creator
Standard 能力 + 运行时检查、插件实验、预设编写
造自己的模式

模式在实现上就是 Agent Preset。dsh-agent-preset 的文档写得很直白:

“

在普通 Cordis YAML 中定义 Agent 的子插件列表。可同时声明多个 preset,由会话选择。声明会提前加载,修改只影响之后创建的 Agent。

最后半句是这套设计的前提条件。工具集决定了会话历史怎么被解释,所以模式改动的生效边界只能划在「之后创建的 Agent」,不能回头改一个已经在跑的会话。自由是有条件的自由。

沙箱也是同一套语气,有几档就说几档:

模式
含义
read-only
只读;后端还要额外授予 /dev/null 这类必需接收器
workspace-write
允许写工作区根目录与后端承诺的临时区
danger-full-access
绕过隔离,消费方直接 spawn 原始 argv

而且这三档只管文件系统效果,网络与进程可见性根本不在这套模式的定义范围内。底层用三个平台的原生机制:Linux 走 bwrap / Landlock,macOS 走 Seatbelt,Windows 走 ACL 受限令牌。而这一点它的写法很直接:后端必须上报强制执行完整性,full 表示该模式承诺的文件效果全部管控,partial 表示只管控了一个子集,「因此要求绝对保证的消费方必须拒绝或向上暴露这一区别」。沙箱主动报告自己只做到一半,把要不要接受交给消费方判断。

MCP 那一章同样把边界写清楚:每个服务器一个连接插件,不支持 MCP 提示词模板、人工输入征询、基于任务的执行和资源订阅。「一切皆插件」不等于「一切都能接」。

八、你实际能搭出什么

说回动手。装 Node,一行命令:

npx @deepseek-ai/dsh web

默认在 http://127.0.0.1:3080 起 Web UI,启动时会顺手打开浏览器。第一次进去要配模型(DeepSeek 官方 API 或任意 OpenAI 兼容端点),然后选工作区。官方文档里的模型配置页:

图 6|官方文档的模型配置页,第一次进入时要在这里选模型端点。

来源:官方仓库 docs/user/guide/providers-models-page.zh.png。

跑通之后,你手上就有了这些可以组装的东西:

  • Headless 入口:dsh --profile headless "job" 跑完打印最终答案就退出,天生适合 CI 和批处理;
  • Code Mode:让模型写一段 TypeScript,把「五步工具调用」合成一次执行。中间结果只留在程序里,不进上下文;
  • 事件日志:模型看到的一切都进一份只增不改的会话日志,系统提示词、思维链、工具调用与结果、子代理调度、每一次上下文注入都在里面。会话恢复、fork、搜索、回放,操作的是同一条事件流。

据内测社区观察,配套的 dsh-external 组织里已经攒了一批仓库,反馈板上的 issue 也在快速增长(二手来源,未经官方核实)。主仓库自己的 Issues 是关着的,只开了 Discussions。「官方做得越少」这句话,连入口设计都在执行。

九、它站在哪

把第 1 篇的三种形态,连同本篇的 dsh 和下一篇要写的 Pi 摆在一起,位置就清楚了。先看「你拿到什么」:

构建形态
代表
你拿到什么
你还要自己补什么
嵌入式 SDK
Qwen Code SDK / Qoder CN SDK
一个 query() 循环 + 工具层
沙箱、评测、SLA
协议型 daemon
qwen serve
(HTTP + SSE / ACP)
多客户端共享的 Agent 后端
容器化、运维、会话治理
托管云
Qoder Cloud Agents
运行时 + 配额 + 隔离容器
供应商绑定、credits 预算
插件化 harness
DeepSeek Harness
一套可替换的能力零件 + 事件日志
你得先决定装哪套
极简核 + 扩展
Pi Coding Agent
一个极小的 agent loop + 自带工具层
子代理、计划模式、权限系统都不内置(下一篇写)

前三种是「买一个 Agent」,差别在买的深浅;后两种是「自己装一个 Agent」,dsh 和 Pi 是这条路的两端:一个把零件拆到最细、配一整套目录让你自己拼,一个把核削到最小、明确告诉你进阶能力全部自己补。

再看一层:客户端和服务端之间那条线

上面那张表看的是能力面。再往下还有一层更要紧:Agent 跑在哪个进程里,客户端和服务端之间那条线由谁定义。这一层决定了你以后想换部署形态时要付多大代价。

构建形态
Agent 跑在哪
客户端边界由谁定
换传输要动什么
Qoder CN SDK
你 spawn 出来的闭源 CLI 子进程
产品方;SDK 只是一层 stdio + JSON Lines 的桥
动不了
Qwen Code SDK
你的进程内,core 直接嵌入
你;core 是源码
没有独立的传输层
qwen serve
独立 daemon 进程
协议方;客户端按 ACP 接
协议本身
Qoder Cloud Agents
供应商的容器
供应商;你手里只有 REST
你无权动
DeepSeek Harness
由载体决定,进程内或跨网络
编译期生成的白名单,运行时再加一层 Peer 与 role 判定
换 Connection 载体,Remote 描述符与客户端调用面不变

dsh 这一格展开看。Host 与 Client 是两个隔离的 TypeScript aggregate,两边的构建不会进同一个 ts.Program:Host 入口不导入 Client 的 Context 合并,Client 入口也不导入 Host 的服务。跨边界的调用得先用 @Remote 或 @RemoteScope 声明,没标记的方法根本不会出现在生成的 Client 类型里。客户端能调什么,在编译期就被划定了一次。

传输是另一回事。Connection 提供 RPC 载体、请求关联、信任边界和 /api 的 HTTP bridge;流式方法走多路复用的 WebSocket 或者进程内载体。官方在这件事上写得很直白:替换载体,不要求改动 Remote 描述符,也不要求改动客户端的编程接口。也就是说,「Agent 和界面在不在同一台机器上」被做成了一个可以替换的接口,而不是一个架构前提。

第 1 篇那几家交付的是各自定好的那条线,dsh 交付的是一条可以换的线。

十、一个人用,和一个团队用

前面讲的都是机制。最后落回使用场景:同一批零件,一个人用和一个团队用,装配时该选的几乎相反。

关注点
一个人用
一个团队用
Agent 跑在哪
自己那台机器上,进程内载体或桌面应用
一个被多人接入的 Host,客户端跨网络连过来
传输
进程内载体
Connection 的 /api:HTTP 与多路复用 WebSocket
客户端能调什么
全部
编译期白名单,运行时再按 Peer 与 role 判定
沙箱
可以开到 danger-full-access
收到 read-only 或 workspace-write
审批
关掉,别打断
打开,ctx.approval 逐次放行
凭据
存在自己的凭据域
设置读取一律脱敏,role('secret') 的字段不进响应
插件来源
自己开一个索引源
每个 profile 各带索引源,不跨环境
无人值守
headless
 一次性跑完就退
ACP 服务端或 SDK,由上层系统驱动

这两列不是两套代码,是同一批插件加同一个权限选择器的两种取值。官方把沙箱模式(sandbox/mode)和审批策略(approval/policy)这两个相互独立的强制开关捆成具名预设,客户端把它当单个 Permissions 选择器呈现,配置表里存的是「未来会话的默认值」。

「一个团队用」那一列里,真正落到实处的是远程访问控制。@deepseek-ai/dsh-api-remote-access 由业务方注册基于 role 的 policy,用来判定非 owner 的 Peer 能调用哪些 Remote 方法,同时过滤列表结果、给每个 Peer 推一份访问快照。Gateway 每次调用都带着这次调用代表的 Peer;不是 owner 的调用,要先解析它访问的资源、再问一次 ctx.remoteAccess.decide(),被拒的调用连 lookup 都不解析,也不会激活 Agent。它还留了一条边界:不带 @Remote 标注的方法仍然是普通的服务方法,只是调用者仅限于进程内。访问控制约束的是「什么能成为 Remote 方法」,不是「服务能做什么」。

有一件事得说清楚:官方没有写任何面向企业部署的指南,也没有多租户、配额、计费这类章节。这张表是从机制上推出来的:这些接缝摆在代码里,说明「多个客户端共用一个 Host」是被设计过的场景,但「怎么把它变成一套能交给一整个团队的内部平台」,文档里没给答案。这大概也是 dsh 和 Qoder Cloud Agents 那一类产品最本质的差别:治理层由谁提供,一个不提供、留给自己补,一个连同运行时一起交付。

文档没给答案,不等于这个空缺没人填。有个第三方项目 MOVO(himovo/movo),自我定位就一句话:DSH 负责智能体如何运行,MOVO 负责智能体如何进入企业生产环境。它不是 dsh 的一部分,而是在 dsh 的 Runtime、Skill、工具与 MCP 之上,补上面那张表右列缺的那一层。

补出来的东西分两边,正好对上表里的两列。

员工那边是一个工作台。对话、检索企业知识、做多轮研究,回答要留下引用和支撑依据;PDF、DOCX、XLSX、PPTX 这类文档连同里面的图与图表一起解析;报告、文章、演示文稿、表格、PDF 直接生成成交付物。

管理员那边是一套管理面。组织、用户、角色有了归属,模型、知识、Skill、工具集中配置;敏感工具操作要审批,定时任务可编排,执行过程与产物留痕可审计。再加上一层统一网关把工作台、管理后台和几个后端服务串成一个整体,一次部署拿到的是完整产品,不是一堆零件。

还有一点是位置:模型服务自己接,应用数据、企业知识与运行服务都留在部署者自己的环境里,凭证加密存放。dsh 只交付运行时,这就是下游把它接住的样子。它自己划的边界也很清楚:只需要底层 Runtime,dsh 已经够了;要把 Runtime 变成可部署、可管理、能服务真实用户的产品,差的正是这一层。

它这套东西是按能力拆开的 dsh 包组起来的;仓库里的兼容性文档还明令禁止 fork 内核,DSH Core 的 fork 记为 none、状态 prohibited,不许改动 vendored 或已安装的 dsh 源码。命题一和命题二在第三方手上又各自复现了一次。

最后

回到标题那句话。dsh 真正改变的不是技术,是搭 Agent 这件事的重心:以前你要写代码,现在你要做装配决策。装哪套模型适配、留哪几层沙箱、要不要 Code Mode、会话日志存哪里,这些决定以前藏在框架的默认值里,现在被摊到配置文件上当选择题。

上一节讲的是部署形态。回到人本身:它适合已经想清楚自己要什么 Agent 的人,也适合团队里那个必须能回答「我们这套 Agent 到底由哪些零件组成」的人。不适合的也很明确:如果你只是想要一个开箱能用的编码助手,Minimal 模式那两个工具会让你当场失去耐心,Standard 模式下的装配工作量也不划算。

一句话:它把 autonomy 从「能不能改」推进到了「要不要装」,代价是你得先想清楚要装什么。

「Agent 构建」系列第二篇,下一篇见。

参考引用

  • DeepSeek Harness 官方仓库:https://github.com/deepseek-ai/deepseek-harness
  • Cordis 仓库:https://github.com/cordiverse/cordis
  • 论文《A Programming Paradigm for Spatiotemporal Composability》:https://arxiv.org/abs/2608.25512
  • MOVO 项目:https://github.com/himovo/movo
  • dsh-external(第三方社区组织,未经官方核实):https://github.com/dsh-external

相关学习资料