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

Agent 的能力体系

提示词及其能力边界

在将 Agent 具体应用到实际的生产环境中之前,人们首先需要弄清楚的是:提示词在这类应用中的作用到底是什么?它的能力边界在哪里?如果我们在这两个问题上的理解出现了偏差,那么后续所有针对 Agent 应用的能力扩展都会被错误地理解为是一种更高级的提示词技巧。

考虑到 LLM 的核心训练机制是在高维参数空间中寻找一个在给定数据分布上表现足够好的函数近似,它的具体推理过程永远都是在根据某一概率分布来输出下一个文本单元(在专业术语中,我们称之为“Token”,关于这个单位的具体计算方法,读者可参考我稍后在“参考资料”一节中所提供的视频教程:《关于 Token 的科普》)。换言之,LLM 并不是一个基于显式规则或程序控制流的命令执行系统,因此当我们向 LLM 提供一个提示词时,需要记得自己并非是在对它下“命令”,而是在为其提供符合当前环境需求的上下文信息,以便影响它输出的概率分布。这就意味着:

提示词调整的是 LLM 输出的概率倾向,它无法改变 LLM 的能力边界。

举个例子,当我们在 Agent 应用中输入并提交如下语句作为提示词时,它们的功能分别是:

  • “你是一名专业的法律顾问”:用于角色塑造(Persona),目的是影响语气、知识调用倾向与表达方式。
  • “请以 JSON 格式输出”:用于输出约束(Format Constraints),目的是规范结果结构,提高可读性与可解析性。
  • “请分步骤推理”:用于任务定义(Task Framing),目的是明确问题范围,限制 LLM 的推理方向。

由此可见,提示词的作用本质上都是在向 LLM 注入用于影响其行为模式的额外上下文信息。尽管学习提示词的使用技巧可以在一定程度上提高任务完成质量。但它们终归只是一种“软控制”手段,并非系统层面的强约束。换言之,无论我们如何编写提示词,它们都免不了会具有以下三个典型特征。

  1. 不确定性:相同的提示词,在不同时间、不同上下文长度、甚至不同模型版本下,都可能产生差异结果。提示词并不能保证稳定行为。
  2. 非隔离性:多轮对话中的历史信息可能影响当前输出;规则之间也可能互相干扰。提示词并不具备真正的“作用域隔离”。
  3. 不可验证性:提示词很难像代码一样做单元测试。一次微小改动,可能影响多个场景;而这种影响往往难以预判。

因此,当问题涉及到针对 Agent 应用的“能力扩展”时,我们需要做的就不再仅仅是“写好提示词”那么简单了。因为提示词虽然可以很好地引导 LLM 的推理路径、规范其输出格式并优化文本的表达质量,从而在一定程度上提升任务的成功率,但对于面向生产环境的具体应用,以下能力是提示词无法提供的:

  • 调用外部的服务/工具:因为这需要独立于 LLM 之外的代码执行环境,以及相关的程序逻辑支持;
  • 管理应用的执行状态:因为这需要执行面向数据库管理系统、文件管理系统的增删改查操作;
  • 保证行为逻辑的可复用:因为即使是相同的提示词,它在不同时空条件下会产生不同的结果;

除了能力层面的限制之外,提示词还存在着工程与经济层面的约束,它给 LLM 带来的计算成本在一定程度上也会成为 Agent 应用的另一种能力边界。毕竟,如今的主流 LLM 服务提供商(例如 OpenAI、Google、Anthropic 等公司)都是以 Token 为单位来进行计费的。众所周知,用户与 LLM 的每次对话,都会产生一定数量的 Token 消耗,越复杂的对话消耗的 Token 数量就越多。因此,当我们在对话中叠加越来越多的提示词时,免不了会导致系统成本的大幅上升。在个人使用场景中,这个成本或许还尚可承受,一旦进入到具体的生产环境中,问题就会迅速被放大,它主要体现在以下四个方面。

  1. 版本管理困难:提示词通常以自然语言形式存在,缺乏清晰的版本结构,很难精确追踪到具体的变更;
  2. 行为回归问题:一次看似微小的改动,可能导致多个下游场景输出变化,而这些变化难以预估;
  3. 可读性下降:当规则不断叠加时,提示词会逐渐演变成“规则堆砌文本”。新成员难以理解设计意图;
  4. 知识隐性化:大量设计经验隐藏在自然语言中,无法结构化复用,也无法模块化组合。

