DeepSeek Harness 的 bundle/profile/patch 到底是什么?cordis.patch.yml 底层实现拆解

发布时间:2026/10/28 1:52:45

DeepSeek Harness 的 bundle/profile/patch 到底是什么?cordis.patch.yml 底层实现拆解 CFzjyAI Engineer▍深耕领域AI Agent 架构设计Harness 插件开发Context Engineering多智能体协同 RAG▍技术底座PythonTypeScript·Cordis 插件MCP Skills·FastAPIDocker▍工程能力专注 Agent 运行时与 Harness 插件开发、长上下文与流式交互优化、LLM 全链路工程化落地「 让 AI 交互更智能让技术落地更高效 」欢迎技术探讨 / 项目合作关注解锁大模型与智能交互的无限可能DeepSeek Harness 的 bundle / profile / patch 到底是什么cordis.patch.yml 底层实现拆解《DeepSeek Harness 插件架构》连载专栏 · 第 05 篇前四篇讲的是插件怎么运行这一篇讲插件怎么组装成应用。DSH 的安装与装配机制绕不开三个词——bundle组合包、profile配置档、patch补丁层——它们频繁出现在官方文档、插件市场页面和报错信息里但很多教程只给命令不给原理导致两个最常见的困惑“为什么我装了插件它不生效”“为什么我的配置被覆盖了”这一篇把三个概念拆到底层bundle 是我贡献什么的答案profile 是这套应用由什么组成的答案patch 是两者之间的粘合层。读完你会理解 DSH 配置系统的层序模型四层逐层覆盖、覆盖的整行替换语义不是深度合并、以及从 GitHub 装插件的构建坑。本文事实全部来自官方文档《打包与安装插件》。痛点一装了不生效。插件装进 profile 了但启动后毫无反应——因为 patch 层的顺序和覆盖语义没搞懂。痛点二配置被神秘覆盖。你在 profile 里改的配置不生效或者你发布给用户的默认配置被用户悄悄改掉了——层序规则没吃透。痛点三分发就是玄学。npm 发布、GitHub 直装、tarball 交付三种方式各有什么坑全凭试错。读完你会拿到bundle/profile 两份 manifest 的完整结构、四层层序模型与覆盖语义、从打包到安装的全流程、三种分发方式的选型与避坑。想追完整系列下一篇0 基础学习路线图与概念百科可以先关注我的 CSDN 主页。文章目录DeepSeek Harness 的 bundle / profile / patch 到底是什么cordis.patch.yml 底层实现拆解一、为什么需要层原理拆解篇1.1 从一个直觉误区说起配置不是一棵树是一叠纸1.2 三个概念的官方定义二、基础篇两份 manifest 与一份 patch官方结构全拆2.1 组合包三个文件的完整结构2.2 profile两个文件的组合描述2.3 层序模型四层纸的叠放顺序三、进阶篇覆盖语义——整行替换不是深度合并3.1 官方定义与两个推论3.2 一段可运行的层组合模拟器3.3 表层组合包持有命令行应用自己的 flag四、高阶三种分发方式的选型与避坑4.1 从 GitHub 安装prepare 脚本这道坎4.2 分发方式选型表4.3 版本兼容与 engines 声明五、实战避坑指南高频问题与一键解决速查表结语一、为什么需要层原理拆解篇1.1 从一个直觉误区说起配置不是一棵树是一叠纸传统的应用配置模型是一棵树一个 config.json字段层层嵌套程序读它。DSH 的配置模型是一叠纸每一份 patch 是一张纸纸上写满插件行多张纸按顺序叠起来后放的纸盖住先放的纸。官方文档把这叫层layer把最终生效的配置叫空根之上逐层组合的结果。为什么选一叠纸而不是一棵树因为插件化生态的配置有三个刚性需求树模型都满足不了第一多来源——插件作者想给默认配置、用户想改、机器想做本地偏好、命令行想做临时覆盖四个来源要同时存在第二可覆盖——用户改作者的默认配置时不能要求用户 fork 作者的包第三可追踪——出问题时能回答这行配置到底是谁写的。纸叠模型天然满足每个来源一层纸覆盖关系肉眼可见--dump-config一打印每层的来源都标得清清楚楚。1.2 三个概念的官方定义官方文档《打包与安装插件》给了最精确的定义值得原文照抄“组合包bundle是附带一个配置层的 npm 包。它的 manifest 声明dsh.bundle回答的是’这个包贡献什么一个插入或覆盖插件行的 patch 文件。”“profile 是位于$DSH_HOME/profiles/name下、描述一份可启动组合的目录。它的 manifest 声明dsh.profile回答的是’这套配置由哪些组合包按什么顺序组成。”还有一句一锤定音的区分“组合包是你编写并分发的东西profile 是用户用dsh --profile name启动的东西。没有东西同时是两者。”记住这句话后面所有概念都不会混。二、基础篇两份 manifest 与一份 patch官方结构全拆2.1 组合包三个文件的完整结构官方文档给出的组合包最小结构hello-plugin/ ├── package.json # declares dsh.bundle ├── cordis.patch.yml # the layer applied when a profile lists this bundle └── index.js # plugin modules the patch rows referencepackage.json的关键在dsh键{name:dsh-hello-plugin,version:0.1.0,type:module,main:index.js,files:[index.js,cordis.patch.yml],dsh:{bundle:{patch:./cordis.patch.yml}}}cordis.patch.yml的内容与你开发期用--patch传的 overlay 完全相同——一个 patch 条目的 YAML 数组唯一的区别是插件行按包名引用而不是按相对源码路径这样 Node 的模块解析才能找到已安装的代码-insert:-id:helloname:dsh-hello-plugin官方还给了两个容易忽略的细节patch 可以是有序文件列表[./base.patch.yml, ./web.patch.yml]launcher 按序把它们作为同一层应用没有dsh.bundle声明的包也能安装但只作普通依赖——dsh plugin会打警告、不激活任何层这种格式专供给其他插件包 import 的库使用。2.2 profile两个文件的组合描述profile 目录同样极简package.json— 树外插件依赖由 pnpm 管理dsh.profilemanifest含有序bundles列表cordis.patch.yml—用户自己的 patch 层在每个组合包层之后应用官方强调 profile manifest 从不需要手写dsh plugin add会自动初始化base 作为第一个 bundle并维护列表。装完 hello-plugin 后的 profile manifest 长这样{name:dsh-profile-demo,private:true,dependencies:{dsh-hello-plugin:link:/path/to/hello-plugin},dsh:{profile:{bundles:[deepseek-ai/dsh-base,dsh-hello-plugin]}}}注意bundles是有序列表——顺序就是层序下一节细讲。以及官方对依赖的三个分类值得记住需要与宿主共享实例的包同时声明 peerDependencies 与 devDependenciespeer 用安装中的副本、dev 供类型检查需要独立版本的第三方依赖放 dependencies。2.3 层序模型四层纸的叠放顺序官方文档给出的生效配置组装顺序从底到顶第 1 层:各组合包的 patch按 profile.bundles 列表顺序dsh-base 在前,后装的在后第 2 层:profile 自己的 cordis.patch.yml(用户的组合层配置)第 3 层:$DSH_HOME/cordis.patch.yml(机器本地偏好,各 profile 共享)第 4 层:--patch overlay按 argv 顺序(临时覆盖)生效配置 空根之上逐层组合四层各管一摊组合包层是出厂配置作者给的默认profile 层是这套应用怎么组合用户的项目级选择home 层是这台机器怎么调跨 profile 的本地偏好overlay 层是这次启动怎么试临时实验。层序即权限序越晚的层越权威。三、进阶篇覆盖语义——整行替换不是深度合并3.1 官方定义与两个推论官方文档对覆盖语义有一句必须刻进脑子的定义“后应用的层按行胜出且 patch 会替换目标行的整个config值而不是深度合并各键。”这句话拆成两个推论每个都直接决定你的 patch 怎么写推论一覆盖别人的行必须重述每一个键。你的 bundle 想覆盖dsh-base里某个插件的超时配置不能只写timeoutMs: 60000——那样整行 config 只剩这一个键其他键全丢。必须把目标行需要的全部键重述一遍官方举的例子是dsh-web-app覆盖dsh-base的行就是这么干的。这是整行替换语义最容易踩的坑少写一个键不是用默认值而是丢了这个键。推论二用户永远能覆盖你无需改你的包。用户在自己 profile 的cordis.patch.yml里按 id 覆盖你的行就行。官方由此给 bundle 作者一条设计建议“优先给出用户大概率会保留的配置默认值其余交给 schema 承担。”翻译别在 patch 里写死你必须用我的配置把可选项留给用户层——你的包提供合理默认用户的层拥有最终决定权。3.2 一段可运行的层组合模拟器层序与覆盖语义写成可运行代码教学等价实现Cordis patch 层组合模拟器:四层层序 整行替换覆盖语义(非深度合并)。from__future__importannotationsfromcopyimportdeepcopydefapply_layer(rows:dict[str,dict],layer:list[tuple[str,dict]])-dict[str,dict]:应用一层 patch:按 id 定位行,整行替换 config(不深度合并)。resultdeepcopy(rows)forrow_id,configinlayer:ifrow_idinresult:print(f [覆盖] id{row_id}整行替换 config{config})else:print(f [新增] id{row_id}config{config})result[row_id]deepcopy(config)returnresultif__name____main__:# 第 1 层:组合包层(作者的出厂配置)rows:dict[str,dict]{}rowsapply_layer(rows,[(bash,{timeoutMs:5000,sandbox:True,shell:bash}),(model,{provider:deepseek,temperature:0.7}),])print( 第 1 层结果:,rows)# 第 2 层:profile 层,用户只改超时 —— 注意整行替换的坑print(第 2 层(用户只写 timeoutMs):)rowsapply_layer(rows,[(bash,{timeoutMs:60000})])print( 结果:,rows[bash],← sandbox 和 shell 丢了!)# 正确姿势:重述全部键print(修正(重述全部键):)rowsapply_layer(rows,[(bash,{timeoutMs:60000,sandbox:True,shell:bash})])print( 结果:,rows[bash])# 第 3 层:home 层机器偏好,第 4 层:--patch 临时覆盖print(第 34 层(按序胜出):)rowsapply_layer(rows,[(model,{provider:deepseek,temperature:0.0})])rowsapply_layer(rows,[(model,{provider:ollama,temperature:0.0})])print( 最终:,rows[model],← 第 4 层胜出)跑一遍你会亲眼看到整行替换的坑用户层只写timeoutMssandbox和shell两个键直接消失——这就是生产环境里改了个超时沙箱没了这类事故的完整机制。以及最后两行层序即权限序最晚的--patch临时覆盖胜出。3.3 表层组合包持有命令行应用自己的 flag官方还给了 bundle 的一个高级能力——表层组合包可以定义自己的命令行。挂载一个注入cmdlineArgs的启动插件用parseCmdline解析自己的 flag再通过!!js在配置里引用-id:my-appname:example/my-appinject:[myAppStartup]config:port:!!jsctx.myAppStartup.port??8080两个要点!!js让配置值在加载时求值官方第 05 章配置教程讲过仅 config 与 disabled 字段有效这里用它读命令行结果、部署取值做回退遇到--help时提供方不发布服务这些行不激活——–help 不启动应用这种细节都由同一套声明机制自然实现不需要特判代码。四、高阶三种分发方式的选型与避坑4.1 从 GitHub 安装prepare 脚本这道坎官方文档专门花了一节讲这个坑因为它几乎人人会踩“git 安装拉取的是源码不是构建产物没有任何环节运行你的build脚本因此 TypeScript 包到手时没有lib/输出加载会失败。”解法是双方各做一件事作者提供prepare脚本——pnpm 在 git 安装后运行它从源码构建发布入口脚本必须自包含不能假设旁边有 monorepo checkout。用户为构建授权——pnpm ≥10 默认拒绝运行 git 依赖的 prepare 脚本第一次add会失败要按 dsh 提示把包键加进 profile 的pnpm-workspace.yamlallowBuilds:dsh-hello-plugin:true官方随之给了一句安全警告值得原文记住“请把这项授权视为允许该包的代码在安装时于你的机器上执行且不在 agent 运行的任何沙箱之内。只对源码可信的包授权并锁定 commitgithub:you/hello-plugin#sha让后续推送无法悄悄改变实际运行的内容。”——供应链安全不是口号是安装命令里的日常。4.2 分发方式选型表分发方式用户操作构建授权适用场景npm 发布dsh plugin add your-package不需要正式发布第 13 篇全链路tarball 交付dsh plugin add ./pkg.tgz不需要内部分发、离线环境GitHub 直装dsh plugin add github:you/pkg#sha需要 allowBuilds尝鲜、私有仓库分发官方的一句话建议“如果不想让用户做这项授权就改为分发构建产物。”npm 发布或 tarball 都是预构建交付用户零授权。生产分发首选 npm/tarballgit 直装留给开发期和私有场景。4.3 版本兼容与 engines 声明官方还给了版本兼容的标准姿势用engines.dshSemVer 范围声明组合包支持的 DSH 版本如engines: { dsh: 0.2.0 0.3.0 }安装和 profile 启动都会拒绝不满足范围的包没有engines.dsh时框架检查其deepseek-ai/dsh*peer 依赖范围。这一条看似琐碎实则决定你的插件生态口碑DSH 迭代快声明兼容范围 用户升级 DSH 时你的插件不会静默坏掉而是在安装/启动期被明确拒绝、有据可查。五、实战避坑指南高频问题与一键解决速查表序号遇到的报错或现象背后的真正原因一句话解决办法1装了插件不生效包没声明 dsh.bundle只作普通依赖安装package.json 加dsh.bundle.patch声明2覆盖别人配置后其余键消失patch 是整行替换不是深度合并重述目标行全部键不能只写改动项3改超时后沙箱功能失效同上——config 只剩 timeoutMs 一个键同上;发布前用 --dump-config 核对4git 安装 TypeScript 包后加载失败git 拉的是源码,没有 build 产物作者加 prepare 脚本;用户配 allowBuilds 并锁 commit5用户改的配置被你的包改回去你的 bundle 层序在用户层之后(层序反了)记住四层层序:出厂配置给默认,用户层天然覆盖你6升级 DSH 后插件静默行为异常没声明 engines.dsh 兼容范围package.json 加 engines.dsh SemVer 范围7–dump-config 看不懂层来源不了解层的概念与打印格式对照 2.3 四层层序图逐段核对这张表的核心心法和前几篇一脉相承DSH 的一切行为都有明确语义坑全在凭直觉里。层序、整行替换、构建授权——每一条都写在官方文档里只是大多数人没读到这一页。结语本文把 DSH 的装配机制拆成了三个词的完整闭环bundle 是我贡献什么npm 包 dsh.bundle.patch 声明 patch 文件profile 是这套应用由什么组成目录 dsh.profile.bundles 有序列表 用户层patch 是两者间的粘合层YAML 行数组按层序逐层组合。四层层序组合包 → profile → home → overlay决定谁的配置说了算整行替换语义决定覆盖时怎么写不会丢键。再加上三种分发方式的选型与供应链安全纪律你就拥有了从写插件到发插件的完整装配知识。一张图总结全文知识要点文字回顾① bundle 回答贡献什么、profile 回答由什么组成、没有东西同时是两者② 层序即权限序组合包层 profile 层 home 层 overlay 层后层按行胜出③ patch 覆盖是整行替换不是深度合并——重述全部键④ 用户层永远能覆盖你的默认所以默认值要选大概率被保留的⑤ git 直装拉源码不构建作者 prepare 用户 allowBuilds 锁 commit⑥ 生产分发走 npm/tarball用户零授权。下一篇连载预告《DeepSeek Harness 学习路线图:0 基础到发布第一个插件,附 20 个核心概念速查表》——原理篇收官后的学习地图,关注 CSDN 主页 不错过更新。你装 DSH 插件时踩过装了不生效的坑吗最后发现是什么原因?评论区聊聊,我挨个回。本文事实基于 DeepSeek Harness 官方文档《打包与安装插件》(2026-09 版本),有出入评论区提醒我。参考资料正文数据来源DeepSeek Harness 官方文档《打包与安装插件》、CLI 行为参考、Cordis 教程《配置》一章。
延伸阅读

