LLM工具调用实战:Function Calling、MCP与Agent三层协同
2026/9/24 21:19:39 网站建设 项目流程

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能力源于两个底层机制的协同:

  1. Token-level constraint decoding:在解码阶段,模型的logits被动态mask。当生成到"arguments": {后,下一个token的候选集被严格限制在"user_id""investment_amount"等key中,而非全词表。这是硬件级优化,不是软件层过滤。

  2. 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_msretry_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_balanceget_exchange_rateinitiate_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
  • [ ]ToolManifestauth_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熔

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询