<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[wshzd的博客]]></title><description><![CDATA[专注于机器学习和深度学习]]></description><link>https://blog.youkuaiyun.com/wshzd</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; wshzd]]></copyright><item><title><![CDATA[LLM之Agent（123）｜DeepSeek-Harness（三十）AGENTS.md 治理规范与文档体系]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/169362353</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/169362353</guid><author>wshzd</author><pubDate>Wed, 28 Oct 2026 16:34:59 +0800</pubDate><description><![CDATA[规则清单里列出的七类边界,本质上都是"值从一个 TypeScript 编译单元之外的世界进来"的地方,这也是为什么它会专门把"model/tool JSON"单列出来——模型返回的工具调用参数,尽管在类型层面被声明成了某个 schema,但产生这份 JSON 的一方(模型)并不在这次编译的类型检查范围内,必须在这个具体的跨界点上做真正的运行时校验。≤ 1,950 words)进一步说明了这份文件的性质:它不是可以无限增长的知识库,而是一份被严格限定篇幅的"必须留在每次会话上下文里的规则集合"。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（122）｜DeepSeek-Harness（二十九）测试哲学：Verify the World, not the Self-Report]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/169269051</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/169269051</guid><author>wshzd</author><pubDate>Tue, 27 Oct 2026 22:47:02 +0800</pubDate><description><![CDATA[换句话说,"模型可见"这件事本身自带一条举证责任:任何声称改变了模型可见内容的改动,都要留下一份可以被后续任何人重新比对的具体证据,而不是停留在开发者自己的描述里——这和前一节讲的"验证外部世界,而非自我报告"其实是同一种不信任自我陈述的态度,只是这一次不信任的对象从"agent 的自我报告"换成了"PR 作者的自我陈述"。这样写出来的测试确实能验证插件内部逻辑,却完全无法验证"这个插件按产品真实的方式被加载时会不会出问题"——而恰恰是"按真实方式加载"这一步,才是 bug 藏身的地方。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（121）｜DeepSeek-Harness（二十八）Skill 技能系统与动态插件扩展]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/169252140</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/169252140</guid><author>wshzd</author><pubDate>Tue, 27 Oct 2026 11:39:53 +0800</pubDate><description><![CDATA[另外,审批现在被明确设计为。新的一套用户创作路径(Agent 自己写插件的"Creator"自我扩展)改由 Plugin Manager 承担,README 原话:"New Creator plugins use Plugin Manager ... this package exposes no model mutation tools." 需要强调的是:这层 UI 只是"审批和观察动态插件"的外壳,并不是给动态插件本身提供渲染能力的框架——插件内部要不要有界面、界面长什么样,是插件自己。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（120）｜DeepSeek-Harness（二十七）Workflow 引擎与 Ralph 循环]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/169165994</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/169165994</guid><author>wshzd</author><pubDate>Mon, 26 Oct 2026 17:32:00 +0800</pubDate><description><![CDATA[" 通道的角色分工和课程写作时的协议(区分"guest → host 的请求"与"host → guest 的回复/结算通知")在思路上是一致的,只是载体从"同进程 worker 的 MessagePort"变成了"跨进程的受管道",且明确写着"模型代码可以写入该通道,因此其中字节仍不可信"——host 侧不能假设从这条通道读到的字节是安全的,必须像对待任何外部输入一样校验。这是"每轮从干净状态开始"这条设计承诺,从提示词层面的口头约定,进一步落到了代码层面的硬校验。,没有任何预先灌入的对话历史。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（119）｜DeepSeek-Harness（二十六）Subagent 委派与协作模型]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/169132541</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/169132541</guid><author>wshzd</author><pubDate>Mon, 26 Oct 2026 08:37:25 +0800</pubDate><description><![CDATA[这与包装外部 CLI 的三个 Provider 有本质区别:那三个是"驾驶一辆别人造的车",这个是"造一辆完全独立、可能配置迥异的新车,让它自己跑"——子 harness 有自己决定的组合、自己的会话持久化、自己的模型路由,完全是一个对等的独立个体,只是它的启停被父进程当作子代理来管理。设置(用户在设置面板里选的"子代理该用哪个模型"这类偏好),并把这个决定原样传给它派生出来的所有子代理会话——也就是说这个设置只在顶层会话创建时采样一次,子代理不会各自重新读取、也不会因为用户中途改了设置而"变卦"。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（118）｜DeepSeek-Harness（二十五）对外协议 SDK、ACP 与生态兼容 Hooks]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/169062739</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/169062739</guid><author>wshzd</author><pubDate>Sun, 25 Oct 2026 14:08:45 +0800</pubDate><description><![CDATA["运行在任何 harness context 之外"——这句话点出了这类 SDK 客户端的本质:它们不是 dsh 内部的一个插件,而是完全独立于 dsh 进程空间之外的调用方,理所当然不能依赖只有 Cordis 插件才能访问的内部服务。这种"每个桥接自己贴合外部协议的具体字节格式,但都翻译到同一套内部拦截点"的分层,正是这个生态兼容层的核心价值——它把"跟外部生态的字节级兼容"和"跟 dsh 内部的语义对接"清晰地分成了两层,后者两个桥接包完全共用。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（117）｜DeepSeek-Harness（二十四）Host/Client 分离与 Typert RPC 生成]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/168952680</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/168952680</guid><author>wshzd</author><pubDate>Sat, 24 Oct 2026 09:09:23 +0800</pubDate><description><![CDATA[第 04 章讲的"assistant/chunk 事件如何在会话日志里被追加",和本篇讲的"这条事件如何被推到浏览器里逐字打字",正好是同一条数据在两个不同抽象层次上的描述——前者关心事件本身的语义和持久化,后者关心这条事件如何跨越进程边界、跨越协议边界,最终变成浏览器里的一次 DOM 更新。说的"separate data protocol"指的是这条流内部的 frame 词汇表(snapshot/records/assistant-stream),不是 Typert 之外的"另一套协议"。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（116）｜DeepSeek-Harness（二十三）Python SDK 与 NDJSON-RPC 桥接]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/168774334</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/168774334</guid><author>wshzd</author><pubDate>Thu, 22 Oct 2026 22:11:15 +0800</pubDate><description><![CDATA[这些都是"完整 dsh CLI 现在自带的能力"(文件全文搜索用 ripgrep,文档处理用 Office 转换引擎)在单文件打包这个环节必须一起背上的行李——这也是为什么这一节的标题从"打包成 exe"变成了"打包成 exe,顺带背了哪些行李":当年打包一个迷你 JSON-RPC demo 应用不需要考虑这些,但打包完整 CLI 就必须考虑。就够了,不需要维护和同步任何"树快照"给客户端。这部分逻辑经历了一次和"两个包的分工"呼应的重写——不再有任何"自动注入一份默认配置、让零参数也能跑起来"的魔法,]]></description><category></category></item><item><title><![CDATA[LLM之Agent（115）｜DeepSeek-Harness（二十二）Native 沙箱内核 landlock-run]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/168655971</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/168655971</guid><author>wshzd</author><pubDate>Wed, 21 Oct 2026 15:44:48 +0800</pubDate><description><![CDATA[Landlock 是 Linux 5.13 引入的一个专门为"非特权自我限制"设计的 LSM(Linux Security Module)：任何进程都可以在不需要额外权限的情况下,给自己施加一个文件系统访问的白名单规则集,规则一旦施加就无法撤销,并且会随。三态而不是简单的能用/不能用)。在跨语言边界这个主题下,它也是一个很好的反面教材式案例——一个包名可能会误导你以为它是"绑定进宿主语言运行时的原生模块",但真正的边界划分方式,可以简单到只是"启动一个独立可执行文件,靠退出码和 stderr 前缀通信"。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（114）｜DeepSeek-Harness（二十一）内置工具全解析]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/168137810</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/168137810</guid><author>wshzd</author><pubDate>Fri, 16 Oct 2026 15:33:28 +0800</pubDate><description><![CDATA[拼成的不透明字符串,任何一项变化都会让它变化)会作为"比较并交换"(CAS)的基准传给底层 Provider——底层实现要保证"只有当前磁盘上的版本和这个基准完全一致时才真正执行替换",否则说明文件在"这个会话读它"和"这个会话写它"之间被别的进程改动过,写入必须失败而不是覆盖别人的修改。,模型读到的是"被人停止的原因"而不是一个莫名其妙的失败。分支——没读过就只能"创建一个原本不存在的文件",读过就必须"替换成读到的那个版本",两条路径都杜绝了"凭空覆盖一个我没看过的文件"的可能性。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（113）｜DeepSeek-Harness（二十）权限审批与沙箱体系]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/168027865</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/168027865</guid><author>wshzd</author><pubDate>Thu, 15 Oct 2026 18:22:12 +0800</pubDate><description><![CDATA["给不给这条命令写文件的权限"和"要不要为这次操作弹窗问用户"其实是两个完全独立的问题:一个命令可能被沙箱允许执行,但部署方仍然希望每一次都有人确认;是给 schema 用的,是"这个部署可能升到的全部目标"的静态并集),因为 schema 是注册表级别全局共享的,而"从哪个模式升级"是每次调用的运行期事实——两者必须分开校验。三个旋钮的当前取值,不只是内部策略检查用的状态,还会被翻译成一段自然语言,拼进每次请求的系统提示词里,让模型对自己的处境有明确认知,而不是只能通过"试了才知道被拒绝"来摸清边界。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（112）｜DeepSeek-Harness（十九）工具注册与执行管线]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/168012414</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/168012414</guid><author>wshzd</author><pubDate>Thu, 15 Oct 2026 11:59:23 +0800</pubDate><description><![CDATA[两者是完全独立的两层调度容量,一个部署完全可以把外层调到 4、内层调到 20(或者反过来),取决于"模型直接发起的调用"和"程序内部串联的调用"各自的并发特性。只会在"下一个待提交的槽位已经就位"时才前进一格。之后,是对一个已经产生的结果的事后否决,通常伴随着"把结果换成一段纠正性的反馈文本"(比如"你写的这段内容触犯了某条策略,请修改后重试"),模型看到的是一个。),模型看到的就不再是每个工具各自的 schema,而是一份生成的 SDK 说明("像写代码一样调用这些函数")加一个唯一可直接调用的工具——]]></description><category></category></item><item><title><![CDATA[LLM之Agent（111）｜DeepSeek-Harness（十八）Seam 三元结构精讲：以 shell 为例]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/167902432</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/167902432</guid><author>wshzd</author><pubDate>Wed, 14 Oct 2026 11:50:47 +0800</pubDate><description><![CDATA["纯前台"变体则不写）。描述的是"这个部署(或者这个 scope)默认怎么执行 shell 命令"这一个全局事实,不是"每个工具各自选择执行器"的路由表。家族,这一整套包后来已从仓库中移除(远程执行仍是官方声明的预留能力,SSH 助手族是当前落地的远程形态)——这也从侧面演示了"三元结构允许 Provider 生灭而 Consumer 不动"的真实历史。这也解释了为什么部署方能够在"纯本地跑""本地但沙箱隔离""文件操作发生在远端主机上"这三种形态之间自由切换——每一种形态换的都只是 Provider,]]></description><category></category></item><item><title><![CDATA[LLM之Agent（110）｜从 Vibe Coding 到 SDD：用 OpenSpec、Spec-Kit 和 BMAD 驯服 AI 编程]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/167792877</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/167792877</guid><author>wshzd</author><pubDate>Tue, 13 Oct 2026 11:23:58 +0800</pubDate><description><![CDATA[SDD 是 Vibe Coding 的进化——在最终的实现阶段，AI 仍然用“氛围编程”的方式写代码，只不过不再根据模糊指令去猜，而是拿着一份清晰的规范去执行。但它的学习曲线也最陡峭。OpenSpec 支持集成到 22 种以上的 AI 编程工具中，包括 Claude Code、Cursor、Windsurf、OpenCode 等，这意味着你不需要绑定某一个特定的 IDE 或助手。当你提交功能 PR 时，可以同时附带规范文件和代码变更，审查者既能看到你“要建什么”（规范），也能看到你“怎么建的”（代码）。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（109）｜DeepSeek-Harness（十七）错误处理、重试与取消机制]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/167696986</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/167696986</guid><author>wshzd</author><pubDate>Mon, 12 Oct 2026 15:43:25 +0800</pubDate><description><![CDATA[而不是一个静态标记：同一个工具,对不同的调用参数可能给出不同的并发分类（比如"读文件"永远安全,但"写文件"要看写的是不是同一个路径）。工具调用的并发上限是一个和 provider 限流完全独立的参数——它限制的是"同一个 agent 步骤里,最多同时有几个工具调用在跑",而不是"多久能发一次模型请求"。空闲太久触发本地看门狗超时;工具执行侧同样如此——第一篇的。（正在执行中的调用）数量还没到上限,就持续从待启动队列里拉新的调用进来启动——但每次要启动下一个之前,会重新检查一遍这个调用当下的并发分类（]]></description><category></category></item><item><title><![CDATA[LLM之Agent（108）｜DeepSeek-Harness（十六）上下文压缩 Compaction 与 Checkpoint 持久化]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/167377837</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/167377837</guid><author>wshzd</author><pubDate>Fri, 09 Oct 2026 11:51:16 +0800</pubDate><description><![CDATA[这套设计让"绝大多数普通事件追加"走一条便宜的、批量摊销的路径,只有真正需要 durability 保证的那几个关键时刻才付出"立刻写入"的代价——,否则派生出的历史会出现一次没有结果的裸调用,模型看到会困惑,更严重的是会破坏 provider 侧对"assistant 消息紧跟工具结果"这类格式的强约束。如果生成的摘要本身比被压缩的原文还长（模型偶尔会这样),整个压缩事务直接判定失败——压缩存在的意义就是"变小",一个不变小的压缩没有任何价值,不应该被接受。,而不是"先执行,再想办法补记一条日志"。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（107）｜DeepSeek-Harness（十五）流式输出管道：从 StreamChunk 到 UI]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/166896639</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/166896639</guid><author>wshzd</author><pubDate>Wed, 30 Sep 2026 14:12:36 +0800</pubDate><description><![CDATA[同时负责"实时转发给 UI"和"落盘一份可无损重放的紧凑记录"这两件事（但两条路径彼此独立，见下），Host/Client 之间的传输层负责把数据搬到浏览器，Client 只管"把收到的数据再折叠成可渲染的 UI 状态"。分支），之前已经发给 UI 的帧也不会被撤回——UI 展示的是"这一刻模型说了什么"的事实，会话日志记的是"这次请求最终、经得起回放验证的结果"，两者故意不耦合。来兜底 adapter 层面的各种抛异常方式——这也是为下一篇的重试机制铺路：重试判断的输入永远是一条结构化的。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（106）｜如何写出好的 Skill]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/166842860</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/166842860</guid><author>wshzd</author><pubDate>Tue, 29 Sep 2026 15:02:46 +0800</pubDate><description><![CDATA[比如你要做一个"PDF 处理"技能：SKILL.md 里写了处理流程，但旋转 PDF 的代码每次都一样，每次让 AI 重写既浪费时间又可能出错——不如直接放一个写好的 Python 脚本。那正确的写法是什么样的？它是一个"创建 skill 的 skill"，它自己的 SKILL.md 就是一份关于"如何给 AI 写指令"的最佳实践。技能文件夹里，可能有一份"怎么处理 PDF"的操作指令、一个旋转 PDF 的 Python 脚本、一份 API 参考文档——AI 不需要从外部再找任何东西，这个文件夹里全有了。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（105）｜DeepSeek-Harness（十四）会话事件溯源：Session Event Log 与 Surface]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/166838255</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/166838255</guid><author>wshzd</author><pubDate>Tue, 29 Sep 2026 11:09:00 +0800</pubDate><description><![CDATA[这让"没有压缩发生的正常对话"每次调用的开销只有 O(新增节点数)，而不是每次都要把整份历史重新投影一遍——对一个可能有几千条事件的长会话来说，这个差别是数量级的。被截断，模型这一步什么内容都没产出、只携带了一份 usage 统计,这类事件被记录下来（为了 usage 账目完整）,但绝不能在派生历史里插入一条空的 assistant 轮次——那会让下一次请求的消息序列出现语义上没有意义的空发言。本身是一个纯粹的"去重"判断：只有当渲染出来的当前上下文文本和已经记住的上一条快照不同时，才返回一条新的。]]></description><category></category></item><item><title><![CDATA[LLM之Agent（104）｜DeepSeek-Harness（十三）ReactLoopAgent 总览：kick → turn → step]]></title><link>https://blog.youkuaiyun.com/wshzd/article/details/166788248</link><guid>https://blog.youkuaiyun.com/wshzd/article/details/166788248</guid><author>wshzd</author><pubDate>Mon, 28 Sep 2026 15:08:00 +0800</pubDate><description><![CDATA[是"一次模型调用 + 它触发的工具执行"，是 ReAct 循环的最小单元。不是运行中的循环会产生的：它是 fork 种子构造时给"源会话在 fork 边界处还没收尾的 turn"事后补记的标记，只出现在 fork 出来的子会话日志里。四类事件在会话日志里天然形成了一个可以精确回放、精确定位"崩溃发生在哪个 turn 的哪个 step"的树状结构——这也是下一篇要讲的"会话事件溯源"的直接基础。依然是"一次模型调用 + 它触发的工具执行"的最小单元，工具调用不产生新 turn的判断逻辑（下面这段）完全没变。]]></description><category></category></item></channel></rss>