Agent 的脑和手——把 SOP 塞进知识库不等于 Agent 能做事|Agentic AI 落地方法论(六)

Yaqin Hei··16分钟阅读
中文EN
Agent 的脑和手——把 SOP 塞进知识库不等于 Agent 能做事|Agentic AI 落地方法论(六)

《Agentic AI 落地方法论》系列第六篇。 前五篇拆「方案能不能上线 + 上线后怎么不放养 + 北极星指标怎么定」——L0-L3 定级L2 vs L3 的 5 个架构决策Critic fail-closed上线即放养接住率 vs 解决率。这一篇换一个角度——为什么 90% 的「我们 Agent 落地了」其实只是「我们 RAG 上线了」,和怎么把这条线划清楚。English version: Brain and Hands — Why Stuffing SOPs Into a Knowledge Base Doesn't Make Your Agent Capable.

「我们把 SOP 都写进知识库了」——这句话是评审会上最常见的伪 Agent

某零售客户客服 Agent 项目验收会,乙方 PPT 翻到第 12 页:

「目前已沉淀 SOP 文档 320 篇 / 政策条款 1,400 条 / FAQ 8,000 条 / 商品话术 6 万条——全部入知识库,召回率 92%,RAG 准确率 87%。」

老板点头。然后随口问了一句:「那现在客户问『帮我把昨天那笔退一下』,能直接退吗?」

PPT 翻完没有这一页。乙方答:「这个我们后面会加退货流程的 Skill。」——意思是没有。

那一刻在场的所有人都意识到一件事:320 篇 SOP + 1,400 条政策 + 92% 召回率,只是让 Agent 知道退货政策长什么样。它没有让 Agent 能给客户办退货。

这一年我跟的所有客服 / 补调 / 工单 类 Agent 项目,技术评审最大的盲区都不在算法、不在模型选型、不在向量库选哪家——是在这一条:没人把「知道」和「能做」分清楚

知识库塞满了,就当能力齐了。检索准确率上去了,就当 Agent 落地了。第一次客户来个写操作请求,整个项目原地翻车。

这一篇拆三件事:(1)脑 vs 手 在工程上到底差在哪、(2)一个 3 行的测试把你方案里的假 Skill 揪出来、(3)「为什么没有像 MCP 那样的 Skill 协议」这个问题为什么问反了。

知识库是脑,Skill 是手——一张表分清

先把结论摆桌面上:知识库(Knowledge Base)和 Skill 不是同一类东西的两种实现,是 Agent 架构里两个完全不同的层。混淆这两个,方案从第 1 天就建错了。

知识库Skill
回答的问题Agent 知道什么Agent 能做什么
内容形态事实、政策、SOP、产品信息、对话语料触发条件 + 工具调用 + 约束 + 输出契约
怎么被触发被检索(RAG,问题进来就召回)被调用(Agent 判断需要执行某个动作)
关键失败模式召回错了 → 答错 / 漏答调用错了 → 给客户多退 980 元 / 给错的人发优惠券
维护者业务 / 运营工程
更新触发政策变了 / 产品上新系统接口变了 / 业务规则变了
审计粒度文档版本调用日志 + 入参 + 出参 + 决策依据
可逆性召回错了 → 改文档重新嵌入写操作错了 → 退款已发出 / 工单已关 / 库存已扣
测试方法召回精度、Recall@K端到端流程对账、幂等性、Critic 漏放率

最后两行特别重要:写操作出错不可逆。知识库召回错了,下次问换个 prompt 还能补救;Skill 调错了,钱已经退出去了。所以 Skill 必须有 Critic(系列三整篇在讲),知识库不一定要。

一句话压缩——知识库回答「客户为什么生气」,Skill 决定「我要不要给他退钱」。前者 RAG 召回就够了,后者要 trigger / tool / constraint / critic 全栈一起上。

知识库回答「为什么生气」,Skill 决定「要不要给他退钱」——L1 看不出差别,L2 分生死

同一份退货政策,在知识库里是「Agent 能告诉客户 7 天无理由可退」,在 Skill 里是「Agent 能真的把退款发起、对账、留审计、Critic 兜底」——这道分界决定 L2 项目能不能上线。

