DeepSeek Harness 内置 ripgrep 搜索:glob/grep 工具从 bash 封装迁移到打包二进制直连的架构解析

发布时间:2026/9/19 17:24:26

DeepSeek Harness 内置 ripgrep 搜索:glob/grep 工具从 bash 封装迁移到打包二进制直连的架构解析 人工智能AI AgentAgent 框架DeepSeek【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址https://gitcode.com/gh_mirrors/de/deepseek-harness点击查看免费下载本篇文章聚焦 DeepSeek Harness 中glob/grep两个文件发现与内容搜索工具的架构演进它们从依赖宿主环境rg的 bash 执行缝seam迁移为通过ctx.subprocess直接派生随 npm 包分发的内置 ripgrep 二进制vscode/ripgrep。你将理解这次决策的问题背景、纯 argv 直连的调用链、--no-config安全边界、懒解析的加载期失败模式设计、完整的SEARCH_*错误词汇表与配置参数默认值并看到对应的源码、测试与部署组合证据。核心变更记录于仓库内的决策笔记 2026-08-01-packaged-ripgrep-search.md对应实现位于deepseek-ai/dsh-tool-fs-search包tool-fs-search。一、问题v1 的 bash 封装让系统rg成为宿主依赖在本次变更之前glob/grep工具通过 bash 执行缝运行其设计记录在已被归档的 2026-07-09-bash-backed-grep-glob-discovery.md 中。当时的取舍是不做ctx.fsprovider 方法避免把本地产品便利变成通用文件系统后端契约而是让工具走ctx.bash.resolve()→ctx.bash.run()流程用固定的rg命令模板执行搜索。这个 v1 方案换来的是三个明确代价系统rg成为宿主依赖插件加载时通过command -v rg探测在 Windows 和精简容器镜像上rg默认不在PATH中于是两个工具静默消失——部署方只能从加载期探测警告中发现问题而模型侧根本没有机会发起搜索。整个模型可见参数面被迫穿过一层 shell 引号辅助函数因为 shell 位于工具与 ripgrep 之间所有模型控制的值pattern、path、include都必须先做 POSIX 单引号转义再拼进命令字符串。v1 笔记把这种耦合明确记录为权衡并点名如果 shell 字符串域被证明过于敏感直接派生 ripgrep 就是合理的后续方案。职责重复探测逻辑要在测试里写脚本模拟执行器的超时分类与协作式工具超时策略tool-call-timeout-policy重复实现。事实上 v1 笔记的备选方案中就已经写过直接从dsh-fs-local派生 ripgrep……它仍是合理的优化方向如果 bash 封装的搜索被证明对 shell 字符串过于敏感。 本次变更正是兑现了这个被显式延期的备选项直接派生 ripgrep。二、决策打包二进制 子进程缝直连deepseek-ai/dsh-tool-fs-search现在通过ctx.subprocess缝运行随包分发的ripgrep 二进制。该二进制来自 npm 依赖vscode/ripgrep——它通过可选平台包vscode/ripgrep-platform-arch为 darwin/linux/win32 × x64/arm64 交付可执行文件见 package.json 中的vscode/ripgrep: ^1.18.0。2.1 runRipgrep纯 argv 向量直连核心执行函数runRipgrep()位于 search-core.ts其调用形态是ctx.subprocess.spawn({ argv: [await resolveRgPath(), --no-config, ...argv], cwd: workdir, stdio: { stdin: ignore, stdout: { maxBytes: rawOutputMaxBytes }, stderr: { maxBytes: stderrMaxBytes }, }, graceMs, signal: exec.signal, })关键点无 shell 层工具与 ripgrep 之间不再有 shell模型提供的每个值都是 argv 数组中的一个普通元素不存在引号转义边界。singleQuote辅助函数及其 shell 派生测试随这次变更一并删除。collect 模式输出stdout/stderr 按诊断尾部形状收集不产生 spill 文件——工具从不读取原始 spill 路径如果 stdout 是有损读取超出rawOutputMaxBytes预算仍未完整保留搜索以SEARCH_RAW_OUTPUT_OVERFLOW失败而不是解析一份静默截断的流completeStdout实现了这条规则。超时与终止graceMsterminate 升级的宽限期与exec.signal原样转发给子进程缝协作式工具调用超时由deepseek-ai/dsh-tool-call-timeout-policy通过 abort 信号触发子进程缝的 terminate 升级负责硬杀工具最终上报SEARCH_ABORTED。2.2 rgPath 懒解析把缺二进制从加载期错误变成调用期错误rgPath的解析被设计为首次调用时懒解析、进程内记忆化resolveRgPath()同一文件内。动机很明确vscode/ripgrep在模块求值阶段就会解析其平台包如果用静态 import一个缺失或损坏的平台包例如--omitoptional安装、部分安装会直接变成Loader 组合失败——而把加载期失败模式移除正是这次变更要解决的核心目标之一。懒解析让失败降级为第一次搜索调用时报SEARCH_FAILED启动失败而不是插件加载失败。源码注释明确写着Resolving at the call boundary keeps a missing or corrupt binary at the first search call asSEARCH_FAILED, rather than failing the Loader composition.。单文件运行时pkg 打包无法从虚拟文件系统派生原生辅助程序因此resolveRgPath还额外支持可执行文件的-rg侧边车sidecar路径。vscode/ripgrep没有自带类型声明包内用 ripgrep.d.ts 声明了最小的模块面命名导出rgPath: string。2.3 注册无条件化删除探测与条件注册v1 的加载期command -v rg探测、条件注册逻辑以及 rg not found 警告全部删除。现在注册是无条件的因为二进制总是可用它是 npm 依赖。包注入的服务也从[tools, systemPrompt, bash]变为[tools, systemPrompt, subprocess]见 index.ts。spillStore仍然通过ctx.get(spillStore)机会式读取因为格式化结果的 spill 是可选的。2.4 工作目录归属工具执行工作目录为会话头中的 cwdexec.agent.session.header.cwd缺失时回退到process.cwd()。由于不再有执行器配置可默认穿透工作目录回退逻辑由工具自己持有。返回路径相对解析后的工作目录展示toWorkdirRelative且仅在工作目录与文件系统read根为同一工作区的共置部署中可被后续读取——这是 v1 就记录的部署要求本次未做运行时校验。三、执行细节与安全边界3.1 --no-config阻断配置注入的任意命令预处理器派生是不受限制的普通ctx.subprocess调用而非受沙箱配置约束的派生因此每次调用都在 argv 前强制加上--no-config。原因宿主若设置了RIPGREP_CONFIG_PATH或二进制旁存在rg.confripgrep 会读取该配置并可能注入一个--pre预处理器——为每个匹配文件执行任意命令。--no-config保证没有任何配置文件因此也没有预处理器能到达搜索过程。这在 search-core.ts 的runRipgrepJSDoc 中有明确说明。3.2 glob 的 argv 模板buildGlobCommandglob.ts构建固定模板--files --globpattern --sortmodified --no-ignore --hidden --glob!**/vcs --glob!**/vcs/** (对 .git/.svn/.hg/.bzr/.jj/.sl 各一对) [-- path]细节值得展开--files只列文件、不列目录--sortmodified保证修改时间序--no-ignore --hidden覆盖被忽略与隐藏文件。VCS 元数据排除是双 glob 对每个 VCS 目录名同时生成裸形式--glob!**/.git遍历时剪枝该目录和内容形式--glob!**/.git/**当搜索根就是或位于该目录内部时裸形式对根前缀路径永不匹配内容形式仍然排除内部。GLOB_VCS_EXCLUDES [.git, .svn, .hg, .bzr, .jj, .sl]。搜索根放在--之后前导连字符的路径永远不会被解析成 flag。3.3 grep 的 argv 模板与 --json 解析buildGrepCommandgrep.ts构建固定的面向行的rg --json命令--json --regexppattern [--globinclude] [-- path]选择--json是为了让文件路径、行号、行文本的解析不依赖冒号切分规避路径含冒号/带格式路径时的歧义。parseGrepMatches只消费match记录begin/end/context/summary属于传输帧而跳过非法 JSON 或缺字段的 match 记录被判定为SEARCH_FAILED行的 UTF-8 解码失败ripgrep 发送 base64bytes而非text时用占位符(line is not valid UTF-8)代替预览而不是让整个搜索失败。include校验前置且严格validateInclude必须是一个正向 glob拒绝空串、拒绝!前缀的否定模式、拒绝逗号分隔列表花括号内的逗号合法如*.{ts,tsx}。3.4 退出码语义仍归工具所有退出码0成功且有结果退出码1成功的空搜索noMatches置真其他分类进既有SEARCH_*词汇表。由于没有 shell 层退出码 127 或 command not found 文本不可能出现——启动失败在 spawn 时就以 rejection 呈现。classifyRunFailure通过 stderr 尾文本中的/regex parse error|error parsing glob/i区分SEARCH_INVALID_PATTERN其余归SEARCH_FAILED。四、配置参数与默认值包级Configindex.ts中sampleOverCapGlobResults是必需项无默认值部署必须显式选择超限分页的排序契约其余字段均有默认值所有计数/字节/毫秒字段都经assertPositiveInteger校验graceMs还受MAX_TIMER_DELAY_MS上限约束。完整表格如下同时见于包 README.md 与生成的 config-catalog.md配置键默认值含义sampleOverCapGlobResults无必需true超限glob页按顶层条目跨目录抽样false保留修改时间序头部globMaxResults100单次glob调用内联展示的最大路径数对应源码GLOB_MAX_RESULTSgrepMaxMatches250单次grep调用内联保留的最大扁平匹配数GREP_MAX_MATCHESgrepMaxLineBytes2000每条匹配行预览的字节上限切分保留 UTF-8 边界GREP_MAX_LINE_BYTESrawOutputMaxBytes20000000工具将解析的完整原始rgstdout 上限超出报SEARCH_RAW_OUTPUT_OVERFLOWRAW_OUTPUT_MAX_BYTEStimeoutMs30000两个工具定义上的协作式调用预算经exec.signal强制执行SEARCH_TIMEOUT_MSgraceMs3000子进程缝在timeoutMs之外给予的 terminate 升级宽限SEARCH_GRACE_MSstderrMaxBytes65536rgstderr 诊断尾部预算SEARCH_STDERR_MAX_BYTESsearchMetaMaxBytes65536单次搜索序列化presentationMeta的字节上限尾部组/路径超过即丢弃SEARCH_META_MAX_BYTES其中rawOutputMaxBytes与globMaxResults/grepMaxMatches分别对应 Claude Code 搜索工具的 20 MB 原始缓冲与 100/250 的内联上限属于双层预算原始收集 内联页的设计参照而非模式化 schema 先例。grep在 v1 不暴露case_insensitive、head_limit、offset、count、多行、上下文行、输出模式或文件类型过滤——需要上下文的模型用read读匹配文件需要后续结果的模型跟随返回的 spill 定位器提示。五、组合方式与部署5.1 最小组合需要先挂载一个ctx.subprocess后端无需宿主rg也无需文件系统 providerspill 后端可选用于让超限结果完整可恢复- name: deepseek-ai/dsh-subprocess-local - name: deepseek-ai/dsh-tool-fs-search config: sampleOverCapGlobResults: false - name: deepseek-ai/dsh-spill-local5.2 内置工具花名册TUI/Web 的固定成员因为dsh-tool-fs-search派生打包二进制并无条件注册两个工具glob/grep从宿主依赖决定是否出现变成固定成员TUI 与 Web 两个已发布界面共享同一工具花名册共享底座 base/cordis.patch.yml 中即可看到tool-fs-search挂载sampleOverCapGlobResults: false。这一花名册决策记录在 2026-07-31-even-out-shipped-tool-rosters.md两个界面端到端测试把glob/grep断言为无条件固定成员而不是宿主相关的一对工具。5.3 快照场景真实二进制 固定 mtimefs-glob-sampling快照场景现在执行真实的打包二进制针对一个预先准备的、用固定 mtime 钉住--sortmodified顺序的工作区——取代了原来通过注入PATH提供的rg替身替身是 POSIX 专用的因为其展示路径带/分隔符会话日志对比无法归一化。证据见 snapshots/session/fs-glob-sampling/cordis.ymlsampleOverCapGlobResults: true、globMaxResults: 4与 snapshots/session/fs-glob-sampling/snapshot.ymlscenario: fs-glob-sampling、platform: posix、workspace.setup: fixed-search-mtimes。六、失败模式与错误词汇表搜索失败使用包所有的HarnessError子类SearchError带稳定错误码与cause链而非FsErrorCode——因为这些工具是 spawn 支撑的发现操作不是ctx.fsprovider 操作。词汇表search-core.ts错误码含义SEARCH_INVALID_PATTERNripgrep 拒绝了正则或 globSEARCH_FAILED搜索无法运行或输出无法解析启动失败、目标不可达、信号杀死、畸形--jsonSEARCH_RAW_OUTPUT_OVERFLOW原始输出超过rawOutputMaxBytes或在请求的 stdout 预算内仍保持截断SEARCH_ABORTED协作式工具超时或调用方取消错误码通过工具注册表的isError结果的{ name, code }暴露重试/权限/UI 层可以分支处理而无需解析消息文本。加载期失败模式也随本次变更改变子进程缝损坏时失败从插件加载失败探测所致变为首次搜索调用报SEARCH_FAILED二进制缺失则变成带打包路径的启动失败而不是 PATH 问题。七、测试与验证测试覆盖是本次重构可信度的直接证据真实集成套件integration.spec.tsdsh-subprocess-local打包二进制通过ctx.tools.execute()走真实世界——磁盘上真实文件被发现与搜索、敌意模式保持惰性、真实rgstderr 分类进SEARCH_*。它此前在缺少系统rg时自我跳过现在每个平台都能跑。敌意模式惰性测试grep传入$(touch pwned)断言结果是No matches found且 canary 文件不存在——因为模式只是 argv 普通元素世界未被触碰。这被注释明确钉为已发布契约未来任何重新引入 shell 包裹的改动都必须守住。懒解析失败路径rg-path.spec.tsmockvscode/ripgrep在求值时抛错证明缺失/损坏平台包--omitoptional、部分安装表现为逐调用的SEARCH_FAILED且解析记忆化后每次调用都一致失败。真实加载路径守卫load-path.spec.ts命名空间插件如果误加export default apply会被 Loader 的unwrapExports折叠、丢掉inject即 postmortem 0001。该测试用真实Loader.prototype.unwrapExports解包模块并挂载验证name/inject/Config/apply形状与无inject错误启动。夹具的 Windows 可重放性集成套件夹具删掉了一个 Windows 无法表示的文件名保证套件在所有平台可重放。八、备选方案与取舍记录决策笔记记录了三组被拒的备选方案作为后续提案必须超越的基准证据保留 bash 缝与探测、仅把rg文档化为必需宿主依赖——拒绝宿主依赖恰恰是本次要消除的失败Windows 支持是本次工作的目标文档化的需求仍然是需求。让rgPath可注入配置字段或环境变量覆盖——拒绝它新增一个唯一的消费方是测试钩子的公开部署面真实二进制已足够确定直接用夹具 mtime 钉住即可——打包二进制就是部署测试就该测它。切换到纯 JS glob/搜索引擎如picomatch/tinyglobby——拒绝依赖交换审计2026-07-26-dependency-swaps-rejected-by-nih-audit.md基于不存在满足条件的 glob 引擎证据已否决该方向ripgrep 语义--sortmodified、VCS 剪枝、JSON 传输、正则方言就是工具契约。九、迁移后果与连锁影响平台覆盖发现工具在打包二进制覆盖的每个平台darwin/linux/win32 × x64/arm64上无需宿主安装即可工作Node 部署接收vscode/ripgrep平台包Python SDK 单文件运行时则把目标平台原生二进制复制为-rg侧边车。攻击面消失shell 字符串注入面不复存在敌意模式是惰性 argv 元素由现在能在 Windows 上运行的集成套件钉住。溢出路径改变形状旧 bash 路径继承 bash-local 常开的 spill可能遗留一个未被读取的多 MB 临时文件子进程缝现在无 spill 收集溢出是纯错误SEARCH_RAW_OUTPUT_OVERFLOWnarrow pattern, path, or include and retry零内容返回。第三方声明生成器 bug 被暴露并修复vscode/ripgrep新依赖让THIRD_PARTY_NOTICES.md生成器的一个潜在缺陷显形——Node 的fs.globSync返回 OS 原生分隔符Windows 上带/后缀的 dev 区前缀永不匹配导致 dev 专用包被错误分档为 runtime生成器现在在摄入时归一化 manifest 路径声明平台无关。同时vscode/ripgrep的 MIT 行进入 runtime 档pnpm 11 截断的虚拟存储目录名需要元数据查找中的内容扫描回退。夹具调整集成套件夹具去掉 Windows 无法表示的文件名套件在所有平台可重放。十、小结从 bash 封装到打包 ripgrep 直连deepseek-ai/dsh-tool-fs-search的这次架构决策围绕一条主线把系统级前置条件变成包内资产把加载期失败变成调用期失败把shell 字符串域变成纯 argv 向量域。配套的懒解析、--no-config安全前缀、SEARCH_*错误词汇表、双层输出预算原始收集 内联页 格式化 spill 恢复与跨平台集成测试共同构成了一套可在任何受支持平台上零安装运行、行为确定、可测试的文件发现与内容搜索能力。若需继续深入可阅读 filesystem 子系统文档、subprocess 能力文档 与 tool-fsread/write/edit 工具 了解与搜索工具配套的完整文件访问链路。赞分享人工智能AI AgentAgent 框架DeepSeek【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址https://gitcode.com/gh_mirrors/de/deepseek-harness点击查看免费下载相关推荐DeepSeek Harness 中的 ripgrep 文件发现工具glob/grep 的设计演进与源码级实现解析DeepSeek Harness 中的 ripgrep 文件发现工具 glob / grep 的设计演进与源码级实现解析 DeepSeek Harness人工智能AI AgentAgent 框架DeepSeekDeepSeek Harness 模型侧搜索工具架构grep/glob 发现工具的边界划分、双层预算与结果溢出回收DeepSeek Harness 模型侧搜索工具架构grep/glob 发现工具的边界划分、双层预算与结果溢出回收 导读 glob 与 grep 是 Deep人工智能AI AgentAgent 框架DeepSeekTurborepo 二进制入口深度解析从 turbo crate 的薄封装看 Rust 迁移架构Turborepo 二进制入口深度解析从 turbo crate 的薄封装看 Rust 迁移架构 本篇文章以仓库中 crates/turborepo/READ构建工具开发工具CLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/19 18:34:30