更多相关文章

2026/10/28 6:33:03

Linux I/O模型演进与性能优化实践

1. Linux I/O 演进的技术脉络在服务端开发领域,I/O性能优化始终是系统设计的核心命题。从早期的管道通信到如今的零拷贝技术,Linux I/O模型经历了数次重大革新。这种演进并非偶然,而是随着网络应用规模扩大和硬件性能提升的必然结果。我曾在多…

2026/10/28 6:33:03

静态博客十分钟上线:Markdown到自动化部署的零成本实践

1. 先算清楚这笔账:静态博客到底省下了什么我这些年帮不少人搭过个人博客,发现一个挺有意思的现象:真正卡住他们的不是技术门槛,而是选择了涉及范围最广的一条路——买服务器、装数据库、配置运行环境、定期打补丁、担心被人扫描。…

2026/10/28 6:33:03

Linux故障排查实战:运维作战地图与工具指南

1. 为什么需要一份Linux故障排查"作战地图"?凌晨3点15分,刺耳的告警铃声把你从睡梦中惊醒。手机屏幕上密密麻麻的报警信息让你瞬间清醒——服务器CPU负载爆表、磁盘空间告急、关键服务无响应。作为运维人员,这种"深夜惊魂&quo…

2026/10/28 6:33:03

AI智能报销系统:微服务架构与费用数据分析实践

