当前位置: 首页 > news >正文

AI 应用工程:Tool、MCP、Skill 与 Workflow 如何接入 Agent?——搭建一个可运行的需求影响面分析 Agent

近期落地接入时发现一个共性认知偏差:很多人把 Tool/MCP/Skill/Workflow 一概当成 Agent 插件,统一放在一个列表里,依靠模型自行走完完整流程。可业务一旦需要交付物校验、上下文拼接、强制审批等逻辑,这种简单堆砌的实现方式就会出现各类问题。

这篇就用一个可以直接运行的最小项目,把四类能力的接入点和参与时刻讲清楚——它们不是四种并列组件,而是分别落在不同的工程责任上。

项目描述:跑通一次“需求影响面分析”任务,并输出一份带校验字段的 JSON 报告。
完整DEMO项目地址:https://gitcode.com/ligang2585116/agent-demo


开篇:先分清接入位置

上一篇 已经讲过职责边界。本篇展开前,先把四类能力放在同一张表里对照。

维度ToolMCPSkillWorkflow
本质模型可调用的一个动作/函数连接外部能力的标准协议按需加载的任务方法论(SKILL.md包住 Agent 的确定性代码流程
解决的问题模型自己做不了的事(查数据、执行操作)外部能力如何被统一发现与调用领域知识不常驻 Prompt,任务匹配时才加载关键环节不允许模型自由裁量
接入位置ToolRegistry,暴露给模型应用侧适配层:Client 把 Tool 转成 Function Tool,Resource 由应用拼入 Context摘要进初始上下文,正文经activate_skill按需进入Agent 循环之外的应用代码
谁触发模型决定调用Tool 由模型调;Resource 由应用主动读模型判断任务匹配后激活代码无条件执行,模型无法感知或跳过
形态代码(函数 + Schema)协议 + 进程(Server / Client)文档(SKILL.md+ 可选资源)代码(普通流程逻辑)
本篇示例resolve_project_ownersearch_codearchitecture://project-mapimpact-analysis/SKILL.md输入校验、Zod 报告校验、审批门禁

这张表是本文的观察框架,不是某一家厂商的统一分类。MCP Resource 是否进入 Context 由 Host 决定,协议不会自动完成。1

几组容易混淆的对比

Tool vs MCP:不是并列关系。MCP 是连接协议,不是和本地 Function Tool 同层级的“另一种 Tool”。mcp-client.ts把 MCP Tool 适配进ToolRegistry之后,模型看到的是同一套 Function Tool 列表,根本分不出哪个来自本地、哪个来自 MCP Server。区别只在工程侧:本地 Tool 是你写的函数,MCP Tool 是别的进程或别的团队通过标准协议提供的能力。

Tool vs Skill:Tool 提供‘手’,Skill 提供‘操作手册’。 Tool 返回的是数据或执行结果;Skill 激活后返回的是指令文本,告诉模型该按什么步骤做、输出什么格式。本篇里 Skill 的激活机制本身也借助了一个 Tool——activate_skill——但这只是交付方式:Skill 仍然是SKILL.md资产,激活 Tool 不是把 Skill 降格成普通动作。

Skill vs Workflow:两者都写“流程”,约束力完全不同。这是接入时最关键、也最容易混的一处:

  • SKILL.md里写的“先搜代码 → 再查依赖 → 输出 JSON”是建议,模型可以不遵守;
  • workflow.ts里的if (highRisk && !approved) throw强制,模型连感知它的机会都没有。

判断一条规则该放 Skill 还是 Workflow,只问一句:这条规则被违反了,能接受吗?能接受 → Skill;不能接受 → Workflow。

Tool 是手,MCP 是接手的标准插座,Skill 是操作手册,Workflow 是流水线上的质检关卡。前三者服务于模型的自主决策,最后一个专门限制模型的自主决策。

后面六节按接入顺序展开:先搭 Harness,再依次接入本地 Tool、MCP、Skill、Workflow,最后跑通一次完整 Run。


一、先搭一个最小 Agent Harness(把循环写出来)

先把问题收窄:最小 Harness 到底要做什么?

对本篇而言,它只保留两项职责:

  1. 把可调用能力整理成模型可见的 Tool 定义;
  2. 解析模型返回的 Tool 调用,把结果回填,再继续循环,直到出现最终文本或触发最大迭代次数。

下面这段是最核心的结构(摘自agent-demo/src/agent.ts的写法):

// 关键点:模型只“请求调用”,执行发生在应用侧for(letiteration=0;iteration<this.maxIterations;iteration+=1){if(turn.type==="final")returnturn.text;constresults=awaitPromise.all(turn.calls.map((call)=>tools.execute(call)));turn=awaitmodel.continue(results);}

为什么要把“执行发生在应用侧”写进代码结构?因为 Tool Calling 的协议里,本质是“模型提出动作 → 应用执行 → 应用回填 → 再请求”。2

Harness 不做 Workflow 的校验、不做 Skill 的激活决策、不做 MCP 发现;它只负责把“动作循环”跑通,并给上层流程提供一个稳定入口。


二、注册第一个本地 Function Tool(让模型能查负责人)

本地 Function Tool 解决的是:模型要能提出“查询项目负责人”的调用请求。

在示例里,这个 Tool 叫resolve_project_owner,入参只有一个projectName,输出包含ownerteam。核心代码在agent-demo/src/local-tools.ts

接入方式也很直接:把 Tool 注册到ToolRegistry,同时把输入 schema 暴露给模型 Adapter。

本节只强调两点工程边界:

  1. Tool Registry 是应用侧的动作目录,模型只是看见 Tool 的描述与参数结构;
  2. 强制校验不放在 Tool。如果你把“必须校验/必须审批”也做成 Tool,那么模型可以不调用,Workflow 的门禁就会失效。

这一点在第五节 Workflow 会反过来体现出来:校验发生在应用代码里,不交给模型选择。


三、用 MCP 接入外部能力(Tool 发现与调用在应用侧完成)

接入 MCP 时,有三个问题必须回答:Server 暴露什么Client 发现与调用什么接入后模型看到什么。本节依次展开。

本篇选择最简单的本地 stdio 方式:Harness 启动子进程作为 MCP Server,再由 MCP Client 做连接、分页发现和调用。3

1) MCP Server:暴露两个 Tool + 一个 Resource