这意味着:如果我们在实际生产环境中不可避免地需要高频调用 LLM,那么其“臃肿的系统提示词”无疑就会成为长期的成本负担,这将大大限制 Agent 应用的能力扩展空间。也正是在这样的背景下,业界才会一直持续不断地寻求在更高层次上对 Agent 应用的能力体系展开进一步的探索,这探索的结果中就包括了由 Anthropic 公司提出的 MCP 服务与 Skills 机制,它们也正是我们接下来要讨论的重点。

如果读者想更详细地了解提示词与上下文工程在 Agent 应用中的工作原理,也可以参考本文在“参考资料”一节中提供的视频教程:《关于提示词与上下文工程的科普》。

MCP 服务

MCP(即 Model Context Protocol,中文可翻译为“模型上下文协议”)是由 Anthropic 公司提出并推广的,一种用于连接 LLM 与外部服务/工具的通信协议,它的设计目标是寻求在 Agent 应用的底层架构上解决以下三个问题:

  1. 工具接入的标准化问题:在 MCP 出现之前,每一个 LLM 平台都需要自行定义工具调用方式(例如 OpenAI 所推出的 function calling 机制),Agent 应用的开发者们往往需要针对不同 LLM 重复编写适配逻辑。现在,MCP 让这些工具能以统一协议的形式被 LLM 调用了,这显然有助于 Agent 应用与 LLM 的耦合度。

  2. 跨平台复用问题:如果工具能以统一协议的形式被 LLM 调用,而非绑定在某一个 API 上,那么理论上它就可以被不同的 LLM 实例调用,这有助于提高 Agent 应用的可移植性。

  3. 安全边界与能力隔离问题:LLM 本身并不直接拥有执行权限,想要发挥其执行功能往往需要通过操作系统进行精确地授权,这类授权通常都存在着一定的误操作风险。有了 MCP 协议之后,我们就可以轻松地让它在被授权的范围内调用外部服务/工具。这种“能力显式声明”的方式,有助于建立清晰的安全边界。

总而言之,该协议的最大作用是为 LLM 与其要调用的外部工具建立通信桥梁,Agent 应用通常会基于该协议接入用于连接特定工具的中间件来构建这样的桥梁,从而实现“能力扩展”。在专业术语中,这样的中间件被称为“MCP 服务(MCP Server)”。那么在实际生产环境中,我们该如何使用 MCP 服务呢?

MCP 服务的接入与使用

为了让读者对 MCP 服务能有一个更直观的认识,我接下来将继续以 OpenCode 这个 Agent 应用为例,里具体演示一下 MCP 服务在 Agent 应用中的接入与使用方法。一般来说,当我们决定在 Agent 应用中接入一个 MCP 服务时,需要完成以下三个配置步骤。

  1. 根据要调用的外部服务/工具找到要接入的 MCP 服务:这一步骤可以通过搜索 MCP 服务列表来完成。例如,如果我们想在 Agent 应用中调用网页浏览器,那么就可以到以下几个目前比较常用的 MCP 服务列表网站中搜索“浏览器自动化”这样的关键字,这些网站通常都会返回chrome-devtools-mcpplaywright这些 MCP 服务。

    • Anthropic MCP Directory:Anthropic 官方提供的 MCP 服务列表。
    • Awesome MCP Servers:这是一个按照经典的"Awesome"系列风格来组织的 MCP 服务列表,目前在 Github 上很受欢迎。
    • MCP.so:这是目前全球最大的 MCP 资源聚合平台,现已收录超过 8000+ 个 MCP 服务,并且还在不断更新中。
    • 魔塔社区的 MCP 广场:由魔塔社区维护的中文 MCP 服务列表,收录了 1000+ 个 MCP 服务。
  2. 选择要接入 MCP 服务并查阅其说明文档:目前主要的 MCP 服务都会提供详尽的说明文档,其中会包含它们的各种接入参数,以及面向各种 Agent 应用的配置方法。例如,playwright这个 MCP 服务的说明文档如图 1 所示。

    图 1:playwright 的说明文档

  3. 根据 MCP 服务的说明文档来完成接入配置:这一步骤需要我们根据 Agent 应用的官方文档将 MCP 服务的接入参数填写到相应的配置文件中。例如在 OpenCode 中,我们可以通过在其配置文件(即opencode.json文件)中添加如下内容来接入playwright这个 MCP 服务。

    {
    "mcp": {
    "playwright": {
    "type": "local",
    "command": [
    "npx",
    "-y",
    "@playwright/mcp@latest"
    ]
    }
    }
    }