一个 3 行的测试:你方案里的「Skill」是真 Skill 还是知识库别名?

下面这个测试是这一年我反复在评审会上用的。任何被标为「Skill」的能力点,用这 3 行问回去:

Test-1:触发它的不是用户问句,而是 Agent 的判断?

  • 知识库典型触发:用户问「退货怎么办」→ embedding 检索 → 召回政策段 → LLM 抽取关键事实 → 答用户。
  • Skill 典型触发:用户说「帮我退一下昨天那笔」→ Agent 判断(这是 write op + 涉及订单 ID + 涉及金额)→ 决定调用 refund_order Skill。

如果你的「Skill」本质上是「问题进来 → 检索 → 把检索结果说出来」,那不是 Skill,是知识库的别名。

Test-2:它有写操作 / 副作用 / 调外部系统?

  • 调订单 API 改状态 = 有副作用
  • 调 IM 给客户发消息 = 有副作用
  • 调 CRM 写客户标签 = 有副作用
  • 召回退货政策段告诉客户 = 没有副作用(只是读)

任何「能力」只读不写、不调外部系统、不改任何状态,本质都是知识库的延伸表达。把这类东西命名成 Skill 是营销话术,不是工程区分。

Test-3:失败模式是「答错了」还是「做错了」?

  • 答错 → 用户看到错的回复 → 一般可以再问一次纠正 → 损失:客户体验
  • 做错 → 系统状态被改了 → 不能"再问一次"撤销 → 损失:钱 / 工单 / 库存 / 合规

写操作错了不可回头——这是 Skill 真正的工程特征。如果失败模式是「答错」,那它是知识库;如果失败模式是「做错」,那才是 Skill,那才需要 Critic + 灰度 + 审计链路。

3 个 test 任何一个答「不」,那个「Skill」就是知识库别名。这一招放到下次评审会上,乙方 PPT 上自称的 5-8 个 Skill,多半剩下 2-3 个是真的。

把 CLAUDE.md 写满规则不等于这些规则会执行——一个博客项目里的同构问题

这件事我自己做这个博客 18 个月也踩了一遍。

CLAUDE.md 现在有 2 万多字,里头写满了规则:「跑 npm run build 之前要确认 dev server 没开」、「写公众号 markdown 时 **X**:description 要写成 **X:** description 避免冒号撞行首」、「DB-backed 的页面要 export const revalidate = N」、「不要给 next.config 加显式 distDir」。

每一条规则都是踩坑后写下来的——文字、清楚、附带原因和反例。问题是:下一次新对话开始,Claude(或者我自己半年后回来)会不会自动遵守?

答案:看是不是变成了执行。

规则留在 CLAUDE.md(知识库)写成代码(Skill)状态
跑 build 前不能让 dev server 在 :3002「Gotchas」里写了scripts/check-dev-server.js prebuild hook,跑 build 前自动检测、阻断✅ Skill 化
公众号 **X**: 冒号撞行首notes/2026-05-18-wechat-colon-orphan.md 写了scripts/mdx-to-wechat-html.mjsmarked.parse 之前一行 regex 自动修✅ Skill 化
API 端点动 Post 表前要 ensurePostInDB(slug) 自动 seedCLAUDE.md 里写了lib/db.ts 提供 ensurePostInDB 函数 + view/clap 端点都调了✅ Skill 化
不要给 next.config 加显式 distDir「Gotchas」里写了,附 burn site reference没有 lint / hook 强制⚠️ 还是知识
MDX 里不要写 <2%(会被 JSX 解析)CLAUDE.md 案例里写了没有 pre-commit 检查⚠️ 还是知识
ZH-first ship 时要去掉 alternateLang frontmatter系列产出指南里写了没有脚本检查⚠️ 还是知识

前 3 条变成了脚本之后,它们不再依赖我或 Claude 记得。第 4-6 条只要还是文字,每次重开对话都有概率漏。

规则只要还在文档里就是"希望"——只有变成执行才是"能力"。3 条已 Skill 化,2 条还在文档里靠人记