示例 MCP Server 在agent-demo/src/mcp-server.ts,它提供:

  • Tool:search_code
  • Tool:get_project_dependencies
  • Resource:architecture://project-map

Server 侧注册 Tool 的写法遵循 SDK 文档的示例范式(registerTool+inputSchema+ handler)。3

2) MCP Client:listTools/listResources + callTool/readResource

Harness 在agent-demo/src/mcp-client.ts里做了两类工作:

  1. listTools:把工具元数据发现出来(本篇实现了 cursor 分页的遍历)。
  2. callTool:把模型提出的 Tool Call 转发给 Server 并执行,然后把返回内容转成 Harness 统一的 ToolResult。

在这里要特别区分两条错误路径:
工具业务失败可能表现为isError: true,但 JSON-RPC 协议故障会导致请求直接 reject/throw;应用侧需要分别处理。4

3) Tool schema 映射:MCP inputSchema → 模型 function parameters

将 MCP Tool 适配到模型 function tool,本质上是做一个“应用侧转换层”——对应开篇表里 MCP 的「接入位置」一行:

  • MCP 的inputSchema是 JSON Schema,可以直接作为模型 function tool 的参数结构使用;
  • 但协议消息结构、返回内容格式、以及工具执行确认都不在 MCP 里解决,需要由 Harness 自己处理。1

Resource 则完全不同:Resource 的进入上下文由应用控制。本篇在 Workflow 里先读architecture://project-map,再把它拼进任务 Context。1


四、加载impact-analysisSkill:只常驻 Catalog,激活时再注入完整指令

Skill 的目的,是让“任务方法”以SKILL.md形式可复用,而不是把所有规则写进一个巨长 Prompt。

示例里,Skill 在/skills/impact-analysis/SKILL.md,它遵循开放规范:YAML frontmatter + Markdown 正文,namedescription是必填字段。5

1) Progressive Disclosure:先 Metadata,再 Instructions,再按需资源

在示例实现里,Catalog 只包含namedescription(以及位置等最少信息),激活时才把完整SKILL.mdbody 注入上下文。这对应官方客户端指南描述的 progressive disclosure 机制。6

2) 为什么要有activate_skill(name)这一层?

如果模型能直接读文件,可以让它自己去读SKILL.md;但为了统一教学示例,本篇走专用激活 Tool 路径:

  • 模型只给出一个activate_skill的调用请求;
  • Harness 用受控的 Skill Map 查找并读取对应 Skill 内容后,再返回给模型;
  • 支持配置松耦合:Skill 资产在哪里、怎么组织,由 loader 决定。7

