DeepSeek Harness glob 工具超限结果采样机制:sampleOverCapGlobResults 的设计、实现与测试全解
DeepSeek Harness glob 工具超限结果采样机制sampleOverCapGlobResults 的设计、实现与测试全解【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness本文基于仓库中的实现笔记 2026-07-27-glob-sampling.md 展开。该笔记记录了一次被判定为已实现implemented的 bug 修复当glob工具的搜索结果超过内联上限时默认的“取修改时间头部”策略会把全部内联路径集中到某一个子树导致 Agent 把单个子目录误当作整个工作区。DeepSeek Harness 通过新增必填配置sampleOverCapGlobResults和一套“跨顶层条目轮询采样”算法解决了这个问题。读完本文你将理解该 bug 的成因、采样算法的源码实现、配置与部署取舍以及完整的测试与快照验证方式。问题Agent 把一个子目录当成了整个项目笔记中记录的真实故障场景非常典型用户询问工作区里有什么内容Agent 却把其中一个子文件夹描述成了整个项目。当时的统计数据是——工作区包含22 个顶层条目、共 11,485 个文件glob {pattern:*}匹配到了10,030 条路径但内联返回的全部 100 条路径都落在同一个“刚解压不久”的子树下。于是模型看到的所有证据都来自那一个目录其余 21 个顶层条目对它完全不可见。问题的关键点在于这不是某个单独环节出错而是三个“各自都合理”的行为叠加成了错误印象。笔记对此做了精确拆解不含/的 glob 模式匹配任意深度的 basename。glob工具底层走的是 ripgrep 语义*并不像 shell 那样只展开当前目录下的直接子项而是匹配整棵树里的每一个文件ripgrep 的--sortmodified是升序排列最旧在前。归档恢复的旧时间戳恰好让那个新解压的子树排在了最前面内联页面直接取这个顺序的头部而且没有说明它只代表了高度集中的一小片结果。三者叠加模型拿到的是一个“看起来像全貌、实际只是局部”的页面。这正是这次 bug 修复要解决的“结果代表性representativeness”问题。决策必填配置sampleOverCapGlobResults两种超限页面契约修复的核心决策是引入一个没有默认值、每个部署必须显式选择的配置项sampleOverCapGlobResults它只影响“超过内联上限”的glob结果页面对未超限的结果完全无影响配置值超限结果的内联页面行为页脚说明false保留按修改时间排序的头部head即修复前的旧行为普通的分页说明true在完整结果的顶层条目之间做轮询采样round-robin明确声明这是跨条目采样而非修改时间头部报告覆盖了多少个顶层条目覆盖不全时提示模型收窄path采样算法保证的语义在笔记中写得很明确每个顶层条目先获得一个槽位之后才轮到第二次分配——即先广度、后深度已被取尽的组自动退出轮询每个组内部的相对顺序保持稳定仍是修改时间顺序分组基准是相对于实际搜索根search root包括显式传入的path参数。换句话说采样只平衡“搜索根之下的第一段”不递归平衡更深层——这一点属于明确的取舍后文会展开。源码实现sampleAcrossTopLevel 的轮询采样算法采样的核心实现在 packages/fs/tool-fs-search/src/glob.ts。三个辅助函数共同构成了分组逻辑relativeToSearchRoot(path, root)glob.ts 第 124 行起在挑选顶层分组之前先去掉展示用的搜索根前缀保证分组基于真实搜索根而不是 workdir 前缀topLevelSegment(path)glob.ts 第 152 行起取路径的第一个路径段作为“顶层条目”无分隔符的路径本身就是自己的顶层条目。它还先剥离前导分隔符使 workdir 之外的绝对路径按第一个真实名字分组而不是全部塌缩进一个空组sampleAcrossTopLevel(paths, maxItems, root)glob.ts 第 171 行起主算法。sampleAcrossTopLevel的逻辑可以浓缩为两遍扫描第一遍分组。遍历完整结果此时仍处于 ripgrep 的修改时间顺序按topLevelSegment(relativeToSearchRoot(path, root))把每条路径归入对应组同时维护一个active活动组列表含当前游标。第二遍轮询取槽。在active非空且已取数量未达maxItems时每一轮按活动组顺序各取一个槽位取完该组游标后移一位若该组还有剩余路径则继续留在活动列表否则退出。这正是“每个条目先得一个槽位耗尽即退出”的逐轮语义也解释了为什么扁平结果全部路径都是顶层条目会精确复现修改时间头部——此时采样退化为取头部测试 tools.spec.ts 第 683-685 行 专门钉住了这一点。页脚格式化在formatGlobOutputglob.ts 第 214 行起当采样覆盖了全部顶层条目时用普通页脚当条目数多于内联槽位时页脚追加“Narrow path to inspect a specific subtree”的提示。两种模式在 spill 成功时都会把完整排序列表写入 artifact。值得注意的实现细节测试覆盖了顶层组数超过 JavaScript 参数上限12.5 万个组的极端场景tools.spec.ts 第 724-727 行验证算法没有把组数当作展开的参数列表而是用 Map 与游标结构线性推进。配置模型必填项与可选上限配置定义位于 packages/fs/tool-fs-search/src/index.ts 的Config。sampleOverCapGlobResults是唯一必填项z.boolean().required()其余键都有默认值。完整的配置表如下默认值来自 glob.ts 与 search-core.ts 的常量配置键默认值含义sampleOverCapGlobResults无必填true对超限 glob 页面跨顶层条目采样false保留修改时间头部globMaxResults100一次glob调用内联展示的最大路径数对齐 Claude Code GlobTool 默认上限grepMaxMatches250一次grep调用内联保留的最大扁平匹配数grepMaxLineBytes2000每条匹配行预览的字节上限保持 UTF-8 边界rawOutputMaxBytes20000000一次搜索可解析的完整 rg 原始 stdout 字节上限超限报SEARCH_RAW_OUTPUT_OVERFLOWtimeoutMs30000两个工具的合作式调用预算经exec.signal强制graceMs3000子进程缝subprocess seam在timeoutMs之后的终止升级宽限期stderrMaxBytes65536rg stderr 的诊断尾部预算searchMetaMaxBytes65536一次搜索序列化presentationMeta的字节上限加载期校验index.ts 第 113-141 行对每个数量类配置断言“正整数”并约束graceMs ≤ MAX_TIMER_DELAY_MS违规在 Loader 组合阶段直接抛错。这就是笔记所说的“错误配置在加载期失败”的落地方式。部署与组合头部模式是官方 CLI 默认采样模式供需要代表性的部署选择笔记明确记录了产品姿态随附的 CLI 组合显式选择 head 模式想要“有代表性的截断页面”的部署则选择采样模式。仓库中三个官方预设 standard/agent.cordis.yml、cordis/agent.cordis.yml、ptc/agent.cordis.yml 均配置sampleOverCapGlobResults: false。一个最小组合示例来自 tool-fs-search 包 README 的 “Minimal composition”- name: deepseek-ai/dsh-subprocess-local - name: deepseek-ai/dsh-tool-fs-search config: sampleOverCapGlobResults: true - name: deepseek-ai/dsh-spill-localdeepseek-ai/dsh-spill-local是可选的装上它超限结果就能通过 spill store 完整恢复没有它页脚会如实报告“完整结果未能保存”。目录取向directory orientation没有被做成新工具笔记明确否决了新增模型可见的list工具理由详见后文。在暴露了模型可见 bash 工具的部署中目录浏览仍是普通 shell 工作——用ls看单目录用glob做跨树的有名文件路径模式匹配ctx.fs.listDir保持为 skill 发现所用的内部 provider 原语。对模型可见的契约提示词与 schema 随模式切换applyGlobToolglob.ts 第 297 行起把配置选择翻译成两处模型可见的文本系统提示词tool:glob节两种模式各有一套措辞采样模式...a larger one is sampled across top-level entries, so it spans the tree instead of one subtree.头部模式...a larger one keeps the modification-time-ordered head.两段共用同一前缀明确告知模型三条规则用 glob 而不是 shell find 做路径发现不含/的模式在任意深度匹配 basename所以*匹配整棵树而非顶层结果只有文件、没有目录且包含隐藏与被忽略文件。schema 描述两种模式分别声明超限结果的返回方式——a larger result returns the first ${caps.maxResults} paths in modification-time order或a larger result instead returns ${caps.maxResults} paths sampled across top-level entries。参数pattern的描述也写明了“不含/即任意深度匹配 basename”的规则并建议用分隔符锚定深度。这解释了笔记中“改动该配置会同时改变 glob 的 prompt、schema 描述以及超限 Native 渲染”的连锁效应。测试 tools.spec.ts 第 234-288 行 同时钉住了两种模式下的提示词与描述文本。页脚、spill 与完整结果恢复超限结果的内联页脚有两种形态头部模式沿用普通的分页说明如(Showing 3 of 5 paths. The complete result could not be saved; narrow pattern or path to see more.)采样模式如(Showing 3 of 6 paths, sampled across 3 of the 4 top-level entries this pattern matched instead of taken in modification-time order. Narrow path to inspect a specific subtree. ...)——当shown total时追加收窄提示全部覆盖到则省略。spill 逻辑位于trySaveFormattedResultsearch-core.ts 第 378 行起通过ctx.get(spillStore)机会式读取非静态注入以会话 ID 为 owner、以工具执行身份为 source把完整格式化结果写入glob-results.txt。spill 是尽力而为后端缺失、无会话 owner、或saveText失败都只记警告并返回undefined搜索成功永远不会因 spill 不可用而变成错误——内联页面照常返回页脚改为报告无法保存。测试用三组用例无 spill 后端 /saveText失败 / 无会话 owner分别验证了这一不变量tools.spec.ts 第 897-908 行。此外canonical 输出始终保留root字段——正是它让采样模式能在渲染时恢复分组基准而未超限的结果保持原样逐字节不动的修改时间顺序。备选方案为什么否决了这些设计笔记完整记录了七个备选方案及其否决理由这部分对于理解设计边界非常关键只保留修改时间头部——否决。故障形态已实测需要稳定顺序的部署可以显式选择头部模式而不该要求模型去怀疑自己拿到的唯一一批路径给采样选择一个默认值——否决。没有任何产品级证据证明某一种顺序是隐含契约所以每个组合必须显式选择错误配置在加载期失败对所有结果都采样——否决。完整结果不受截断损失修改时间顺序对“新旧”类问题依然有用只有当头部无法描述整体时才需要采样改成最新优先newest-first——否决。只是换一个可能占主导的集中子树还破坏了既有的最旧优先契约超过偏斜阈值才采样——否决。没有部署级阈值的证据支撑模型也无法得知当前生效的是哪种排序契约现有上限才是可解释的切换点在顶层之下递归平衡——推迟。首段平衡已修复观测到的故障更深层的平衡需要“深度 vs 广度”策略的额外支撑新增模型可见的list工具——实现评审后否决。默认编码组合已暴露通用 bash模型理解ls重复工具会永久增加 schema/prompt 令牌外加排序、分页、符号链接、转义、UI 与快照等一整组契约却没有额外的安全或策略收益。不含模型可见 bash 工具的瘦部署也不会因此获得目录取向拒绝*或静默锚定无分隔符模式——否决。正是“任意深度匹配 basename”让*.ts在整棵树上有用把规则写进文档保留可用的 ripgrep 语义。影响与取舍Consequences采样模式引入了一个明确的权衡超限采样页面的内联路径不再能回答“新旧顺序”问题——页脚会如实声明这一点而 spill artifact 保留完整排序视图。由于采样只平衡搜索根下的第一段更深层的热点子树仍可能在单个顶层条目内占主导。工具表面没有增长每个组合都必须设置sampleOverCapGlobResults改动它会影响 glob 的 prompt、schema 描述和超限 Native 渲染。canonical 输出保留root使采样模式能恢复分组基准未超限结果保持原样。头部模式的“集中风险”则被明确记录为部署层面的取舍。测试与验证从单元到真实进程笔记列出的一整套测试覆盖在仓库中均有对应包级单元测试packages/fs/tool-fs-search/tests/tools.spec.ts钉住必填配置缺省即抛错、两种超限模式、各自的 prompt 与 schema 描述、集中与扁平结果、显式根、超过 JS 参数上限的组数、耗尽组、槽位少于组数、workdir 之外的路径、spill 失败不改变搜索结果等集成测试tests/integration.spec.ts针对真实 rg 二进制钉住实际行为ACP 场景fs-glob-sampling显式启用采样模式启动一个极简的真实 Loader/app/local-bash 组合对确定性的 rg 进程 fixture 执行真实搜索插件。对应快照位于 snapshots/session/fs-glob-sampling/cordis.yml 与cordis.snapshot.yml——其断言结果是页面横跨四个顶层条目而不是只返回某个子树的头部。测试还覆盖了采样算法与展示路径的几条不变量采样页面与 Native 搜索卡片用同一套sampleAcrossTopLevel计算globCardPage保证文本与卡片对“哪些路径挺过了上限”认知一致workdir 之下的绝对路径输出会先被相对化再展示toWorkdirRelativesearch-core.ts 第 296 行起而 workdir 之外的绝对路径保持原样并按其第一个真实名字参与分组。小结sampleOverCapGlobResults是 DeepSeek Harness 对“截断结果代表性”问题的一次完整回答它把“超限页面的排序契约”从一个隐式的实现细节升级为每个部署必须显式选择的配置面用一组无递归的轮询采样算法在顶层条目间做平衡同时通过页脚、提示词、schema 与 spill artifact 让模型和用户都能理解自己看到的究竟是全貌、头部还是采样。源码、测试与快照三者共同把这个契约钉死使这一行为可以在任何部署中被审计和复现。【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