1. 项目背景与核心价值在企业管理中,费用报销一直是个让人头疼的环节。传统报销流程通常需要员工手动填写单据、粘贴发票、层层审批,不仅效率低下,还容易出现错漏。根据我过去服务过30多家企业的经验,平均每个员工每月要花4-6小时…

2026/10/28 6:33:03

二维交叉分析:制度规则与经济资源的跨维度认知框架

1. 先搞清楚:为什么单维度看问题十有八九会看走眼“政治与经济一体二维:跨维度认知构建框架”这个题目,第一次听的人多半会皱眉——听起来像学术黑话,其实拆开讲特别朴素:它是一套把“规则约束”和“资源流动”放在同一…

2026/10/28 6:28:03

React Native与鸿蒙组件集成开发指南

1. React Native与鸿蒙组件开发概述 在移动应用开发领域,React Native作为跨平台框架已经广为人知,而鸿蒙OS(HarmonyOS)作为新兴的分布式操作系统,其独特的架构理念和组件化设计为开发者带来了全新的可能性。将两者结…

2026/10/27 14:24:03

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/27 9:34:54

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/28 0:02:13

Python股票自动交易系统源码解析:从行情获取到风控的完整链路

简介:这份资源是面向高校计算机、金融相关专业毕业设计场景的完整项目源码包,主题为基于Python的股票自动交易系统,适合需要完成毕设选题、课程设计或自学金融量化交易开发的学生与开发者参考。压缩包共收录687个文件,整体约14.93…

2026/10/28 0:02:13

视酷酷信IM源码部署指南:Java 17+MySQL 8.0.33实战配置

简介:这是一套2024年亲测可部署的视酷酷信IM即时通讯系统源码,面向具备Java、OC、C#及Vue开发能力的技术人员,解决私有化即时通讯平台快速搭建与二次定制需求,尤其适用于需集成商城、保障数据主权的中小型企业或独立开发者。资源共…

2026/10/28 0:02:13

Python爬取百度迁徙数据:接口解析、批量采集与避坑指南

简介:这份资源是一个用Python爬取百度迁徙数据的脚本压缩包,面向具备Python基础、希望入门网络爬虫与数据解析的开发者,解决按日期获取全国热门城市人口迁徙数据的问题。包内共1个文件,为单个py脚本,压缩包约1KB&#…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