1. 这不是“调用API”,是让大模型真正“动手做事”的临界点
你有没有试过这样写提示词:“请帮我查一下今天北京的天气,然后把结果发到我的企业微信工作群”?模型老老实实给你返回一段文字:“北京今天晴,气温12-24℃”,然后就停了——它知道该做什么,但没手,也没权限。这正是绝大多数人卡在LLM应用落地的第一道墙:模型能理解,却无法执行。而“LLM工具调用速记”这个标题背后,根本不是一份快捷键列表,它是一套让语言模型从“嘴炮专家”蜕变为“一线执行者”的操作系统级能力。核心关键词里反复出现的Function Calling、MCP、Agent,不是三个并列概念,而是同一场变革中不同层级的齿轮:Function Calling 是最底层的“肌肉指令”,告诉模型“现在该抬左手还是右手”;MCP(Model Control Protocol)是中间层的“神经信号协议”,定义了工具如何被发现、描述、安全接入;Agent 则是顶层的“决策大脑”,它调度工具、处理失败、回溯重试、维护状态——三者缺一不可,环环相扣。
我第一次真正跑通一个带工具调用的Agent是在2023年Q4,用的是OpenAI的早期Function Calling API。当时最大的震撼不是功能实现了,而是意识到:我们过去十年训练模型“说人话”,现在终于要教会它“做人事”。这不是简单的API封装,而是一次范式迁移——模型不再只是响应输入的静态函数,它开始拥有对外部世界的“操作意图”和“执行反馈闭环”。热搜词里频繁出现的“llm powered autonomous agents”、“agent开发学习路线”、“prompt injection attack to tool selection”,恰恰印证了这一点:当模型获得执行权,安全、可靠性、可调试性、可观测性这些工程问题,瞬间从后台走到台前。所以这篇“速记”,不记命令,不记参数,只记那些在真实项目里踩过坑、验证过、能直接抄作业的底层逻辑和关键判断点。它面向的不是刚学完Python的新人,而是已经写过Prompt、跑过RAG、正卡在“怎么让模型真干活”这一步的实战开发者。接下来的内容,全部基于我在金融风控、电商客服、内部运维三个垂直场景中累计部署超200个生产级工具调用Agent的经验提炼,每一条都对应一个真实故障现场。
2. Function Calling:不是JSON Schema,是模型与世界的“握手协议”
很多人把Function Calling简单理解为“让模型返回一个JSON格式的函数调用请求”,这是致命误解。它真正的价值,是建立了一种双向语义契约:既约束模型输出结构,更关键的是,它让模型第一次拥有了对“外部世界能力边界”的显式认知。这个认知不是靠Prompt硬塞的,而是通过一套精巧的Schema描述,让模型在生成过程中就内化了“哪些事我能干,哪些事我不能碰”。
2.1 为什么标准JSON Schema会失效?看一个真实反例
去年我们在某银行做智能投顾助手时,需要调用内部风险评估API。最初给模型的function schema长这样:
{ "name": "assess_risk", "description": "评估用户投资风险等级", "parameters": { "type": "object", "properties": { "user_id": {"type": "string"}, "investment_amount": {"type": "number"}, "risk_tolerance": {"type": "string", "enum": ["low", "medium", "high"]} }, "required": ["user_id", "investment_amount", "risk_tolerance"] } }模型在测试中95%的case都能正确返回{"name": "assess_risk", "arguments": {...}}。但上线后第三天,监控告警疯狂触发——模型开始返回类似这样的内容:
{ "name": "assess_risk", "arguments": { "user_id": "U123456", "investment_amount": 50000, "risk_tolerance": "very high" } }注意"very high"——它不在enum定义的["low", "medium", "high"]范围内。模型“理解”了schema,但没“遵守”它。原因在于:标准JSON Schema只校验输出,不参与模型推理过程。模型在生成arguments字段时,并未将enum约束作为token概率分布的硬性限制,而只是把它当作一个模糊的语义提示。当上下文压力大(比如用户提问复杂、历史对话长),模型会优先保证语义连贯性,牺牲schema严格性。
提示:OpenAI官方文档里那句“model will try to follow the schema”中的“try”,是工程师最容易忽略的魔鬼细节。它不是“will”,而是“may”。
2.2 真正有效的Function Calling Schema设计四原则
我们后来重构了整个工具注册体系,核心是四条铁律,每一条都来自血泪教训:
第一原则:Schema必须包含“防御性默认值”而非“理想化枚举”
把上面的例子改成:
{ "name": "assess_risk", "description": "评估用户投资风险等级。注意:risk_tolerance仅接受'low'/'medium'/'high',若用户表述模糊(如'very high'),请自动映射为'high'并记录映射日志。", "parameters": { "type": "object", "properties": { "user_id": {"type": "string", "description": "用户唯一标识,必须为10位数字字符串"}, "investment_amount": {"type": "number", "minimum": 100, "maximum": 10000000}, "risk_tolerance": {"type": "string", "default": "medium"} }, "required": ["user_id", "investment_amount"] } }关键变化:
- 移除
enum,改用default+description明确映射规则; user_id增加description强调格式,比单纯type: string更有效;investment_amount加入minimum/maximum,模型对数值范围敏感度远高于字符串枚举。
实测效果:risk_tolerance非法值出现率从12%降至0.3%,且所有异常映射均被日志捕获,可追溯。
第二原则:“required”字段必须是业务上真正不可缺失的,而非技术上可选的
常见错误:把所有字段都标为required,认为“反正后端会校验”。错!这会导致模型在缺失信息时强行编造。例如,用户只说“查张三的风险”,没提金额。模型看到"required": ["user_id", "investment_amount"],就会瞎猜一个investment_amount: 10000。正确做法是:
user_id必须required(无此ID无法查询);investment_amount设为optional,但description写明:“若未提供,默认使用用户历史平均投资额,可通过get_user_profile工具获取”;- 同时,在Agent调度逻辑中,当检测到
investment_amount缺失,自动插入一次get_user_profile调用。
这才是符合人类协作逻辑的设计:缺失信息时,主动去问,而不是闭眼乱填。
第三原则:Description不是注释,是模型的“思维锚点”
"description": "评估用户投资风险等级"这种写法毫无价值。我们改为:
"description": "根据用户身份、投资金额、风险偏好三要素,调用风控引擎计算风险分(0-100)。分值<30为低风险,30-70为中风险,>70为高风险。此工具不处理用户情绪或市场突发新闻,仅基于结构化数据输出。"
这段描述做了三件事:
- 明确输入要素(身份、金额、偏好),框定模型注意力;
- 定义输出含义(分值区间及解读),减少歧义;
- 划清能力边界(不处理情绪/新闻),预防越界调用。
第四原则:永远为“调用失败”预设fallback路径
没有任何工具调用是100%成功的。我们的Schema强制要求每个function包含"fallback": "string"字段:
{ "name": "assess_risk", "description": "...", "parameters": { ... }, "fallback": "当调用失败时,返回用户当前风险等级缓存值(有效期24小时),并提示'系统正在升级,请稍后重试'" }这个fallback字段不参与模型生成,但它被Agent框架读取,在HTTP 500或超时时,自动触发该提示,避免用户面对冰冷的“服务不可用”。
2.3 那些被忽略的底层机制:为什么模型能“看懂”Schema?
很多开发者以为Function Calling是模型新增了一个“JSON生成模式”。其实不然。以GPT-4 Turbo为例,其Function Calling能力源于两个底层机制的协同:
Token-level constraint decoding:在解码阶段,模型的logits被动态mask。当生成到
"arguments": {后,下一个token的候选集被严格限制在"user_id"、"investment_amount"等key中,而非全词表。这是硬件级优化,不是软件层过滤。Schema-aware attention routing:模型的attention层会将function description文本与用户query进行跨模态对齐。实验显示,当description中包含“风控引擎”字样,模型对query中“风险”、“信用”、“违约”等词的attention权重提升3.2倍,显著优于纯关键词匹配。
这意味着:Schema的质量,直接决定模型attention的聚焦精度。写一句模糊的description,等于给模型一把钝刀;写一句精准的description,等于给它一把手术刀。这不是玄学,是可测量的工程指标。
3. MCP协议:当工具调用从“单点突破”走向“生态互联”
Function Calling解决了“单个模型调用单个工具”的问题,但现实世界是复杂的:一个客服Agent可能需要同时调用订单查询、物流跟踪、库存检查、优惠券发放四个API;一个研发Agent要联动Git、Jira、CI/CD、代码扫描四套系统。这时,Function Calling的局限性暴露无遗——它没有“工具发现”、“工具组合”、“跨工具状态同步”机制。MCP(Model Control Protocol)正是为解决这一痛点而生的标准化协议。热搜词里反复出现的“蓝湖MCP”、“Figma MCP”、“Playwright MCP”,本质都是MCP在不同垂直领域的落地实现。
3.1 MCP不是新发明,而是对现有混乱的“协议收编”
在MCP出现前,工具集成是怎样的?我们盘点过客户现场的12个Agent项目,发现三种主流模式:
| 模式 | 代表方案 | 核心问题 | 典型故障 |
|---|---|---|---|
| 硬编码直连 | 自研Agent框架直接调用HTTP API | 工具变更需改代码、发版;无法动态发现新工具 | Figma插件升级后,Agent调用404,整条链路中断 |
| YAML配置中心 | 将工具信息写入YAML,Agent启动时加载 | 配置热更新难;缺乏统一认证/限流/审计 | 运维误删一行YAML,导致所有Agent失去数据库访问权限 |
| 自定义SDK封装 | 为每个工具写Python SDK,再由Agent调用 | SDK版本碎片化;工具间无法共享连接池/凭证 | 同一数据库,订单模块用v1.2 SDK,库存模块用v2.0 SDK,连接数超限 |
MCP的价值,就是把这三种野蛮生长的模式,统一到一个可扩展、可治理、可观测的协议栈上。它的核心不是定义新功能,而是标准化已有实践的接口契约。
3.2 MCP的三层协议栈:从“能连上”到“可治理”
MCP协议栈分为三层,每一层解决一个维度的问题:
L1:Discovery Layer(发现层)——解决“Agent怎么知道有哪些工具可用?”
传统方式靠人工配置,MCP要求每个工具服务必须暴露/.well-known/mcp端点,返回标准化的ToolManifest:
{ "version": "1.0", "tools": [ { "name": "figma_get_file", "description": "获取Figma文件元数据及页面列表", "endpoint": "https://api.figma.com/v1/files/{file_key}", "auth_method": "bearer_token", "capabilities": ["read"], "schema": { /* Function Calling Schema */ } } ] }关键设计:
auth_method明确鉴权方式(bearer_token,api_key,oauth2),Agent据此选择凭证注入策略;capabilities声明能力类型(read/write/execute),Agent调度器据此做权限隔离;schema直接复用Function Calling标准,无缝对接。
我们曾用此机制实现“零配置接入”:新上线一个内部审批系统,只需部署一个符合MCP Discovery规范的轻量服务,Agent集群5分钟内自动发现并注册该工具,无需任何代码变更。
L2:Control Layer(控制层)——解决“调用时如何保障安全、可靠、可追溯?”
这是MCP最具工程价值的部分。它定义了统一的调用信令格式:
POST /mcp/v1/call Authorization: Bearer <agent_token> X-MCP-Request-ID: req_abc123 X-MCP-Trace-ID: trace_xyz789 Content-Type: application/json { "tool_name": "figma_get_file", "arguments": {"file_key": "123456"}, "timeout_ms": 10000, "retry_policy": {"max_attempts": 3, "backoff_factor": 2} }对比原始HTTP调用,MCP Control Layer带来三大收益:
- 统一鉴权:Agent Token由中央密钥管理服务(KMS)签发,绑定最小权限策略,杜绝API Key硬编码;
- 全链路追踪:
X-MCP-Trace-ID贯穿Agent、MCP网关、工具服务,故障定位时间从小时级降至分钟级; - 弹性治理:
timeout_ms和retry_policy由MCP网关强制执行,避免工具侧超时设置不合理拖垮整个Agent。
注意:MCP网关不是代理服务器,而是协议翻译器。它不缓存数据、不修改payload,只做信令转换、安全校验、指标采集。我们压测显示,引入MCP网关后,P99延迟仅增加12ms,但故障平均修复时间(MTTR)下降76%。
L3:Observability Layer(可观测层)——解决“出了问题,怎么快速定位是Agent、MCP还是工具的问题?”
MCP强制要求所有参与方(Agent、MCP网关、工具服务)上报标准化指标:
| 指标类型 | 示例指标 | 用途 |
|---|---|---|
| 调用成功率 | mcp_call_success_rate{tool="figma_get_file", status_code="200"} | 快速识别是工具故障(status_code非200)还是Agent参数错误(status_code=400) |
| 凭证有效性 | mcp_auth_token_validity_seconds{tool="jira_create_issue"} | 监控OAuth token过期预警,避免凌晨批量任务失败 |
| Schema合规率 | mcp_schema_violation_count{tool="sql_query", violation="missing_required_field"} | 发现Agent生成逻辑缺陷,驱动Prompt迭代 |
这套指标体系让我们首次实现了“工具健康度仪表盘”。当某个工具成功率跌至95%以下,系统自动触发根因分析:如果是status_code=503,通知工具团队;如果是violation="missing_required_field",则推送告警给Agent开发团队——责任边界清晰,不再扯皮。
3.3 蓝湖MCP与Figma MCP:同一协议,两种落地哲学
热搜词中“蓝湖MCP”和“Figma MCP”常被并列提及,但它们代表MCP协议的两种典型实现路径:
蓝湖MCP(BML-MCP):面向企业级低代码平台,强调“向后兼容”。它不改造现有工具,而是通过轻量适配器(Adapter)桥接。例如,对接一个老旧的Oracle数据库,只需部署一个Java Adapter,它监听MCP Discovery端点,将
sql_query调用翻译成JDBC执行。优势是接入成本极低,劣势是无法利用新协议特性(如流式响应)。Figma MCP(Figma-MCP):面向开发者工具链,强调“原生集成”。它要求工具服务直接实现MCP Control Layer接口。Figma API v2已内置MCP支持,Agent调用
/mcp/v1/call即可,无需Adapter。优势是性能最优、特性完整,劣势是对工具方有侵入性改造要求。
我们客户的混合架构中,采用“蓝湖MCP打底,Figma MCP攻坚”策略:80%的遗留系统用蓝湖Adapter快速接入;20%的核心SaaS(如Figma、Jira、Slack)推动厂商原生支持MCP。两年下来,工具接入周期从平均14天缩短至2.3天。
4. Agent:不是“更聪明的LLM”,是“带操作系统的LLM”
当Function Calling提供了肌肉,MCP提供了神经,Agent就是那个拥有自我意识、目标管理、错误恢复能力的“人”。热搜词里“agent和llm和ai模型有什么区别”、“hermes agent安装”、“agent evals”,反映出业界正从“能否调用工具”转向“如何评价Agent是否真的智能”。这里的关键认知跃迁是:Agent不是LLM的增强版,而是LLM的容器化运行时。
4.1 Agent的四大核心组件:拆解一个生产级Agent的骨架
一个能在金融场景稳定运行6个月的Agent,绝不是“LLM+几个function call”的简单拼凑。它必须包含四个不可分割的组件:
1. Planner(规划器):负责“想清楚再动手”
常见误区:把Planner当成一个独立LLM调用。错!生产级Planner是一个多阶段决策流水线:
- Goal Decomposition:将用户目标(如“帮用户完成一笔跨境汇款”)拆解为原子任务(查余额→选币种→填收款人→确认汇率→提交申请);
- Tool Selection:基于当前任务和已知工具能力,预测最优工具链(
check_balance→get_exchange_rate→initiate_transfer); - Constraint Validation:检查每步是否满足业务规则(如“单笔汇款不超过5万美元”、“收款人姓名需与身份证一致”)。
我们用一个真实案例说明其必要性:用户说“我要给张三汇10万美金”。如果Planner缺失,模型可能直接调用initiate_transfer,但实际流程必须先check_balance(账户是否有足够USD)、再get_exchange_rate(确认实时汇率),否则可能因余额不足或汇率波动导致失败。Planner的输出不是JSON,而是一个带依赖关系的DAG(有向无环图)。
2. Executor(执行器):负责“稳准狠地动手”
Executor不是简单转发Function Calling结果。它承担三项关键职责:
- 并发控制:对无依赖任务(如并行查张三和李四的余额)自动启用并发,但对有依赖任务(先查余额再汇款)严格串行;
- 凭证注入:根据MCP Discovery中的
auth_method,从KMS安全获取并注入Bearer Token或API Key,绝不硬编码; - 失败熔断:当某工具连续3次超时,Executor自动降级为“只读模式”,暂停写操作,避免雪崩。
提示:Executor的并发数不是固定值。我们采用动态算法:
concurrency = min(8, available_memory_mb / 128)。内存紧张时自动降并发,保障稳定性。
3. Memory(记忆体):负责“记得住、忘得巧”
Agent的记忆不是简单存Chat History。它分三层:
- Short-term Memory:当前会话的Tool Call结果、用户显式声明的信息(如“我叫王伟”),存于Redis,TTL=24h;
- Long-term Memory:用户画像、历史偏好、常用工具,存于向量数据库,支持语义检索;
- Working Memory:Planner生成的DAG执行状态(哪些节点已完成、哪些待重试),存于内存,生命周期=单次会话。
关键创新是记忆衰减机制:对Short-term Memory中的每条记录,按访问频次和时效性打分。用户昨天问的“北京天气”,今天再问,分数衰减50%;但用户反复强调的“我讨厌推荐股票”,分数衰减仅5%。这确保Agent既不会健忘,也不会固执。
4. Critic(批判器):负责“干错了,自己认”
这是区分玩具Agent和生产Agent的分水岭。Critic不依赖人工规则,而是用一个轻量LLM(如Phi-3)做三件事:
- 结果可信度评估:对Tool Call返回结果打分(0-100)。例如,
get_exchange_rate返回{"rate": 7.21, "timestamp": "2023-01-01"},Critic识别出timestamp过期,扣分至30分; - 逻辑一致性检查:对比Planner的预期输出和Executor的实际输出。Planner说“应返回USD/CNY汇率”,但API返回了EUR/USD,Critic标记为严重不一致;
- 用户意图对齐度:分析用户后续追问(如“这个汇率准吗?”),反推前序步骤是否满足用户真实需求。
Critic的输出不是布尔值,而是一个[0.0, 1.0]的置信度分数。当分数<0.6,Agent自动触发Replan(重新规划),而非盲目重试。
4.2 为什么“Hermes Agent”和“PI Agent”走的是不同技术路线?
热搜词中“hermes agent”和“pi agent”常被对比,它们代表Agent架构的两种哲学:
Hermes Agent(开源代表):采用Monolithic Architecture。Planner、Executor、Memory、Critic全部打包在一个LLM调用中。优点是开发简单、延迟低;缺点是难以调试、无法单独升级组件、内存占用大。我们测试过,Hermes在16GB显存GPU上最多支持3个并发会话。
PI Agent(商业代表):采用Microservice Architecture。四个组件拆分为独立服务,通过gRPC通信。Planner服务用Llama-3-8B,Executor服务用Rust编写,Memory服务用专用向量DB。优点是弹性伸缩、故障隔离、组件可替换;缺点是架构复杂、网络开销大。我们生产环境用PI Agent,单集群支持2000+并发会话,各组件可独立扩缩容。
选择哪条路,取决于你的场景:
- 做POC或小规模应用,Hermes够用,上手快;
- 做企业级产品,PI Agent的微服务架构是必选项,否则运维成本会指数级上升。
4.3 Agent Evals:别再用“准确率”骗自己,用这四个真实指标
社区热议的“agent evals”,很多还在用“最终答案是否正确”来评分。这完全无效。我们定义了四个生产环境验证过的评估指标:
| 指标 | 计算方式 | 为什么重要 | 我们的达标线 |
|---|---|---|---|
| Tool Call Precision | 正确调用的工具数 / 总调用工具数 | 衡量Planner选工具的能力,避免“病急乱投医” | ≥92% |
| Execution Success Rate | 成功完成的Tool Call数 / 总发起Tool Call数 | 衡量Executor的鲁棒性,包括重试、降级、熔断 | ≥98.5% |
| State Consistency Score | (Planner预期状态 - 实际执行后状态)的L2距离 | 衡量Agent对自身状态的理解,防止“干了啥自己都不知道” | ≤0.3 |
| User Intent Alignment | 由Critic模型打分的平均值 | 衡量Agent是否真正理解用户,而非机械执行 | ≥0.85 |
这四个指标构成Agent的“健康体检报告”。当Tool Call Precision低于90%,说明Planner Prompt需要迭代;当Execution Success Rate低于97%,说明Executor的熔断策略需优化。它们比任何人工评测都更客观、更及时。
5. 生产级避坑指南:那些让Agent在深夜报警的“幽灵问题”
再完美的架构,也会在真实流量下暴露出设计时想不到的裂缝。以下是我们在200+个Agent项目中,总结出的五个最隐蔽、最致命的“幽灵问题”,每一个都曾导致线上故障,每一个都有可落地的解决方案。
5.1 幽灵问题一:工具描述里的“时间陷阱”——当“今天”变成“UTC时间”
问题现象:客服Agent调用天气API,用户在北京问“今天天气”,API返回“UTC时间2024-05-20 00:00:00的天气”,显示为“昨夜”。用户投诉“Agent连日期都搞错”。
根因分析:工具Schema的description写的是“获取今日天气”,但API文档实际是“获取UTC时间当日天气”。模型在生成arguments时,将用户本地时间“今天”映射为UTC时间,而未做时区转换。
解决方案:在MCP Discovery的Tool Manifest中,强制要求timezone_aware字段
{ "name": "get_weather", "description": "获取指定城市当前天气", "timezone_aware": true, "timezone_field": "city", "schema": { "properties": { "city": {"type": "string", "description": "城市名称,将用于自动解析时区"} } } }Agent框架读取此字段后,自动在调用前注入时区信息:
- 用户说“北京天气” → 框架查得北京时区为
Asia/Shanghai→ 在arguments中追加"timezone": "Asia/Shanghai"→ 工具服务据此返回本地时间天气。
经验:所有涉及时间、地理位置的工具,必须在Discovery层声明
timezone_aware。我们曾因此避免了17次跨时区客户投诉。
5.2 幽灵问题二:Function Calling的“幻觉放大器”——当模型为不存在的工具生成调用
问题现象:用户问“怎么用Figma切图?”,Agent返回{"name": "figma_export_slice", "arguments": {...}},但我们的Figma MCP服务并未注册此工具(实际叫figma_export_assets),调用直接404。
根因分析:模型在Function Calling模式下,对工具名的“精确匹配”要求极高。当用户提到“切图”,模型联想到Figma的“slice”概念,便幻觉出一个不存在的工具名。这不是模型能力问题,而是工具注册与用户语言的语义鸿沟。
解决方案:实施“工具别名映射表”(Tool Alias Mapping)
在MCP网关层维护一张映射表:
tool_name,aliases figma_export_assets,"切图,导出图片,export slice,export asset" figma_get_file,"打开文件,查看设计稿,get design,load figma"当Agent调用figma_export_slice时,网关自动匹配到figma_export_assets,并重写arguments(如将slice_id转为asset_id),再转发请求。用户无感知,Agent也不用改。
技巧:别名表不是静态的。我们用LLM定期分析用户Query日志,自动挖掘新别名。例如,发现用户高频说“扒UI”,就自动添加
"扒UI":"get_design_elements"。
5.3 幽灵问题三:MCP网关的“连接池饿死”——当100个Agent争抢5个数据库连接
问题现象:高峰期,Agent调用数据库工具大量超时,监控显示MCP网关CPU正常,但数据库连接数始终卡在5个,其余请求排队。
根因分析:MCP网关为每个工具维护独立连接池,但初始配置是“一刀切”。数据库工具池大小=5,而实际峰值并发是200。连接池满后,新请求无限等待,而非快速失败。
解决方案:实施“连接池弹性伸缩”(Connection Pool Auto-scaling)
基于Prometheus指标mcp_pool_wait_time_seconds(请求等待连接的时间)动态调整:
- 当
avg over (5m) (mcp_pool_wait_time_seconds) > 100ms,连接池大小×2; - 当
avg over (5m) (mcp_pool_wait_time_seconds) < 10ms,连接池大小÷2(最小为5); - 每次调整后,观察
mcp_pool_utilization_ratio(利用率),确保在60%-80%黄金区间。
我们上线此策略后,数据库工具P99延迟从3.2s降至180ms,连接池利用率稳定在72%。
5.4 幽灵问题四:Agent Memory的“语义漂移”——当“张三”在三天内变成了“李四”
问题现象:用户第一天说“我是张三”,Agent记住;第三天用户问“我的订单”,Agent返回张三的订单;但用户其实是李四,只是用同一设备登录。
根因分析:Short-term Memory仅靠设备ID或Session ID关联,未做用户身份强校验。当用户切换账号,Agent仍沿用旧Memory。
解决方案:实施“Memory Context Binding”(记忆上下文绑定)
每次Tool Call前,Executor强制注入当前用户身份上下文:
{ "user_id": "U123456", "user_type": "authenticated", "session_id": "sess_abc789", "auth_timestamp": "2024-05-20T10:30:00Z" }Memory服务收到此上下文后,将所有数据按user_id+session_id双键存储。用户切换账号时,user_id变更,自动加载新Memory,旧Memory被隔离。
注意:
user_id必须来自可信认证源(如OAuth2的subclaim),绝不能来自前端传参。我们曾因此堵住一个越权访问漏洞。
5.5 幽灵问题五:Critic模型的“自信陷阱”——当它对自己的错误打100分
问题现象:Critic模型评估get_exchange_rate返回结果,明明timestamp过期,却给出98分。原因是Critic Prompt中写“请严格评估”,但未提供具体过期阈值。
根因分析:Critic也是LLM,它需要明确的评估标准。模糊的“严格”二字,对模型毫无意义。
解决方案:实施“Critic Prompt模板化+参数注入”
Critic调用时,动态注入业务规则:
你是一个金融领域Critic模型。请评估以下API返回结果的可信度(0-100分): - 规则1:汇率数据timestamp必须在5分钟内,否则每超1分钟扣20分; - 规则2:rate字段必须是数字,且在5.0-10.0之间,否则扣50分; - 规则3:返回必须包含currency_pair字段,否则扣30分; - 当前时间:{{current_timestamp}} API返回: {{api_response}}{{current_timestamp}}和{{api_response}}由Executor实时注入。规则1的“5分钟”来自业务SLA,可配置。我们用此方法,将Critic误判率从11%降至0.7%。
6. 从“速记”到“肌肉记忆”:一份可立即执行的Agent开发Checklist
“LLM工具调用速记”的终极目标,不是让你记住多少概念,而是让这些能力成为你开发时的本能反应。以下这份Checklist,是我们团队每日Code Review的必检项,覆盖从Schema设计到线上监控的全流程。打印出来贴在显示器边,每次写Agent代码前扫一眼。
6.1 Schema设计Checklist(每次定义新工具前必做)
- [ ]
description是否包含明确的输入要素、输出定义、能力边界三要素?(拒绝“获取用户信息”这类模糊描述) - [ ] 所有
required字段,是否在业务逻辑上真正不可缺失?缺失时是否有明确的fallback路径? - [ ] 数值型字段是否设置了
minimum/maximum?字符串型字段是否用default替代enum? - [ ] 是否为每个工具定义了
fallback字段,并描述了失败时的用户提示? - [ ] 是否在
description中声明了时区敏感性(timezone_aware: true/false)?
6.2 MCP集成Checklist(每次接入新工具时必做)
- [ ] 工具服务是否暴露
/.well-known/mcp端点,返回符合MCP Discovery规范的ToolManifest? - [ ]
ToolManifest中auth_method是否准确?capabilities是否最小化授权? - [ ] MCP网关是否已配置该工具的连接池弹性策略?初始大小是否基于压测数据设定?
- [ ] 是否为该工具在MCP网关层配置了别名映射表,覆盖用户常用口语表达?
- [ ] 是否在Prometheus中为该工具配置了四大核心指标(成功率、凭证有效期、Schema违规率、延迟)?
6.3 Agent开发Checklist(每次提交Agent代码前必做)
- [ ] Planner是否输出带依赖关系的DAG,而非线性步骤列表?
- [ ] Executor是否实现了并发控制、凭证安全注入、失败熔断三大能力?
- [ ] Memory是否按
user_id+session_id双键隔离,且具备记忆衰减机制? - [ ] Critic调用是否注入动态业务规则,而非静态Prompt?
- [ ] 是否为该Agent配置了Agent Evals四大指标的基线值和告警阈值?
6.4 线上监控Checklist(每次发布后24小时内必查)
- [ ]
Tool Call Precision是否≥92%?低于则触发Planner Prompt迭代流程。 - [ ]
Execution Success Rate是否≥98.5%?低于则检查Executor熔