同时,本篇 loader 做了真正的 YAML frontmatter 解析,而不是用正则硬拆字段,以避免多行值/引用等边界导致字段丢失。8


五、Workflow:把不可跳过的校验与审批写进应用代码

这一节回答一个看似反直觉的问题:既然 Skill 里已经写了分析步骤和输出要求,为什么还要 Workflow?

原因很简单:Skill 指令是否被执行,取决于模型“理解并选择”;Workflow Gate 必须由代码强制执行,否则模型可能直接输出一段未经校验的文本就结束 Run,绕过你预期的交付路径。

示例把 Workflow 写成普通 TypeScript 函数,并固定一个顺序:

validateInput → 读取 MCP Resource(architecture://project-map) → runAgent(Tool 调用循环发生在这里) → validateReport(Schema 校验发生在这里) → highRisk → approvalGate.confirm → publish

validateReport使用 schema 校验输出字段,失败直接抛出错误,不进入发布路径。approvalGate也同样是代码层面控制:高风险报告被拒绝时,Workflow 不会“继续产出结果”。9

这里直接对应官方对 Workflow 的定义取向:Workflow 是预定义的路径/门禁;Agent 则是模型动态决定过程与 tool usage。9


六、跑通一次:离线模式先验证“接入点都真的执行了”

在本地按以下步骤跑通:

cd"agent-demo"npminstall--registry=https://registry.npmjs.orgnpmtestnpmrun demo

npm run demo默认是离线模式(不需要OPENAI_API_KEY)。你会看到一条清晰的 Trace(示例输出):

MODEL_MODE=offline Workflow: validate input MCP:readarchitecture://project-map Model: activate impact-analysis Model: call search_code Model: call get_project_dependencies Model: call resolve_project_owner(checkout-web)Model: call resolve_project_owner(merchant-console)Model: call resolve_project_owner(finance-admin)Model: produce report Workflow: validate report Workflow: approval required Workflow: publish

注意这里的“验证重点”不是评测模型好不好,而是证明工程链路真的闭合:

  • MCP Client 发现与调用确实发生;
  • Skill 被激活并注入了完整指令;
  • Workflow 的校验与审批确实发生;
  • 最终输出满足你在 Workflow 里定义的报告 schema。

如果你想切到 Live 模式,只需要把 Adapter 切到 OpenAI Responses API,并配置环境变量。示例项目里也提供了MODEL_MODE=live分支,但默认以 offline 作为可复现基线。10


七、替换 Model/Server/业务时,哪些模块可以保留?

这一节用“替换对象”倒推职责边界,帮助你避免把 demo 变成不可迁移的样板。

1) 换模型 Provider(只替换 Model Adapter)

你需要替换的是:

  • provider 专属的 Tool Call/Result Item 解析与组装;
  • 但 Harness 的“动作循环”、Tool Registry、Workflow、MCP 适配层都可以保留。

这也是本篇选择 Model Adapter 的原因:把 Provider 差异限制在 Adapter 边界内。2

2) 换 MCP Server(只替换 Server 配置 + Tool Allowlist)

你需要调整的是:

  • Server 启动方式、暴露工具集合、以及 Resource 的 URI;
  • Harness 仍然沿用同一套 listTools/callTool/readResource 的调用结构(尤其要保持错误路径处理一致)。4

3) 换业务场景(替换本地 Tool、Skill 与 Workflow Gate)

当业务规则发生变化,最先动的是:

  • 本地 Function Tool 与其校验 schema;
  • Skill(方法与输出模板);
  • Workflow 的结果校验与高风险判定。

这三块变化的规模通常比你想象的小,因为它们都与“交付物 schema 与强制门禁”直接绑定。

4) 但请记住:这仍然不是生产 Runtime

这个最小例子能完成一次任务,但它缺少第四篇要讲的生产能力:如何在中断后恢复、如何追踪执行、如何在真实故障里评测与改进。

所以收束一句:接入链路跑通了 ≠ 生产系统完成了。


适用/不适用边界

适用,把本文作为:

  • 新团队建立 Agent 接入基线(先跑通再扩展);
  • 需要把“工具、外部能力、任务方法、门禁路径”拆清楚的工程训练。

不适用,把本文当作:

  • 完整生产 Runtime(没有 checkpoint/memory/evaluation/observability);
  • 多厂商跨协议的通用 SDK 教程(本篇锁定了具体的版本基线,用于可复现)。

下一篇我会接着回答:为什么一次任务跑通之后,仍不能直接进入企业生产环境。