这个博客 18 个月里 CLAUDE.md 写了 2 万多字。每条规则下次重开对话都有概率漏——直到把它变成 prebuild hook、变成 marked 的 pre-processor、变成 ensurePostInDB 函数。这件事和客服 Agent 完全同构。

这是 Skill 的工程定义:一条规则只要还停留在文档里,它就是「希望」;它一旦能在系统执行流里被强制走到,才是「能力」。

这件事和客服 Agent 完全同构:

  • 「7 天无理由退换」写在客服培训手册里 → 知识库
  • 「7 天无理由退换」走到下单页底部 + 退货按钮点开自动判断时间 + 超 7 天直接灰掉退货选项 → Skill 化

前者是「客服都知道这条政策」,后者是「这条政策被流程强制执行了」。两者之间隔着是不是被代码(或确定性流程)兜底。Agent 也是同一道分界。

「为什么没有 MCP 那样的 Skill 协议」——这个问题问反了

每隔两周就有人在评审会上问这个。措辞略不同——「行业有没有统一的 Skill 标准」、「我们要不要等 OpenAI 出一个协议」、「Anthropic 的 Skills 算不算工业标准」——本质都同一个问题:我们是不是该等一个标准出来再开始?

不是。这个问题问反了,原因有 3 条:

原因 1:MCP 和 Skill 不在同一层。 MCP 解决的是 transport——Agent 怎么调外部工具,工具怎么暴露能力,鉴权 / 通道 / 序列化怎么走。它是协议层的东西,所以可以标准化。

Skill 是 policy——这个工具在你这家公司客服场景里允不允许调、调之前要不要先查会员等级、调失败要不要主动补偿、超过多少金额要转人工。这是业务规则的封装,不是传输标准。

行业不会出一个统一协议告诉你「客服 Agent 退款金额超过 500 元应该转人工」,因为这件事每家公司都不一样。你公司的客单价 300 元,门槛可能是 500;你竞品的客单价 3000 元,门槛是 5000。统一协议在这一层不存在,也不应该存在。

原因 2:MCP 已经在你想要的那一层做完了。 你担心的是「我接 5 个 SaaS 系统,每个都自己的 API,没法复用」——这件事 MCP 已经解决了。订单系统、工单系统、物流系统、CRM 系统、IM 系统,全部按 MCP server 暴露能力,Agent 用统一调用方式接所有这些。这是真的 protocol-level 标准化。

剩下的「这个 tool 在这个场景下怎么用、什么时候调、调之前要先做什么」,那部分本来就该是你公司自己的资产,不应该等一个外部标准告诉你。

原因 3:等就是不开始。 行业里凡是说「等 Skill 标准出来再上 Agent」的公司,6 个月后看,全部什么都没做。等的人不是在等协议,是在用「等协议」当不动手的理由。

行业的真实状态——

标准状态
工具传输层MCP / OpenAPI / function calling schema成熟,照着接就行
知识检索层embedding + RAG + rerank成熟,开源闭源方案一抓一把
Skill 定义层YAML + Prompt + 工具引用 + Critic没有外部统一标准,也不需要
多 Agent 编排层A2A / OpenAI Swarm / LangGraph早期,方案在收敛

中间两层是你自己企业的内功,没有外部协议能替你定义你公司的客服 Agent 该怎么退款。这件事跟 ERP / OMS 时代是一样的——SAP 不会出一个协议告诉你 SKU 怎么打标,它给你字段和工作流,标怎么打你自己定。Skill 在 Agent 时代是同一个位置。

一个 Skill 真正长什么样——比 YAML 多三块

很多人看到「Skill 用 YAML 定义」就觉得够了。不够。一个真正能落地的 Skill 至少要 5 块。下面是我跟过的项目里收敛出来的最小 Skill 规范:

