
Agent 为什么会“说查到了”却没有真正查询从工具调用到执行结果理解 Function Calling开发 AI 智能应用时经常会遇到这样的需求用户输入订单号让智能体查询订单状态并用自然语言解释结果。如果只是把需求写进提示词你是一个订单助手请根据用户提供的订单号查询订单状态。模型并不会因此自动获得数据库访问能力。更麻烦的是如果系统没有正确接入工具模型仍可能生成一段看起来完整的回答例如“订单已经发货”。因此开发 Agent 时首先需要区分模型提出工具调用请求与业务系统真正完成操作是两件不同的事。一、工具调用的完整过程是什么以订单查询为例一个基本流程如下用户提出问题 ↓ 模型选择查询工具并生成参数 ↓ 应用校验工具名称、参数和访问权限 ↓ 应用执行查询 ↓ 将查询结果返回模型 ↓ 模型生成用户可读的回答模型通常负责决定“调用什么、传什么参数”应用负责真正执行工具并提供结果。以 Claude 的客户端工具调用为例模型返回tool_use应用执行工具后再通过对应的tool_result提交结果。官方工具调用说明不同模型平台的字段和消息结构可能不同但执行职责需要明确。二、先定义工具的输入约束假设订单号格式为ORD-加六位数字ORD-100001可以使用 Pydantic 2.x 定义输入模型from pydantic import BaseModel, ConfigDict, Field class OrderQueryArgs(BaseModel): model_config ConfigDict( strictTrue, extraforbid, ) order_id: str Field( patternr^ORD-[0-9]{6}$ )这里有三层约束order_id必须是字符串。格式必须符合订单号规则。不允许传入未声明的额外字段。严格模式可以减少隐式类型转换extraforbid则用于拒绝额外字段。具体行为见 Pydantic 严格模式和配置文档。还可以生成 JSON Schema用于模型平台的工具定义schema OrderQueryArgs.model_json_schema()实际接入时要根据平台支持的 Schema 范围进行适配。给模型提供 Schema并不能替代服务端校验。三、实现一个可控的工具执行入口下面使用内存数据模拟订单查询不依赖真实数据库from pydantic import ValidationError ORDERS { ORD-100001: { owner_id: user_01, status: shipped, }, ORD-100002: { owner_id: user_02, status: paid, }, } def execute_tool( tool_name: str, raw_args: dict, current_user_id: str, ) - dict: if tool_name ! query_order: return { ok: False, code: UNKNOWN_TOOL, } try: args OrderQueryArgs.model_validate(raw_args) except ValidationError: return { ok: False, code: INVALID_ARGUMENTS, message: order_id 必须符合 ORD-六位数字的格式, } order ORDERS.get(args.order_id) if order is None or order[owner_id] ! current_user_id: return { ok: False, code: NOT_FOUND_OR_FORBIDDEN, message: 订单不存在或当前用户无权访问, } return { ok: True, data: { order_id: args.order_id, status: order[status], }, }调用示例result execute_tool( tool_namequery_order, raw_args{order_id: ORD-100001}, current_user_iduser_01, ) print(result)预期结果{ ok: True, data: { order_id: ORD-100001, status: shipped } }注意current_user_id应来自后端已经验证的登录会话不能直接相信模型生成的用户身份。四、参数合法为什么还不能直接执行因为格式正确与业务允许是两个层面。下面的参数完全符合订单号格式{ order_id: ORD-100002 }但对于user_01这是一笔不属于他的订单。因此执行层至少要区分三类检查检查层次需要回答的问题结构校验字段和类型是否正确业务校验订单是否存在状态是否允许当前操作权限校验当前用户是否能够访问或修改它模型可以帮助理解用户意图但权限判断应由业务系统完成。五、工具失败后不能当成正常结果继续总结假设查询接口超时工具结果是{ ok: false, code: UPSTREAM_TIMEOUT, message: 订单服务暂时没有响应, retryable: true }此时 Agent 应说明暂时无法确认订单状态或者按照程序规定进行有限重试。不能把“没有查到结果”推断为订单尚未发货。没有获得事实不等于获得了否定事实。实际接入模型 API 时还应把工具调用 ID 与结果正确关联并按平台要求表示工具错误避免多个查询结果互相串用。六、为什么还需要限制调用次数模型可能因为参数错误或工具返回不明确连续调用同一个工具。因此执行循环需要设置最大工具调用次数。整体任务超时。单次工具超时。可重试错误范围。重复无效调用的停止条件。查询工具可以按策略重试创建订单、发送消息等写操作还需要考虑重复执行和幂等性。不能因为模型再次提出调用就默认再次执行一定合理。七、如何验证这个 Agent 是否可靠可以建立以下测试用例输入场景预期行为合法订单号且属于当前用户返回真实状态订单号格式错误校验失败不查询订单属于其他用户不返回订单详情工具名称不存在拒绝执行查询服务超时不编造订单状态连续生成错误参数达到限制后停止除了检查最后的回答还应记录模型请求了什么工具 实际执行了什么工具 使用了哪些参数 工具返回了什么 最终回答引用了什么结果八、面试时怎样解释 Function Calling可以这样回答Function Calling 让模型以结构化方式提出工具调用请求。真正的参数校验、权限检查和业务执行由应用完成执行结果再返回模型。我会重点检查工具结果关联、失败处理和调用预算。对于修改外部状态的工具还要设计幂等和必要的确认流程。