等级 L4 · 每天 40 分钟 · 场景:做Agent→二、什么时候不该上 Agent,接MCP→五、MCP 是什么

一句话:Agent = 让模型自己决定调什么工具、调几次,直到任务完成。它解决的是「步骤没法提前写死」的问题——如果步骤能写死,那就别用 Agent,用普通代码编排,又快又便宜又好排查。

学习地图

你的问题看哪一节
「Agent 到底是什么」一、Agent 就是一个循环
「我这个需求该不该上 Agent」二、什么时候不该上 Agent
「工具怎么定义」三、工具设计
「跑着跑着上下文爆了」四、上下文与成本失控
「MCP 是什么」五、MCP 是什么

前置:LLM应用开发

一、Agent 就是一个循环

去掉包装,Agent 的核心是十几行:

messages = [{"role": "user", "content": task}]
while True:
    resp = call_model(messages, tools=tools)
    messages.append({"role": "assistant", "content": resp.content})
 
    if resp.stop_reason != "tool_use":
        break                                  # 模型认为做完了
 
    results = []
    for call in resp.tool_calls:               # 可能一次要调多个
        results.append(execute(call))          # 你的代码去执行
    messages.append({"role": "user", "content": results})

三个关键点:

  1. 模型不执行任何东西——它只输出「我要调 search,参数是 X」,真正执行的是你的代码。安全边界完全在你手里。
  2. 循环由结束原因驱动——模型说「不用调工具了」才退出。
  3. 一轮可能要调多个工具——所有工具结果必须放在同一条消息里一次性返回。分成多条返回,会让模型逐渐不再并行调用,把并发退化成串行。

三个必须加的护栏

裸循环上生产会出事,至少加这三样:

护栏不加的后果
最大轮次模型可能反复调同一个工具,无限循环烧钱
总 token 预算单次任务成本不可控
超时一个任务跑几十分钟没人管

工具执行失败时,要把错误作为工具结果返回给模型(标记为错误),让它自己调整——而不是直接抛异常中断循环。模型看到「文件不存在」会换个路径重试,这正是 Agent 的价值。

二、什么时候不该上 Agent

这是本篇最重要的一节。Agent 是最贵、最慢、最难排查的方案,只在确实需要时用。

先看能不能降级

单次调用  →  固定流程编排  →  Agent
(最便宜)                    (最贵)
需求该用
分类、抽取、摘要、翻译单次调用
步骤固定的多步流程(先检索→再总结→再翻译)固定编排(你写代码控制顺序)
步骤取决于中间结果,没法提前写死Agent

「步骤能不能提前写死」是唯一的判据。 能写死就别用 Agent——固定编排更快、更便宜、出问题能精确定位到哪一步。

四个检查项

确实要上 Agent 前,四项都过了再做:

检查项问自己
复杂度任务是否真的多步且无法提前指定?
价值产出值不值这个成本和延迟?(Agent 通常贵一个量级)
可行性模型在这类任务上真的做得了吗?
纠错成本做错了能不能被发现和回滚?

第四项最容易被忽略,也最致命。 Agent 会自主执行多步操作——如果其中有不可逆的(删数据、发消息、付款),一次跑偏就是事故。不可逆操作必须加人工确认,或者干脆不给它这个工具。

三、工具设计

Agent 效果好不好,工具设计的权重比提示词高。

描述要写清楚「什么时候用」

最常见的错误是工具描述只说了功能,没说触发条件

# ❌ 模型不知道该在什么情况下调
{"name": "search_docs", "description": "搜索文档"}
 
# ✅
{"name": "search_docs",
 "description": "搜索内部产品文档。当用户询问产品功能、配置项、"
                "API 用法,或任何你不确定且可能记录在文档里的问题时调用。"
                "返回最相关的 5 个片段及其来源链接。"}

参数也要逐个写说明,包括取值范围和格式。工具描述写得详细是有回报的——它是模型判断的唯一依据。

数量:宁少勿多

工具太多有两个问题:每个工具的定义都占上下文(每次请求都要带上),以及功能相近的工具会让模型选错

  • 十几个以内:直接全部提供
  • 更多:按场景分组,或者用「工具检索」机制按需加载

功能重叠的工具要合并。 与其提供 search_by_titlesearch_by_content 两个,不如一个 searchmode 参数。

粒度:通用 vs 专用

给一个万能的 execute_sql 很灵活,但你的代码只能看到一个 SQL 字符串,没法做细粒度管控。拆成 query_orderquery_user 这类专用工具,灵活性下降但每个都能单独做权限校验、参数校验、审计

判据是需不需要管控:只读的、低风险的可以给通用工具;涉及写入、权限、金额的必须拆成专用工具,在你的代码里卡死。

返回值要精简

