Finn Days
博客笔记项目标签关于
博客笔记项目标签关于
Finn Days
博客·关于·RSS

用 Agent Skills 标准封装可复用的检索能力

2026.03.12·8 min read
Agent SkillsHarness EngineeringMCPArchitecture

问题:N 个助手复制粘贴同一套检索逻辑

我们有七八个不同领域的 Agent 助手(周报、培训、产品文档、项目交付等),底层都在做同一件事——从知识库检索文档、获取详情、整理回答。但每个助手的 prompt 文件里各写了一遍检索流程:120 行的 Python f-string,内联了索引路由规则、工具使用策略、检索深度要求。

改一个检索策略要改七八个文件,经常漏改。更糟糕的是,新增一个助手时不得不复制粘贴这些内容,然后手动调整——几乎所有 Agent 系统在扩展助手数量时都会遇到这个问题。

Agent Skills 标准

2024 年底 Anthropic 发布了 Agent Skills 开放标准。一个 Skill 就是一个目录,里面用 Markdown + YAML 定义一项可复用的 Agent 能力。Microsoft、OpenAI、Cursor、GitHub 已经采纳了这个标准。它正在成为 Agent 能力的通用封装格式。

Skill 的结构

以我们封装的知识检索 Skill 为例:

    • SKILL.md
      • index-catalog.md
      • retrieval-strategy.md
      • output-format.md

SKILL.md 分两部分——YAML frontmatter 声明元数据,Markdown 正文写指令:

SKILL.md (frontmatter)
---
name: knowledge-retrieval
description: >
  Enterprise knowledge base retrieval and Q&A skill. Searches knowledge bases
  using semantic hybrid retrieval, fetches full page content when truncated,
  and generates well-cited answers. Triggers on: 项目进展, 周报, 产品文档, 培训课程...
allowed-tools: knowledge_search fetch_page_content
metadata:
  author: team-ai
  version: "1.0"
---

description 是 Skill 发现的唯一依据——Agent 启动时只加载每个 Skill 的 name + description(约 100 tokens),用来判断当前 query 该不该激活这个 Skill。只有决定激活后才读 SKILL.md 正文,正文中引用的 references/ 文件则是 Agent 觉得需要时才读。

这就是 渐进式加载(Progressive Disclosure) 的核心设计。

渐进式加载的量化分析

三层加载,按需展开:

Layer 1 — 元数据(~100 tokens/skill)
  Agent 启动时加载 name + description,用于发现匹配
  12 个 Skill × 100 = ~1,200 tokens

Layer 2 — 指令(~800 tokens)
  激活后读取 SKILL.md 正文

Layer 3 — 参考资料(按需)
  Agent 调用 read_file 读取 references/ 中的文件

以我们的 knowledge-retrieval Skill 为例,四块内容的 token 消耗:

内容tokens何时加载
SKILL.md 正文~800Skill 激活时(每次)
index-catalog.md~600Step 2 选索引时(需要时)
retrieval-strategy.md~800搜索不理想时(需要时)
output-format.md~600写回答时(每次)

不同场景下的实际 token 消耗:

简单事实查询("R6900 支持多大内存")
  加载:SKILL.md + output-format = ~1400 tokens
  不需要:index-catalog(默认索引够用)+ retrieval-strategy(一次命中)
  → 比全量 2800 tokens 省了 50%

复杂多角度查询("对比三大运营商 5G 部署")
  加载:全部 4 个文件 = ~2800 tokens
  → 和全量注入一样

按查询类型分布加权:平均 token 消耗降低约 40%

token 节省不是唯一目标

更重要的是减少注意力稀释。研究表明 LLM 推理性能在 context 超过 ~3000 tokens 后开始退化。渐进式加载让 Agent 在简单查询时只看到 1400 tokens 的精简指令,注意力更集中。

从 prompt.py 提取了什么、保留了什么

封装 Skill 时最关键的设计决策是:什么属于"不变的能力"(放进 Skill),什么属于"变化的上下文"(留在各助手 prompt 中)。

跨助手不变的检索能力定义:

  • 5 步检索流程(分析 → 选索引 → 执行检索 → 构建回答 → 个人问题处理)
  • 工具使用规范(knowledge_search 怎么调、fetch_page_content 何时用)
  • 输出格式要求(纯文本、引用规范、禁止行为)
  • 索引路由规则(关键词到索引的映射,YAML 配置化)
  • 检索质量自检清单(事实断言是否有来源、引用是否真实)

references/ 的拆分依据

三个 reference 文件不是按内容分类拆的,而是按 Agent 使用的时机拆的:

index-catalog.md — Step 2 选索引时

详细描述每个知识库索引的覆盖内容和典型查询示例。简单查询(默认索引就够)时 Agent 不需要读这个文件。

retrieval-strategy.md — Step 3 搜索不理想时

深度检索策略:多角度搜索模式、改写技巧、fetch_page_content 分段策略。如果第一次搜索就命中了,Agent 不会读这个文件。

