Agent 的能力体系

张开发
2026/4/5 0:37:44 15 分钟阅读

分享文章

Agent 的能力体系
提示词及其能力边界在将 Agent 具体应用到实际的生产环境中之前人们首先需要弄清楚的是提示词在这类应用中的作用到底是什么它的能力边界在哪里如果我们在这两个问题上的理解出现了偏差那么后续所有针对 Agent 应用的能力扩展都会被错误地理解为是一种更高级的提示词技巧。考虑到 LLM 的核心训练机制是在高维参数空间中寻找一个在给定数据分布上表现足够好的函数近似它的具体推理过程永远都是在根据某一概率分布来输出下一个文本单元在专业术语中我们称之为“Token”关于这个单位的具体计算方法读者可参考我稍后在“参考资料”一节中所提供的视频教程《关于 Token 的科普》。换言之LLM 并不是一个基于显式规则或程序控制流的命令执行系统因此当我们向 LLM 提供一个提示词时需要记得自己并非是在对它下“命令”而是在为其提供符合当前环境需求的上下文信息以便影响它输出的概率分布。这就意味着提示词调整的是 LLM 输出的概率倾向它无法改变 LLM 的能力边界。举个例子当我们在 Agent 应用中输入并提交如下语句作为提示词时它们的功能分别是“你是一名专业的法律顾问”用于角色塑造Persona目的是影响语气、知识调用倾向与表达方式。“请以 JSON 格式输出”用于输出约束Format Constraints目的是规范结果结构提高可读性与可解析性。“请分步骤推理”用于任务定义Task Framing目的是明确问题范围限制 LLM 的推理方向。由此可见提示词的作用本质上都是在向 LLM 注入用于影响其行为模式的额外上下文信息。尽管学习提示词的使用技巧可以在一定程度上提高任务完成质量。但它们终归只是一种“软控制”手段并非系统层面的强约束。换言之无论我们如何编写提示词它们都免不了会具有以下三个典型特征。不确定性相同的提示词在不同时间、不同上下文长度、甚至不同模型版本下都可能产生差异结果。提示词并不能保证稳定行为。非隔离性多轮对话中的历史信息可能影响当前输出规则之间也可能互相干扰。提示词并不具备真正的“作用域隔离”。不可验证性提示词很难像代码一样做单元测试。一次微小改动可能影响多个场景而这种影响往往难以预判。因此当问题涉及到针对 Agent 应用的“能力扩展”时我们需要做的就不再仅仅是“写好提示词”那么简单了。因为提示词虽然可以很好地引导 LLM 的推理路径、规范其输出格式并优化文本的表达质量从而在一定程度上提升任务的成功率但对于面向生产环境的具体应用以下能力是提示词无法提供的调用外部的服务/工具因为这需要独立于 LLM 之外的代码执行环境以及相关的程序逻辑支持管理应用的执行状态因为这需要执行面向数据库管理系统、文件管理系统的增删改查操作保证行为逻辑的可复用因为即使是相同的提示词它在不同时空条件下会产生不同的结果除了能力层面的限制之外提示词还存在着工程与经济层面的约束它给 LLM 带来的计算成本在一定程度上也会成为 Agent 应用的另一种能力边界。毕竟如今的主流 LLM 服务提供商例如 OpenAI、Google、Anthropic 等公司都是以 Token 为单位来进行计费的。众所周知用户与 LLM 的每次对话都会产生一定数量的 Token 消耗越复杂的对话消耗的 Token 数量就越多。因此当我们在对话中叠加越来越多的提示词时免不了会导致系统成本的大幅上升。在个人使用场景中这个成本或许还尚可承受一旦进入到具体的生产环境中问题就会迅速被放大它主要体现在以下四个方面。版本管理困难提示词通常以自然语言形式存在缺乏清晰的版本结构很难精确追踪到具体的变更行为回归问题一次看似微小的改动可能导致多个下游场景输出变化而这些变化难以预估可读性下降当规则不断叠加时提示词会逐渐演变成“规则堆砌文本”。新成员难以理解设计意图知识隐性化大量设计经验隐藏在自然语言中无法结构化复用也无法模块化组合。这意味着如果我们在实际生产环境中不可避免地需要高频调用 LLM那么其“臃肿的系统提示词”无疑就会成为长期的成本负担这将大大限制 Agent 应用的能力扩展空间。也正是在这样的背景下业界才会一直持续不断地寻求在更高层次上对 Agent 应用的能力体系展开进一步的探索这探索的结果中就包括了由 Anthropic 公司提出的 MCP 服务与 Skills 机制它们也正是我们接下来要讨论的重点。如果读者想更详细地了解提示词与上下文工程在 Agent 应用中的工作原理也可以参考本文在“参考资料”一节中提供的视频教程《关于提示词与上下文工程的科普》。MCP 服务MCP即 Model Context Protocol中文可翻译为“模型上下文协议”是由 Anthropic 公司提出并推广的一种用于连接 LLM 与外部服务/工具的通信协议它的设计目标是寻求在 Agent 应用的底层架构上解决以下三个问题工具接入的标准化问题在 MCP 出现之前每一个 LLM 平台都需要自行定义工具调用方式例如 OpenAI 所推出的 function calling 机制Agent 应用的开发者们往往需要针对不同 LLM 重复编写适配逻辑。现在MCP 让这些工具能以统一协议的形式被 LLM 调用了这显然有助于 Agent 应用与 LLM 的耦合度。跨平台复用问题如果工具能以统一协议的形式被 LLM 调用而非绑定在某一个 API 上那么理论上它就可以被不同的 LLM 实例调用这有助于提高 Agent 应用的可移植性。安全边界与能力隔离问题LLM 本身并不直接拥有执行权限想要发挥其执行功能往往需要通过操作系统进行精确地授权这类授权通常都存在着一定的误操作风险。有了 MCP 协议之后我们就可以轻松地让它在被授权的范围内调用外部服务/工具。这种“能力显式声明”的方式有助于建立清晰的安全边界。总而言之该协议的最大作用是为 LLM 与其要调用的外部工具建立通信桥梁Agent 应用通常会基于该协议接入用于连接特定工具的中间件来构建这样的桥梁从而实现“能力扩展”。在专业术语中这样的中间件被称为“MCP 服务MCP Server”。那么在实际生产环境中我们该如何使用 MCP 服务呢MCP 服务的接入与使用为了让读者对 MCP 服务能有一个更直观的认识我接下来将继续以 OpenCode 这个 Agent 应用为例里具体演示一下 MCP 服务在 Agent 应用中的接入与使用方法。一般来说当我们决定在 Agent 应用中接入一个 MCP 服务时需要完成以下三个配置步骤。根据要调用的外部服务/工具找到要接入的 MCP 服务这一步骤可以通过搜索 MCP 服务列表来完成。例如如果我们想在 Agent 应用中调用网页浏览器那么就可以到以下几个目前比较常用的 MCP 服务列表网站中搜索“浏览器自动化”这样的关键字这些网站通常都会返回chrome-devtools-mcp、playwright这些 MCP 服务。Anthropic MCP DirectoryAnthropic 官方提供的 MCP 服务列表。Awesome MCP Servers这是一个按照经典的Awesome系列风格来组织的 MCP 服务列表目前在 Github 上很受欢迎。MCP.so这是目前全球最大的 MCP 资源聚合平台现已收录超过 8000 个 MCP 服务并且还在不断更新中。魔塔社区的 MCP 广场由魔塔社区维护的中文 MCP 服务列表收录了 1000 个 MCP 服务。选择要接入 MCP 服务并查阅其说明文档目前主要的 MCP 服务都会提供详尽的说明文档其中会包含它们的各种接入参数以及面向各种 Agent 应用的配置方法。例如playwright这个 MCP 服务的说明文档如图 1 所示。图 1playwright 的说明文档根据 MCP 服务的说明文档来完成接入配置这一步骤需要我们根据 Agent 应用的官方文档将 MCP 服务的接入参数填写到相应的配置文件中。例如在 OpenCode 中我们可以通过在其配置文件即opencode.json文件中添加如下内容来接入playwright这个 MCP 服务。{mcp: {playwright: {type: local,command: [npx,-y,playwright/mcplatest]}}}根据 OpenCode 的官方文档MCP 服务的配置信息需要被放置在mcp字段下每一个 MCP 服务都需要以一个唯一的名称例如playwright来进行配置其配置方式主要分为本地接入与远程接入两种类型具体如下远程接入在这种配置类型下MCP 服务的配置参数主要包含type、url、enabled等字段。其中type字段的值应固定为remote而url字段用于指定该 MCP 服务所在的地址enabled字段用于指定是否启用该服务。例如以下是远程接入jira这个 MCP 服务的官方示例{$schema: https://opencode.ai/config.json,mcp: {jira: {type: remote,url: https://jira.example.com/mcp,enabled: true}}}本地接入在这种配置类型下MCP 服务的配置参数主要包含type、command、environment、enabled等字段。其中type字段的值应固定为local而command字段用于指定该 MCP 服务的启动命令及其参数environment字段用于指定启动该服务所需设置的环境变量enabled字段用于指定是否启用该服务。例如以下是本地接入github这个 MCP 服务的示例{$schema: https://opencode.ai/config.json,mcp: {github: {type: local,command: [npx,-y,modelcontextprotocol/server-github],environment: {// 此处的 token 需要用户自行前往 GitHub 获取GITHUB_PERSONAL_ACCESS_TOKEN: your github personal access token},enabled: true}}}目前的 MCP 服务主要有 NPM 和 UV 两种打包方式所以它们的启动命令通常是npx或uvx。例如之前配置的playwright这个 MCP 服务的启动命令是npx -y playwright/mcplatest而fetch这个用于抓取网页信息的 MCP 服务的启动命令就是uvx mcp-server-fetch了。在完成了上述配置之后我们只需在 OpenCode TUI 中执行/mcps命令就可以看到所有已配置的 MCP 服务并管理它们的接入状态了如图 2 所示。图 2在 OpenCode TUI 中确认 MCP 服务的接入状态在确认playwright这个 MCP 服务已成功接入之后我们就可以试着在 OpenCode TUI 中使用提示词让它去调用网页浏览器打开 Twitter/X并发一个测试推文来检查这个 MCP 服务的功能是否可用了如图 3 所示。图 3试用 playwright 服务接入 MCP 服务的成本与风险在计算机的世界中任何针对应用程序的能力扩展都会引入新的复杂度。MCP 服务也不例外。在实际生产环境中它至少带来三类新的成本部署复杂度提升接入 MCP 服务意味着我们所使用的 Agent 应用已从简单的“LLM 提示词”结构变成了“LLM MCP 外部服务/工具”的复杂结构这无疑会增加应用的部署与维护难度。安全风险扩大一旦 LLM 具备了调用外部能力的通道我们就必须开始考虑系统权限的管理、输入校验与调用审计。否则 LLM 输出的错误判断很可能会被转化为真实的程序执行风险。依赖管理问题外部服务/工具的可用性、版本变更以及接口兼容性等因素都会直接影响到 Agent 应用的稳定性。能力扩展的同时也意味着更多外部依赖。因此对于 Agent 应用来说MCP 服务从来都不是“多多益善”的能力增强工具它们只应被用于那些确实有必要使用外部工具的应用场景。如果仅仅是文本生成与结构化输出过早在 Agent 应用中引入 MCP 服务反而会造成不必要的资源浪费用户应根据自己的实际需求来决定启用哪些 MCP 服务。为了解决这个问题我们通常会分以下两个作用域的配置文件来管理 MCP 服务。系统级配置文件该文件的存储路径通常为~/.config/opencode/opencode.json我们在其中配置的 MCP 服务往往是所有应用场景都会用到的通用服务例如playwright、fetch等项目级配置文件该文件的存储路径通常为项目根目录/.opencode/opencode.json我们在其中配置的 MCP 服务往往是针对特定项目或应用场景的专用工具例如用于操作数据库的MongoDB或者用于 WebUI 设计的figma等。如果从能力体系的层次来看MCP 服务属于“能力接入层”。它解决的是 LLM 的外部调用能力而提示词则是用于控制 LLM 的单次推理行为与输出表现的。二者并不冲突但也不在同一层级。理解这一点才能避免将 MCP 误解为一种“高级提示词技巧”从而在架构设计上做出错误决策。

更多文章