电力系统暂态稳定分析:从试题到仿真建模实战指南

简介:本资源是一套面向电气工程专业本科生及考研学生的电力系统稳定与暂态分析核心习题集,聚焦电力系统安全运行的关键能力训练,涵盖静态稳定判据、等面积定则应用、复合序网构建、潮流计算方法比较、短路故障类型辨析、调压方式识别等高频考…

2026/9/19 18:34:30

办公室直饮机选购指南:核心指标与维护要点

1. 为什么办公室饮水设备值得认真挑选上周公司行政部的同事小张跑来问我:"王哥,咱们部门准备换台直饮机,市面上从两千到两万的都有,到底该怎么选啊?"这个问题让我想起三年前我们部门采购饮水设备时踩过的坑—…

2026/9/19 18:34:30

AI Agent技术架构与核心模块解析

1. AI Agent 技术架构解析AI Agent(人工智能代理)本质上是一个具备自主决策能力的智能系统,它通过感知环境、处理信息、制定策略并执行动作来完成特定任务。现代AI Agent通常由以下几个核心模块构成:感知模块:负责接收…

2026/9/19 18:34:30

新课标语文必考题库备考指南:从考点拆解到复习计划

简介:面向中小学语文教师、备考教师资格证笔试及课程标准考核的考生准备的应试练习材料,以2022版义务教育语文新课程标准为依据汇编必考题型。题库围绕课程任务与作用、语文课程性质、工具性与人文性的统一、语文课程基本理念、语文教育特点、阶段目标与…

2026/9/19 18:34:29

如何自定义GDB dashboard布局?dashboard -layout终极配置指南

如何自定义GDB dashboard布局?dashboard -layout终极配置指南 【免费下载链接】gdb-dashboard Modular visual interface for GDB in Python 项目地址: https://gitcode.com/gh_mirrors/gd/gdb-dashboard GDB dashboard 是一款用 Python 编写的模块化 GDB 可…

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/19 0:03:10

验证 OpenSpec 兼容性,Cursor 的 Token 从 TaoToken 出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

书桌角落的 Mac mini,OpenClaw 通过 TaoToken 跑任务。

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

oh-my-hermes:打造跨工具的命令编排与插件化工作流

1. 项目概述与设计初衷1.1 它到底是什么先说结论:oh-my-hermes 是一个面向开发者日常终端操作的效率工具套件,核心定位是“把分散在各类命令行工具里的高频操作,统一收拢成一套插件化、可编排的工作流”。项目灵感来源很明显——oh-my-zsh 重…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

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

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

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