DeepSeek Harness 中 Skills 与 AGENTS.md 的注入机制与工程实践
1. 从标题拆解Harness、Skills 与 AGENTS.md 到底是什么关系第一次看到“DeepSeek Harness 的 Skills 和 AGENTS.md 怎么用、注入到哪”这个标题很多人会愣一下Harness 是什么Skills 又是什么AGENTS.md 和 CLAUDE.md 是不是一回事这三个词放在一起其实指向的是同一件事——怎么让一个通用大模型在你的项目里变成一个“懂规矩、有专长、能干活”的工程助手。我先把这三个概念用大白话对齐一下不然后面全是空中楼阁。Harness直译是“马具、挽具”在 AI 工程语境里它指的是套在模型外面的一层运行框架。模型本身是个“裸脑”能推理、能生成但它不知道你的项目结构、不知道你的代码规范、不知道你希望它先读哪个文件再动手。Harness 就是那套“挽具”把模型的能力约束到你的工作流里。你可以把它理解成一个“AI 员工的操作台”左边是模型右边是你的项目中间这层调度、注入、约束、回收的机制就是 Harness。Skills是挂在 Harness 上的能力模块。一个 Skill 通常是一段结构化的说明加配套资源告诉模型“遇到某类任务时按这个流程、用这些工具、遵守这些约束来做”。比如“前端组件开发 Skill”“论文阅读 Skill”“SQL 审计 Skill”本质上是把资深工程师脑子里的套路固化下来让模型每次都能按同一套高标准执行而不是每次自由发挥。AGENTS.md是放在项目根目录或子目录里的代理行为约定文件。它回答的是“在这个仓库里AI 应该怎么做事”代码风格、目录约定、提交规范、禁止事项、常用命令。CLAUDE.md 是同一类东西在不同工具里的叫法思路完全一致——用一份人类可读的 Markdown把项目上下文喂给模型。所以标题问的“怎么用、注入到哪”翻译成工程语言就是Skills 和 AGENTS.md 这两类上下文通过 Harness 的什么机制、在什么时机、以什么优先级进入模型的上下文窗口。这个问题搞清楚了你才能真正掌控 AI 助手的行为而不是被它牵着走。提示本文讨论的是本地/自托管场景下的通用工程实践涉及的所有配置均为项目内的文本约定不涉及任何网络层或系统层的特殊操作。2. 整体设计思路为什么要有“注入”这一层2.1 裸模型的问题上下文是稀缺资源大模型的上下文窗口看起来很大动辄几十万 token但真正用起来你会发现它极其不经花。一个中等规模的前端项目光是把src目录下的关键文件读一遍就可能吃掉几万 token。如果你还把一堆 Skill 说明、历史对话、工具返回结果全塞进去模型很快就会“注意力涣散”——前面说的规范它记不住后面给的指令它又理解偏。这就是为什么需要“注入”这一层设计。注入不是把所有东西一股脑塞进去而是有策略地、分时机地、按优先级地把上下文送进模型。这跟人类工程师的工作方式是一样的你带一个新同事不会第一天就把公司十年的文档全甩给他而是先给他一份“入职须知”AGENTS.md再在具体任务里给他“操作手册”Skills。2.2 三层上下文的分工我把这套体系拆成三层理解起来会清晰很多层级载体作用注入时机典型体量项目层AGENTS.md / CLAUDE.md定义项目全局约定会话启动时几百到几千 token能力层Skills定义某类任务的执行流程任务匹配时按需加载每个几百到几千 token任务层用户指令 工具返回当前具体要干的事实时动态变化这个分层的关键在于按需加载。项目层的 AGENTS.md 是常驻的因为它体量小、通用性强Skills 是懒加载的只有当任务命中某个 Skill 的描述时才把它的完整内容注入进去任务层则是完全动态的。我实测下来这套分层能把一次会话的“固定开销”压到很低。一个配置得当的项目AGENTS.md 控制在 800 token 以内Skills 平均每个 500 token模型有充足的上下文余量去处理真正的任务内容。2.3 为什么不用一个大文件全搞定有人会问那我直接把所有规范、所有流程写进一个巨大的 AGENTS.md 不就行了短期看可以长期看是灾难。原因有三个第一上下文污染。一个 5000 行的规范文件模型每次都要读一遍其中 90% 的内容跟当前任务无关这些无关内容会稀释模型对关键指令的注意力。工程上有个经验值与当前任务无关的上下文超过 30%模型的指令遵循率会明显下降。第二维护成本。所有东西堆在一个文件里改一处要通读全文团队协作时冲突不断。拆成 Skills 之后每个 Skill 独立维护谁用谁改互不干扰。第三复用性。一个好的 Skill 可以跨项目复用比如“React 组件开发规范”这个 Skill在你所有前端项目里都能挂。但如果你把它写死在某个项目的 AGENTS.md 里换个项目就得复制粘贴改一次要改十处。所以整体设计思路就一句话AGENTS.md 管“这个项目是什么样”Skills 管“这类活该怎么干”Harness 管“什么时候把谁送进去”。3. AGENTS.md 的写法与注入机制3.1 AGENTS.md 应该写什么、不该写什么我见过太多 AGENTS.md 写成“公司员工手册”洋洋洒洒几千字结果模型根本记不住。AGENTS.md 的正确写法是极度克制只写那些“模型不知道、但每次都必须知道”的信息。该写的项目一句话定位这是个什么项目用什么技术栈跑在什么环境。目录结构约定核心代码在哪测试在哪配置文件在哪。代码风格硬约束缩进、命名、导入顺序、禁止使用的语法。常用命令怎么装依赖、怎么跑测试、怎么构建。禁止事项不许改哪些文件不许引入哪些依赖。不该写的详细的业务逻辑说明模型读代码就能懂。长篇的架构设计文档放独立文件需要时再读。具体的任务流程那是 Skills 的活。任何会频繁变化的信息版本号、临时开关。我自己的习惯是AGENTS.md 控制在60 行以内。超过这个长度我就会问自己这段内容是不是应该拆成一个 Skill或者放到一个独立的文档里让模型按需读取3.2 一个可直接抄的 AGENTS.md 模板下面这个模板是我在多个项目里迭代出来的你可以直接拿去改# 项目约定 ## 项目定位 这是一个基于 TypeScript 的前端项目使用 Vite 构建React 18 Zustand 状态管理。 ## 目录结构 - src/components/ 通用组件每个组件一个目录 - src/features/ 业务功能模块按领域划分 - src/lib/ 工具函数纯函数无副作用 - tests/ 测试文件与 src 结构镜像 ## 代码风格 - 使用 2 空格缩进禁止 Tab - 组件文件使用 PascalCase工具文件使用 camelCase - 导入顺序外部依赖 → 内部模块 → 类型导入 - 禁止使用 any必要时用 unknown 加类型守卫 ## 常用命令 - 安装依赖pnpm install - 开发pnpm dev - 测试pnpm test - 构建pnpm build ## 禁止事项 - 不要修改 src/lib/legacy/ 下的任何文件 - 不要引入新的状态管理库 - 不要提交 console.log 到主分支这份模板大概 400 token模型每次会话启动时读一遍成本极低但能挡掉 80% 的“低级错误”。3.3 注入时机与优先级AGENTS.md 的注入时机是会话启动时也就是你打开 Harness、开始一个新会话的那一刻。它会被放在系统提示system prompt之后、用户指令之前属于“高优先级常驻上下文”。这里有个细节很多人不知道AGENTS.md 的优先级高于 Skills。也就是说如果某个 Skill 的流程跟 AGENTS.md 的约定冲突模型应该以 AGENTS.md 为准。这个优先级设计是合理的因为项目约定是“宪法”Skills 是“地方法规”地方法规不能违宪。实操中我会在 AGENTS.md 里显式写一句当 Skill 流程与本文件约定冲突时以本文件为准并在回复中说明冲突点。这句话能有效防止模型被某个 Skill 带偏。3.4 多级 AGENTS.md 的覆盖规则大型项目里你可能有多个 AGENTS.md根目录一个src/features/payment/下一个src/features/user/下一个。Harness 的处理规则通常是就近覆盖模型在处理payment目录下的文件时会同时加载根目录和payment目录的 AGENTS.md后者覆盖前者的同名约定。这个机制非常有用。比如根目录规定“所有组件用函数式”但payment目录因为历史原因还在用类组件你可以在payment/AGENTS.md里写一句“本目录允许类组件”模型就不会强行改造。注意多级 AGENTS.md 的加载顺序和覆盖规则不同 Harness 实现可能有差异。建议在项目里放一个AGENTS.md说明文件写清楚你用的 Harness 的具体行为避免团队成员踩坑。4. Skills 的结构、开发与注入策略4.1 一个 Skill 的最小结构Skill 不是随便写一段提示词就完事它有一套约定俗成的结构。一个标准的 Skill 通常包含三部分元信息frontmatter名称、描述、触发条件。这部分是给 Harness 看的用来判断“当前任务要不要加载这个 Skill”。主体说明body具体的执行流程、步骤、约束。这部分是给模型看的任务命中后才注入。配套资源resources可选的脚本、模板、参考文档。模型在执行过程中按需读取。用 Markdown 表示大概长这样--- name: react-component description: 开发 React 组件时使用覆盖组件结构、样式、测试的完整流程 trigger: 当任务涉及创建或修改 React 组件时 --- # React 组件开发流程 ## 步骤 1. 在 src/components/ 下创建组件目录 2. 编写组件文件使用函数式组件 TypeScript 3. 编写同目录下的 index.test.tsx 4. 运行 pnpm test 验证 ## 约束 - 组件必须接受 className prop 并透传 - 禁止在组件内直接调用 API数据通过 props 传入 - 样式使用 CSS Modules禁止内联样式这个 Skill 大概 300 token只在开发组件时加载平时不占用上下文。4.2 触发条件怎么写才准Skill 的触发条件是整个机制里最容易写砸的部分。写得太宽模型动不动就加载上下文被塞满写得太窄该用的时候不加载模型自由发挥。我的经验是触发条件要同时包含“动作”和“对象”。比如差的写法“处理代码时”太宽差的写法“当用户提到按钮组件时”太窄用户可能说“做个提交按钮”好的写法“当任务涉及创建、修改或调试 React 组件文件时”好的写法里“创建、修改、调试”是动作“React 组件文件”是对象两者结合命中率就高很多。另外我建议在 Skill 描述里显式列出反例不适用于纯样式调整、配置文件修改、依赖升级。这能进一步降低误触发。4.3 Skills 的注入策略懒加载与预加载Skills 的注入有两种策略各有适用场景懒加载lazy loadingHarness 先只把 Skill 的元信息名称 描述放进上下文等任务命中时再把完整内容注入。这是默认策略适合 Skill 数量多、单个 Skill 体量大的场景。预加载eager loading会话启动时就把某些 Skill 的完整内容注入。适合那些“几乎每次都会用到”的核心 Skill比如“代码提交规范”。我自己的配置是核心 Skill 预加载 2 到 3 个其余全部懒加载。预加载的 Skill 总 token 控制在 1500 以内剩下的上下文留给任务本身。这里有个实操技巧给 Skill 描述加权重标记。比如在描述里写[core]前缀Harness 可以据此决定预加载优先级。这个不是所有 Harness 都支持但值得在你的配置里试一下。4.4 开发一个 Skill 的完整流程我拿“SQL 审计 Skill”举例走一遍完整流程。注意这里的 SQL 审计指的是代码层面的 SQL 语句质量检查比如索引使用、注入风险、性能问题属于正常的工程实践。第一步明确边界。这个 Skill 只做“审查已有 SQL”不做“生成新 SQL”不做“执行 SQL”。边界清晰触发条件才好写。第二步写元信息。--- name: sql-audit description: 审查 SQL 语句的质量检查索引使用、参数化、性能隐患 trigger: 当任务涉及审查、优化或排查 SQL 语句时 ---第三步写主体流程。把资深 DBA 的检查清单固化下来# SQL 审计流程 ## 检查项 1. 是否使用参数化查询禁止字符串拼接 2. WHERE 条件字段是否有索引 3. 是否避免了 SELECT * 4. 子查询是否可改为 JOIN 5. 是否有隐式类型转换 ## 输出格式 按严重程度分级阻断 / 警告 / 建议 每条问题给出位置、原因、修改建议第四步加配套资源。放一个examples/目录里面是正例和反例的 SQL 片段模型需要时可以读取参考。第五步实测调优。拿几个真实的 SQL 文件喂给模型看它是否按流程执行、是否漏检、是否误报。根据结果调整检查项和输出格式。这个流程走下来一个 Skill 大概花 1 到 2 小时但之后能反复用性价比极高。5. 注入到哪上下文窗口的排布实战5.1 一次会话的上下文排布把前面所有东西串起来一次典型会话的上下文窗口排布是这样的从上到下优先级从高到低位置内容体量是否常驻1系统提示固定是2根目录 AGENTS.md400是3子目录 AGENTS.md200按文件路径4预加载 Skills1500是5懒加载 Skill命中时500否6用户指令动态否7工具返回结果动态否8历史对话动态否这个排布的核心逻辑是越靠前的内容模型注意力越集中。所以项目约定放最前任务内容放中间历史对话放最后因为历史对话的重要性随时间递减。我实测下来把 AGENTS.md 放在系统提示之后、用户指令之前模型的指令遵循率比放在最后高出不少。这个位置差异在小任务上不明显但在长会话里差距会拉大。5.2 上下文超限时的裁剪策略上下文总有满的时候。当接近窗口上限时Harness 需要裁剪。裁剪的优先级应该是先裁历史对话保留最近 5 轮更早的压缩成摘要。再裁工具返回大块的日志、文件内容只保留关键片段。然后裁懒加载 Skill任务完成后立即释放。最后才动 AGENTS.md 和预加载 Skill这两个是底线尽量不裁。这个顺序不能反。我见过有人为了塞下更多任务内容把 AGENTS.md 裁掉了结果模型开始乱改代码风格得不偿失。5.3 验证注入是否生效的方法配置完了怎么知道生效没生效我常用三个方法方法一直接问模型。在会话里问“你现在的项目约定是什么”看它能不能准确复述 AGENTS.md 的内容。能复述说明注入成功。方法二故意违规测试。让模型做一个 AGENTS.md 里明确禁止的操作看它是否拒绝。比如约定里写了“禁止使用 any”你就让它写一段用 any 的代码看它是否提醒你。方法三看 Harness 日志。大多数 Harness 会打印上下文组装日志能看到每个文件注入了多少 token、在什么位置。这是最准确的方法。提示如果你发现 Skill 没被触发先检查触发条件的措辞再检查 Harness 的日志里 Skill 元信息是否被正确加载。九成的问题出在触发条件写得太窄或太宽。6. 常见问题与排查技巧实录6.1 模型不遵守 AGENTS.md 怎么办这是最高频的问题。排查顺序如下先看位置。AGENTS.md 是不是放在了系统提示之后如果放在了历史对话之后模型很可能忽略它。再看长度。AGENTS.md 是不是太长了超过 1000 token 的 AGENTS.md模型的遵循率会下降。拆分成多个文件或者精简内容。然后看冲突。是不是有某个 Skill 的流程跟 AGENTS.md 冲突检查一下最近加载的 Skill。最后看措辞。AGENTS.md 里的约定是不是太模糊把“尽量使用函数式组件”改成“必须使用函数式组件禁止类组件”遵循率会明显提升。6.2 Skill 误触发或漏触发误触发不该加载时加载了和漏触发该加载时没加载是 Skill 机制的两大痛点。我整理了一个速查表现象可能原因解决方法频繁误触发触发条件太宽加入对象限定词列出反例完全不触发触发条件太窄扩展动作词用同义词时灵时不灵描述有歧义用具体名词替代抽象词加载了但不执行主体流程太长精简步骤突出关键约束我踩过最深的坑是“触发条件用了抽象词”。比如写“当任务涉及优化时”结果模型把“优化代码格式”也当成命中加载了性能优化 Skill完全跑偏。后来改成“当任务涉及查询性能、内存占用、响应时间的优化时”就准多了。6.3 多个 Skill 冲突怎么处理有时候一个任务会同时命中多个 Skill比如“重构一个 React 组件里的数据请求逻辑”可能同时命中“React 组件 Skill”和“数据请求 Skill”。这时候 Harness 需要决定加载顺序和优先级。我的处理原则是在 Skill 元信息里加priority字段数值小的优先。同时在 AGENTS.md 里写一句冲突解决规则当多个 Skill 同时命中时按 priority 升序执行priority 相同时按加载顺序执行执行中如遇冲突以 AGENTS.md 为准。这样模型就有明确的裁决依据不会在两个 Skill 之间反复横跳。6.4 上下文被 Skill 撑爆怎么办Skill 太多、太长上下文很快就不够用了。我的应对策略有三条第一合并同类 Skill。把“React 组件 Skill”“React Hooks Skill”“React 测试 Skill”合并成一个“React 开发 Skill”减少元信息开销。第二拆分大 Skill。一个 Skill 超过 1000 token就考虑拆成“核心流程”和“进阶参考”两部分后者放配套资源里按需读取。第三定期清理。每季度 review 一次 Skill 列表删掉三个月没用过的合并功能重叠的。我自己的 Skill 库常年保持在 15 个以内超过就清理。6.5 团队协作时的约定同步多人协作时AGENTS.md 和 Skills 的版本同步是个大问题。我的做法是AGENTS.md 纳入版本控制跟代码一起 review、一起合并。Skills 单独建一个仓库用 submodule 或包管理工具引入版本号明确。每次改动写 changelog说明改了什么、为什么改、影响哪些项目。新人入职第一件事读 AGENTS.md跑一遍 Skill 触发测试。这套流程跑下来团队里 AI 助手的行为一致性会高很多不会出现“张三的会话很听话、李四的会话乱来”的情况。7. 我个人的配置心得与几个实用技巧先说一个反直觉的结论AGENTS.md 和 Skills 写得越少效果往往越好。我刚上手时恨不得把所有知道的东西都写进去结果模型被淹没在信息里反而抓不住重点。后来做减法AGENTS.md 从 200 行砍到 60 行Skill 从 30 个砍到 12 个模型的表现反而上了一个台阶。第二个心得是用“测试驱动”的方式写 Skill。先写一个 Skill然后拿 5 个真实任务去测看命中率、执行质量、输出格式。不达标就改改完再测。一个 Skill 通常要迭代 3 到 5 轮才能稳定。这个过程很枯燥但比事后救火划算得多。第三个技巧是给 Skill 加“自检清单”。在 Skill 主体末尾加一段## 完成前自检 - [ ] 是否遵守了 AGENTS.md 的所有约定 - [ ] 是否运行了相关测试 - [ ] 输出是否包含必要的说明模型在结束任务前会过一遍这个清单能挡掉不少低级失误。实测下来加了自检清单的 Skill输出质量比不加的高出一截。最后一个技巧是定期做“上下文审计”。每隔一段时间把一次典型会话的完整上下文导出来看看每个部分占了多少 token、哪些是必要的、哪些是浪费的。我做过一次审计发现历史对话占了 40% 的上下文其中大部分是无关的寒暄和试错。后来我调整了会话策略把长任务拆成多个短会话上下文利用率立刻上去了。这套东西没有银弹核心就是理解机制、小步迭代、持续审计。你把它当成一个需要长期维护的工程系统来对待它就会稳定地给你回报。