来源索引(用于支撑关键技术断言)


  1. MCP Tool/Resource 边界:Tool 是工具动作,Resource 由应用控制如何进入 Context:https://modelcontextprotocol.io/specification/2025-11-25/server↩︎ ↩︎ ↩︎

  2. OpenAI Function Calling:模型提出 tool call、应用执行与回填循环由应用侧完成:https://developers.openai.com/api/docs/guides/function-calling↩︎ ↩︎

  3. MCP v1:stdio/Streamable HTTP transport 与本地子进程集成方式:https://github.com/modelcontextprotocol/typescript-sdk/blob/v1.x/docs/server.md↩︎ ↩︎

  4. MCP Tool 错误语义:isErrorvs JSON-RPC 协议故障不同处理路径:https://modelcontextprotocol.io/specification/2025-11-25/server/tools↩︎ ↩︎

  5. Agent Skills 开放规范:Skill 目录包含SKILL.md,frontmatter + Markdown,必填name/descriptionhttps://agentskills.io/specification↩︎

  6. Agent Skills Progressive Disclosure:Catalog(metadata)→ 激活(instructions)→ 资源按需进入:https://agentskills.io/client-implementation/adding-skills-support↩︎

  7. Skill 激活机制与专用激活工具模式:https://agentskills.io/client-implementation/adding-skills-support↩︎

  8. YAML frontmatter 解析与分离 metadata/body:官方客户端实现指南与参考解析器(按需解释):https://agentskills.io/client-implementation/adding-skills-support↩︎

  9. Workflow 与 Agent 的架构区分(Workflow 预定义路径,Agent 动态路径):https://www.anthropic.com/engineering/building-effective-agents↩︎ ↩︎

  10. OpenAI 官方 TypeScript SDK 与 Responses API 作为主要接口:https://github.com/openai/openai-node、releasev6.49.0(调研基准日 2026-07-27) ↩︎

http://www.jsqmd.com/news/1292447/

相关文章:

  • 基于Proteus的STM32环境监测系统仿真:从传感器模拟到ADC采集全流程解析
  • TI嵌入式开发实战指南:从MSPM0入门到I2C/SPI通信调试
  • Qt应用动态语言切换:实现不重启实时更新界面文本
  • 1:12遥控液压挖掘机模型:3D打印与CNC加工的多工艺集成实践
  • C语言扫雷递归展开优化:从栈溢出到队列BFS的算法演进
  • 一加15顶配版游戏性能实测:骁龙8 Gen 4散热与帧率稳定性分析
  • YOLO目标检测训练与测试工具 YOLO一键训练工具
  • Unity道路系统高效构建:EasyRoads3D核心功能与实战指南
  • 库存管理系统构建:数据驱动的仓储数字化管控架构
  • 读懂大模型六大核心底层概念:从原理到落地应用
  • C++与Python实现Modbus TCP客户端:Qt框架下的性能与效率抉择
  • 照片怎么改大小kb手机软件:会议PPT插图撑爆后的处理日记 - AI测评专家
  • Linux CAN应用编程实战:从Socket CAN到嵌入式通信开发
  • WeChatPad终极指南:如何简单三步实现微信双设备同步登录
  • Node.js安装全流程
  • 布隆过滤器详解:从原理到 Go 实现,解决缓存穿透问题
  • AI改写消费决策链路,出海品牌如何借合作伙伴营销破局?
  • 深入解析Windows C++ DLL导出技术:从原理到实战避坑指南
  • Xshell:从零到精通的SSH终端工具实战指南
  • Java逻辑运算符深度解析:从短路机制到实战应用
  • [虾说AI]白话全解上下文工程一:什么是上下文工程
  • Simulink仿真实现PMSM脉振高频注入无感控制:原理、建模与调试
  • Windows Python环境配置全攻略:从多版本管理到虚拟环境实战
  • 迪文串口屏开发实战:从硬件对接到单片机通信全解析
  • Claude中转站用于教程内容生产:大纲、步骤与FAQ一体化
  • 海思Hi3531D通过IT6801实现HDMI转BT1120视频采集全流程解析
  • C++虚函数表(vtable)与虚指针(vptr)底层机制详解
  • 技术人选电脑租赁平台不看价格:六维选型框架拆解
  • HC毛发插件在Maya中的完整应用指南:从基础到AAA级游戏制作
  • 智读致用《噪声》全书总结|噪声不会消失,但你可以学会和它共处