skill:
  name: "refund_order"
  description: "对未发货 / 7 天内的订单发起退款"

  # 1. 触发:谁来调,怎么知道该调
  trigger:
    intents: ["refund_request", "cancel_order"]
    required_entities: ["order_id"]
    optional_entities: ["refund_amount", "reason"]
    # Critical: trigger 不止是 intent 匹配,还要 entity 齐
    # 没有 order_id 就不能调,应该转去「澄清意图」分支

  # 2. 知识引用:调之前 / 调之间要查哪些政策
  knowledge:
    must_check:
      - "refund_policy.7day_no_reason"       # 7 天无理由条款
      - "refund_policy.shipped_status"        # 已发货 vs 未发货
      - "member_tier.refund_priority"         # 会员等级影响优先级

  # 3. 工具调用:调什么、参数怎么填、失败怎么处理
  tools:
    - server: "order-service"
      action: "query_order_status"
      timeout_ms: 1500
      on_failure: "escalate_to_human"

    - server: "order-service"
      action: "initiate_refund"
      idempotency_key: "refund:{order_id}:{timestamp}"
      timeout_ms: 3000
      on_failure: "rollback_and_escalate"   # 失败必须能回滚

  # 4. 约束:在这个公司这个场景,这个 Skill 不允许做什么
  constraints:
    - "refund_amount 必须 ≤ order_total_paid"
    - "refund_amount > 500 → 必须转人工二次确认"
    - "同一订单 24h 内不允许重复调用"
    - "用户未实名 → 不允许调用"
    - "凌晨 02:00-08:00 → 转人工(风控时段)"

  # 5. Critic:调用前 + 调用后 双层审查
  critic:
    pre_call:
      - check: "金额对账:amount == queried_order_total"
      - check: "状态对账:order_status in ['paid','shipped_not_delivered']"
      - check: "时间窗:now - order_create_time <= 7 days"
      timeout_action: "fail_closed"          # 超时即升级(系列三讲过)

    post_call:
      - verify: "refund record 已写入"
      - verify: "用户已收到确认通知"
      - verify: "三方对账接口返回一致"
      timeout_action: "alert_human"

  # 6. 输出契约:调用结果怎么回给上层
  output:
    success:
      template: "已为您发起退款,预计 X 个工作日到账,订单号:{order_id}"
    failure:
      template: "[转人工] 我帮您接入人工客服跟进退款,请稍等"
      attach_context: true                   # 工单系统能看到 Agent 之前的判断链路

最关键的是 4、5、6 三块——constraints + critic + output 契约。

constraints 是这家公司这个场景的业务规则封装。「金额 > 500 转人工」是这家公司的风控阈值,下家公司是 5000。这部分只能你自己定,没有外部标准。

critic 是写操作的兜底审查。pre_call 检查参数对得上,post_call 检查调完了状态对。任何一关 fail → 升级人工(系列三 fail-closed)。一个没有 critic 的 Skill 上线就出事故,时间问题而已。

output 契约决定 Agent 调完 Skill 之后能不能跟上下游对话。包括失败时的话术、人工接管时附带的上下文——这件事乙方默认会跳,因为 demo 阶段只演示 happy path,failure path 的输出契约没人写。

少了这三块,剩下的 YAML 只是「调 API 的薄壳」,谈不上 Skill。

5 个失败模式:「我们只用 RAG 也能做」的方案为什么 6 个月后翻车

这一年我跟过的几个项目,乙方一开始的方案就是「我们把 SOP 入知识库,加上 LLM,就能解决」。6 个月后翻车的 5 个典型模式——

模式 1:知识漂移——政策变了,知识库没更新,Agent 照念老政策。客服领域这件事每周发生:商品下架了、活动结束了、规则改了。这件事 RAG 系统结构上没办法管,因为它不知道知识过期。Skill 化的对应做法:每次调用前 pre_call critic 查最新政策接口,不依赖 embedding 副本。

模式 2:幻觉执行——Agent 看了「7 天无理由退换」的政策文档,自己脑补出退款已经发起的话术回给用户。用户以为退完了,过两天发现钱没到账,回头投诉。这一年至少在 3 个项目里见过。RAG 模式下根本拦不住——只读不写的链路里,LLM 编一句「退款已发起」零成本。Skill 化后这件事调不了 initiate_refund API 就根本说不出口。