工具返回的所有内容都会进上下文,都要付费,而且会挤占后续空间

❌ 返回整个数据库记录(30 个字段,模型只用得上 3 个)
✅ 返回模型需要的字段,长文本先截断并标注「还有 N 条」

四、上下文与成本失控

Agent 最典型的生产问题:跑着跑着上下文就爆了,成本还高得离谱

为什么会爆

每轮循环都在往 messages 里追加内容,而每次请求都要把完整历史重发一遍。10 轮工具调用后,你在为前 9 轮的所有内容重复付费。

三个应对手段:

手段做法适合
裁剪清掉早期的工具结果(保留结论,丢掉原始返回)工具返回体积大的场景
压缩把早期对话摘要成一段长对话
外置中间结果写文件/数据库,上下文里只留引用处理大量数据的任务

第三种最被低估:让 Agent 把中间产物写到文件里,需要时再读回来——上下文里只留一个路径,成本差一个数量级。

成本控制的具体动作

  • 给单个任务设总 token 预算,超了就终止
  • 共享前缀做缓存:系统提示和工具定义在整个循环里不变,正是缓存的理想对象(见 LLM应用开发
  • 别中途改工具列表:工具定义排在上下文最前面,改动会让整个缓存失效
  • 子任务用轻量模型:主循环用强模型做规划,简单子任务分流到便宜模型

可观测:Agent 必须能回放

Agent 出问题时,「它为什么这么干」是最难回答的问题。每一轮都要记录:调了什么工具、参数是什么、返回了什么、token 消耗多少。

没有这份记录,线上 Agent 出错基本无法定位——你只能看到一个奇怪的最终结果,中间十几步全是黑盒。

五、MCP 是什么

MCP(Model Context Protocol)是「模型怎么连接外部工具和数据」的开放协议。

解决的是 M×N 问题:以前每个 AI 应用要对接每个数据源都得写一遍适配;有了统一协议,工具方实现一次 MCP 服务端,所有支持 MCP 的客户端都能用

类比:MCP 之于 AI 工具,约等于 JDBC 之于数据库——统一接口,各家实现驱动。

后端会怎么接触到它

两个方向:

① 用现成的 MCP 服务:给你的 AI 编程工具接上代码仓库、任务系统、监控系统,让它能直接读这些数据。这是最常见的用法,属于 L2 的工具配置。

② 把内部系统包成 MCP 服务:让 AI 能查你们的订单系统、工单系统、内部文档。这是后端可能要干的活

包装内部系统时的三条原则

  1. 只读优先:第一版只暴露查询能力。写操作等你确认整套权限和审计到位了再说。
  2. 权限不能靠模型自觉:认证鉴权必须在 MCP 服务端做,不能指望提示词里写「不要查别人的数据」。模型是不可信输入源
  3. 返回要精简:同工具设计——返回的一切都会进上下文并计费。

什么时候不需要 MCP

如果只是你自己的应用调自己的 LLM,直接定义工具就行,不需要引入 MCP。MCP 的价值在于跨应用复用——你的工具要被多个 AI 客户端使用时才划算。为了「用上新技术」而引入协议层,是纯粹的复杂度。

常见追问

  • Agent 和工作流编排怎么选? 判据只有一条:步骤能不能提前写死。能写死用编排(Airflow、状态机、你自己的代码都行),不能写死才用 Agent。现实中很多号称 Agent 的系统其实是固定流程——那用编排会更好,快、便宜、可排查。

  • 多 Agent 协作靠谱吗? 在特定场景有效(并行处理独立子任务),但成本和复杂度是乘法级上涨:每个 Agent 都要重新建立上下文、要设计通信协议、出问题要跨 Agent 追踪。先把单 Agent 做到位——大多数团队在单 Agent 还没调好时就上多 Agent,结果是又慢又贵又查不出问题。

  • 怎么防止 Agent 干出格的事? 三层防护,缺一不可:工具层(只给它必要的工具,危险操作干脆不提供)、执行层(在你的代码里做权限校验和参数校验,别信模型传的参数)、确认层(不可逆操作要人工确认)。提示词层的约束是最弱的一层——「不要删除数据」挡不住被注入的指令。

  • 工具调用失败了怎么办? 把错误信息作为工具结果返回给模型,让它自己调整——这是 Agent 优于固定编排的地方。但要限制同一工具的连续失败次数,否则它可能反复重试同一个必然失败的操作,把预算烧完。

  • MCP 会成为标准吗? 生态在快速形成,但仍在演进。实际建议:用它来接现成工具是低风险的(用不上换掉就是);把核心内部系统深度绑定到某个协议要谨慎——在你的系统和协议之间留一层,别让协议细节渗进业务代码。这和当年对待任何新中间件的态度一样。

相关