output-format.md — Step 4 写回答时

格式规范、引用规则、禁止行为清单。每次回答都需要参考,所以这个文件加载频率最高。

assets/index-routing.yaml 不在 references/ 中,因为它的消费者是框架代码(解析 YAML → 匹配关键词 → 返回索引列表),不是给 LLM 阅读的自然语言。

assets/index-routing.yaml
default_indexes:
  - weekly_all
 
keyword_routing:
  - name: training
    keywords: ["培训", "课程", "学习", "考试"]
    add_indexes: ["kb_training_latest"]
  - name: product-doc
    keywords: ["产品", "网元", "5G", "核心网"]
    add_indexes: ["kb_ccn_product_doc"]
  - name: ssp
    keywords: ["SSP", "存储", "服务器"]
    add_indexes: ["ssp_internal", "kb_ssp_model_all"]

新增一个知识库只需要在 YAML 里加一条路由规则,不需要改任何代码。

Skills 与 MCP 的双栈关系

Agent Skills 和 MCP(Model Context Protocol)经常被放在一起讨论。它们是互补的两层标准:

MCP  = Agent 如何连接外部工具/数据源     → "怎么插上"
Skill = Agent 连上工具后如何执行任务     → "插上后怎么用"

以我们的系统为例:MCP 层面定义了 knowledge_search 工具怎么连接 Elasticsearch(API 格式、认证、数据结构);Skill 层面定义了拿到这个工具后怎么搜——搜几次、怎么判断结果够不够、怎么组织回答。

同样的 knowledge_search 工具,检索产品文档和检索周报的策略完全不同(前者侧重精确型号匹配,后者侧重多角度交叉搜索)。这个差异由 Skill 定义,不由 MCP 定义。

跨助手复用的效果

封装完成后,接入方式从手动拼参数变为声明式配置:

before_skill.py
# 之前:每个助手手动配置十几个参数
service = DeepAgentService(
    service_name="weekly",
    system_prompt_generator=gen_agentic_system_prompt,  # 120 行函数
    index_names=["weekly_all"],
    soul_path="weekly/soul.md",
    output_rules_path="weekly/output_rules.md",
    enable_searcher_subagent=True,
    # ...
)
after_skill.py
# 之后(目标):Skill 声明能力,soul 声明角色
service = DeepAgentService(
    service_name="weekly",
    soul_path="weekly/soul.md",           # 角色(每个助手不同)
    skills=["knowledge-retrieval"],        # 能力(共享 Skill)
)

Skill 组合

对于有额外逻辑的助手(如 SSP 的设备型号过滤),可以通过 Skill 组合解决:skills=["knowledge-retrieval", "ssp-product-filter"]。通用检索能力由共享 Skill 提供,SSP 的型号过滤逻辑封装为独立的专属 Skill。

Skill 在 Harness 中的位置

从 Harness Engineering 的视角看,Skill 是 Harness 七层架构中的**"可插拔能力层"**:

Agent Harness 架构:
  Soul     → 定义"我是谁"(角色)           → 每个助手不同
  Skill    → 定义"我会什么"(能力)          → 可跨助手共享
  Middleware → 定义"我的边界"(行为约束)     → 框架统一管理
  Memory   → 定义"我记住什么"(知识持久化)   → 框架统一管理
  Recovery → 定义"出错怎么办"(容错降级)     → 框架统一管理
  Eval     → 定义"做得好不好"(质量评估)     → 框架统一管理
  State    → 定义"对话到哪了"(会话状态)     → 框架统一管理

之前的系列文章分别讨论了 Middleware、Memory、Recovery 这些层。Skill 是最后一块拼图——它把"能力"从 prompt 字符串中解放出来,变成独立的、版本化的、可组合的模块。

Agent Skills Specification

Agent Skills 的完整格式规范,包括 SKILL.md frontmatter、目录结构和渐进式加载设计

agentskills.io

Equipping Agents for the Real World with Agent Skills

Anthropic 关于为什么要做 Agent Skills 标准的工程博客

www.anthropic.com

Harness Engineering — OpenAI

Harness Engineering 的概念定义。Skill 是 Harness 中可插拔的能力层

openai.com

上一篇

生产环境中 Agent 记忆系统的设计与缺陷

分享:··

Finn

AI 工程师,做 Agent 系统和 RAG 检索。在这里写下工程实践中踩过的坑和学到的东西。

订阅 Newsletter

每周精选技术文章,直达你的收件箱。不发垃圾邮件,随时退订。

我们尊重你的隐私,邮箱信息仅用于发送 Newsletter,不会分享给第三方。

评论

目录

  • 问题:N 个助手复制粘贴同一套检索逻辑
  • Skill 的结构
  • 渐进式加载的量化分析
  • 从 prompt.py 提取了什么、保留了什么
  • references/ 的拆分依据
  • Skills 与 MCP 的双栈关系
  • 跨助手复用的效果
  • Skill 在 Harness 中的位置