根据 OpenCode 的官方文档,MCP 服务的配置信息需要被放置在mcp字段下,每一个 MCP 服务都需要以一个唯一的名称(例如playwright)来进行配置,其配置方式主要分为本地接入与远程接入两种类型,具体如下:

  • 远程接入:在这种配置类型下,MCP 服务的配置参数主要包含typeurlenabled等字段。其中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 服务的配置参数主要包含typecommandenvironmentenabled等字段。其中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 两种打包方式,所以它们的启动命令通常是npxuvx。例如,之前配置的playwright这个 MCP 服务的启动命令是npx -y @playwright/mcp@latest,而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 服务也不例外。在实际生产环境中,它至少带来三类新的成本:

  1. 部署复杂度提升:接入 MCP 服务意味着我们所使用的 Agent 应用已从简单的“LLM + 提示词”结构,变成了“LLM + MCP + 外部服务/工具”的复杂结构,这无疑会增加应用的部署与维护难度。

  2. 安全风险扩大:一旦 LLM 具备了调用外部能力的通道,我们就必须开始考虑系统权限的管理、输入校验与调用审计。否则 LLM 输出的错误判断很可能会被转化为真实的程序执行风险。

  3. 依赖管理问题:外部服务/工具的可用性、版本变更以及接口兼容性等因素,都会直接影响到 Agent 应用的稳定性。能力扩展的同时,也意味着更多外部依赖。

因此,对于 Agent 应用来说,MCP 服务从来都不是“多多益善”的能力增强工具,它们只应被用于那些确实有必要使用外部工具的应用场景。如果仅仅是文本生成与结构化输出,过早在 Agent 应用中引入 MCP 服务反而会造成不必要的资源浪费,用户应根据自己的实际需求来决定启用哪些 MCP 服务。为了解决这个问题,我们通常会分以下两个作用域的配置文件来管理 MCP 服务。

  • 系统级配置文件:该文件的存储路径通常为~/.config/opencode/opencode.json,我们在其中配置的 MCP 服务往往是所有应用场景都会用到的通用服务,例如playwrightfetch等;

  • 项目级配置文件:该文件的存储路径通常为<项目根目录>/.opencode/opencode.json,我们在其中配置的 MCP 服务往往是针对特定项目或应用场景的专用工具,例如用于操作数据库的MongoDB,或者用于 WebUI 设计的figma等。

如果从能力体系的层次来看,MCP 服务属于“能力接入层”。它解决的是 LLM 的外部调用能力,而提示词则是用于控制 LLM 的单次推理行为与输出表现的。二者并不冲突,但也不在同一层级。理解这一点,才能避免将 MCP 误解为一种“高级提示词技巧”,从而在架构设计上做出错误决策。

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

相关文章:

  • 从代码混淆到动态加载——构建Android多层次反编译防护体系
  • 嵌入式裸机编程内存管理优化实践
  • TLT库:面向Arduino的Telit ME310G1蜂窝通信轻量级C++ SDK
  • CLion开发STM32:环境配置与高效调试指南
  • ROS 机器人开发工程师技术开发指南
  • OpenClaw多任务测试:Qwen3-32B在RTX4090D上的并行处理极限
  • openclaw本地安装包一键安装 集成400+大模型+微信、企业微信、钉钉、飞书图形界面参数,无需复杂配置
  • HJ162 ACM中的AC题
  • 嵌入式开发中的代码静态分析工具与应用
  • 你以为 Android 返回手势就是往右划?太天真了
  • Adafruit GFX图形库:嵌入式显示驱动的分层架构与实践
  • RTOS在嵌入式开发中的核心价值与实战应用
  • 社交娱乐场景下AI智能体开发:技术实现与产品落地
  • ArduCMSIS-DSP:Arduino平台的ARM官方DSP库移植指南
  • PHP的作用域的生命周期的庖丁解牛
  • PCB设计中数字地与模拟地的区分与处理技巧
  • RT-Thread环境搭建与内核开发实战指南
  • 大模型推理凭什么这么贵?从GRPO到BCR,推理效率之战全解析
  • Linux内核中的eBPF技术详解
  • DLP投影系统驱动开发与优化技术详解
  • 富士通再向英国子公司注资8000万英镑 邮政丑闻后遗症持续
  • ButtonGestures:单按钮六态手势识别嵌入式实现
  • Linux内核中的cgroups v2资源管理技术
  • Linux下C程序编译过程详解与GCC工具链使用
  • 2026年金堂护栏定制实力品牌深度测评与选购指南 - 2026年企业推荐榜
  • systemctl start mysqld的生命周期的庖丁解牛
  • Matrix Laser Sensor I²C嵌入式驱动开发与工业测距实践
  • OpenClaw语音控制之使用 Vosk 实现离线语音控制
  • Arduino/ESP32轻量级协作式任务调度库
  • C语言函数指针原理与嵌入式开发实践