模式 3:没有审计链路——客户投诉「为什么给我多退了 200」,公司想查是谁批的、为什么批,RAG 模式只能查到 Agent 当时检索了哪几段政策,查不到为什么决定退这个数。Skill 模式下整个调用链有日志:trigger → critic → tool call → response,每一步入参出参都在。出事故时这件事决定能不能定责。

模式 4:prompt-only 治理——所有约束都写在 prompt 里:「金额超过 500 一定要转人工」、「凌晨不要做退款」、「记得查会员等级」。LLM 听 70-80% 的话,剩下 20-30% 该听不听。prompt 越长这个比例越糟。Skill 模式下 constraints 是代码 if-then,确定性走通,不依赖 LLM 自觉

模式 5:版本回滚不可能——RAG 系统里调整一段政策文档的描述,整个 embedding 索引重建一次,效果上不上不知道,回滚也只能再重建一次。Skill 模式下 YAML 走 git,每次改动 diff 可见、灰度可控、一键回滚。

5 个模式有一条共性:纯 RAG 方案在「写操作」这件事上没有任何工程兜底。所有兜底都靠 prompt 提醒 LLM 自觉。LLM 不自觉时,问题直接打到生产用户。

这就是为什么 L1 场景可以 RAG-only,L2 / L3 不行(L0-L3 定级)——级别越高,写操作越多,对工程兜底依赖越重,对 Skill 化的需求越硬。

落地路径:从 5 个 Skill 开始,3 个月建起企业 Skill 库

不要等协议。也不要一口气定 50 个 Skill。从最痛的 5 个开始:

第 1 个月:盘点你现在客服 Agent 真正在做的写操作。一个 L2 客服 Agent 一般是 5-8 个:查订单 / 发起退款 / 创工单 / 改地址 / 发优惠券 / 标记投诉 / 转人工。每一个写一份完整的 YAML(5 块齐:trigger / knowledge / tools / constraints / critic)。

第 2 个月:把这 5 份 YAML 放进 git,建一个 skills/ 目录,每个 Skill 一份 PR、走 code review。重点 review 两个地方:(1)constraints 业务侧签字,(2)critic 工程侧签字。任何一边没签 → 这个 Skill 不上线。

第 3 个月:把同样的格式复制到非客服场景。补调(智能补货)、滞销预警、排班——同一份 YAML 模板填新场景的 trigger / tool。3 个月跑完,你公司的内部 Skill 规范就建起来了。

这个东西完全不依赖外部协议。等的所有公司,3 个月后还在等。

5 个评审问题:下次乙方说「我们有 N 个 Skill」时问回去

下次乙方 PPT 翻到「我们已沉淀 X 个 Skill」时,问这 5 个。任何一个答不上 = 那不是 Skill。

问题 1:把你们 5 个 Skill 的 YAML 定义发我一眼。 真 Skill 至少有 trigger + tools + constraints + critic 4 块。乙方拿出来的如果只是「我们做了 skill_refund.py」+ 一段调 API 的代码,那叫 wrapper,不叫 Skill。

问题 2:每个 Skill 的 critic 在哪里?pre_call 检查什么,post_call 检查什么,超时怎么办? 答「我们没有 critic,LLM 自己判断」= 直接终止评审(系列三专门讲为什么)。

问题 3:constraints 谁定的、改 constraints 要走什么流程? 合格答案:业务方和工程方双签 + PR 走 code review + 灰度上线 + 一键回滚。不合格答案:「都在 prompt 里写了」。Prompt 里写约束 = 没约束。

问题 4:Skill 调用失败时,上下文怎么交给人工? 合格答案:人工座席能看到 Agent 之前 trigger 了哪个 Skill、检索了哪些知识、试图调用什么 tool、为什么失败。不合格答案:「失败了就转人工」(剥离上下文,等于让人工从零开始)。

问题 5:5 个 Skill 里,写操作 Skill 占几个?纯读 Skill 占几个? 帮乙方分清这件事。如果他们 PPT 上的 8 个 Skill,6 个其实是「查 + 答」,2 个是真写操作——那意味着方案只解决 L1 + L1.5。L2 部分基本没做。