IEC 60601标准落地指南:从体系解读到检测认证避坑

IEC 60601标准落地指南:从体系解读到检测认证避坑

做医疗电气设备这些年,我最大的感受是:标准不是拿来背的,是拿来“对话”的。你设计一台监护仪、一张电动病床、一套超声主机,哪怕只是一个带电源适配器的家用指夹血氧仪,要进全球市场,绕不开的核心门槛就是…

2026/9/20 3:15:15 阅读更多 →
Chrome DevTools MCP vs Playwright MCP:浏览器AI自动化选型对比

Chrome DevTools MCP vs Playwright MCP:浏览器AI自动化选型对比

别急着去搜索“对比”,这两个项目我建议你直接都装一遍,花一个下午分别跑几个典型任务,比看十篇评测都有用。但既然你诚心要选型依据,我就把实际体验和底层逻辑掰开揉碎讲清楚。Chrome DevTools MCP和Playwright MCP,本…

2026/9/20 3:15:15 阅读更多 →
nvm安装Node.js报错not yet released:6种原因与排查方法

nvm安装Node.js报错not yet released:6种原因与排查方法

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

2026/9/20 3:15:15 阅读更多 →

最新新闻

Codex CLI 安装全攻略:Node.js 环境配置与 PATH 问题排查

Codex CLI 安装全攻略:Node.js 环境配置与 PATH 问题排查

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