10 件这周可以做的事

  1. 把团队现在 Agent 方案里所有「能力点」列出来,用文章里的 3 行 test 走一遍,标出哪些是真 Skill / 哪些是知识库别名
  2. 抓一个最容易翻车的写操作(一般是「退款」「改地址」「发优惠券」),照着上面 6 块的 YAML 模板补全
  3. 把 constraints 单独拉出来给业务方签字——这是治理签字,不是技术签字
  4. 把 critic 的 pre_call / post_call 检查项单独列一张表给工程方签字
  5. 上线前跑一遍漏放率测试:故意构造 100 个边界 case(金额刚好 500 / 订单刚好第 8 天 / 凌晨 02:01),看 critic 拦下多少
  6. 写一份 Skill review checklist 挂工位墙——下次新 Skill PR 必走这张表
  7. 把知识库内容和 Skill 的 constraints 做一次对账——任何在知识库里出现「不能 / 必须 / 超过 X 要 Y」类语句,对应 Skill constraints 里要有等价 if-then
  8. 在你的 CLAUDE.md / 团队 SOP 里挑 1 条最常忘的规则,把它写成脚本 / hook,让它不能被忘
  9. 给所有写操作 Skill 加 idempotency key(典型格式 <action>:<entity_id>:<timestamp>)防重复触发
  10. 下次评审会拿这一篇的 5 个问题问乙方

写在最后:脑可以背 SOP,手要被流程兜住

知识库和 Skill 的区分不是一个名词游戏。它决定的是你的方案在第一次写操作出事故时,有没有兜底

「我们 SOP 都入库了」=「客服都背过那条政策」。这是真的,但和「公司退货流程能跑通」是两件事。后者要按钮按下去后系统真的能退、退完了对账对得上、出错了能追责——这是 Skill 工程化解决的事。

行业还会有人继续问「为什么没有像 MCP 那样的 Skill 协议」。等的人继续等。这一年开始动手定义自己 5-8 个 Skill 的公司,3 个月后就有真 L2 Agent 在跑了,他们不会再问这个问题

如果你公司方案里乙方自称的 Skill 数量 ≥ 5、但真写操作 Skill ≤ 2、且没有一个有完整 critic——这是个伪 Agent 方案。从今天起把上面那张 5 块 YAML 拿过去对一遍。一个对不上的 Skill 比 10 个对得上的容易补,先盯一个补到能跑。


工具包领取

如果你想把这一篇里的工具立刻用到下次评审会 / 团队 Skill 定义,我整理了一个 PDF 工具包:

回复关键词「SKILL 模板」,我把工具包发给你:

  1. Skill 定义 6 块 YAML 完整模板(refund / cancel / address-change / coupon-grant 4 个填好的示例)
  2. 「真 Skill vs 知识库别名」3 行测试表(评审会 + 内部 review 都能用)
  3. Skill review checklist(PR 必经的 9 项检查 + 双签字段)
  4. 乙方评审 5 问 + 合格 / 不合格答案样本

这一年跟项目里收敛出来的工程模板,送给读到这里的你。

回复渠道见页脚(公众号 / X)。不方便回复的,评论区留邮箱也行。

系列接下来排期

A4 系列下一篇——

  • 3 级 intent 级联调参:规则 + embedding + LLM 三级 fallback 的阈值怎么调(系列二决策 2 深挖)
  • LLM 接入企业 SaaS 生态:25 API → 5 tool 的契约和幂等性(系列二决策 4 深挖)
  • AI 系统怎么测:双轨架构 + 7 质量维度 + SSE Spike
  • 企业 LLM Agent 踩坑合集:async ES 阻塞事件循环 / Critic timeout fallback 误用 / proxy 拦 localhost / intent rename 跨 7+ 文件 / KB-ES 不同步

如果团队正在做 L2 客服 Agent 或别的写操作类 Agent,这 4 篇接下来一篇一篇出。

Subscribe for updates

Get the latest AI engineering posts delivered to your inbox.

评论