2026/9/20 5:29:33 阅读更多 →
VuePress 目录结构详解:从 `.vuepress` 约定到默认页面路由规则

VuePress 目录结构详解:从 `.vuepress` 约定到默认页面路由规则

前端文档SSR 【免费下载链接】vuepress 📝 Minimalistic Vue-powered static site generator 项目地址: https://gitcode.com/gh_mirrors/vu/vuepress 点击查看 免费下载 VuePress 的核心设计理念是**“约定优于配置”**(Convention over Co…

2026/9/20 5:29:33 阅读更多 →
TabPFN 快速上手指南:3 行代码让表格数据跑起基础模型

TabPFN 快速上手指南:3 行代码让表格数据跑起基础模型

TabPFN 快速上手指南:3 行代码让表格数据跑起基础模型 【免费下载链接】TabPFN ⚡ TabPFN: Foundation Model for Tabular Data ⚡ 项目地址: https://gitcode.com/GitHub_Trending/ta/TabPFN 拿到一张新 CSV 时,最磨人的从来不是建模本身 每周都…

2026/9/20 5:29:33 阅读更多 →
Cap 开源录屏教程:从免费录制到在线分享的完整指南

Cap 开源录屏教程:从免费录制到在线分享的完整指南

Cap 开源录屏教程:从免费录制到在线分享的完整指南 【免费下载链接】Cap Open source Loom alternative. Beautiful, shareable screen recordings. 项目地址: https://gitcode.com/GitHub_Trending/cap1/Cap 客户说“这个按钮有问题”时,他想看的…

2026/9/20 5:29:33 阅读更多 →
多智能体编排从入门到生产:Multi-Agent Orchestrator 路由、存储与避坑完整指南

多智能体编排从入门到生产:Multi-Agent Orchestrator 路由、存储与避坑完整指南

多智能体编排从入门到生产:Multi-Agent Orchestrator 路由、存储与避坑完整指南 【免费下载链接】agent-squad Flexible and powerful framework for managing multiple AI agents and handling complex conversations 项目地址: https://gitcode.com/GitHub_Tren…

2026/9/20 5:29:33 阅读更多 →
移动云自研数据库架构与云原生实践解析

移动云自研数据库架构与云原生实践解析

1. 移动云的自研技术架构解析作为国内云计算领域的国家队选手,移动云在技术自主性上的投入确实令人印象深刻。以他们的云原生数据库为例,这个产品线完整展现了从基础设施到上层架构的全栈自研能力。我仔细研究过他们的技术白皮书,发现其"…

2026/9/20 5:28:32 阅读更多 →

日新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →