Agent 工具调用前,先校验参数与授权
文章将工具调用划分为可执行、需澄清和无法继续三种状态,要求在修改外部状态前检查必填参数与授权。素材以日程安排为例,展示使用 Pydantic 建模和校验参数的思路。
AI 深度解读
AI Agent 接到「明天和 Alex 开个会」,能识别意图,还不代表可以立刻调用日历工具。开始时间、会议时长、使用哪个日历,以及 Alex 的联系方式,都可能没有确定。模型一旦替用户补齐这些空白,就可能把一句模糊请求变成一次错误操作。
作者给出的结论是:执行会改变外部状态的操作前,先校验参数,再判断能否从已授权的上下文补齐,必要时向用户提问。文章提供了一套清晰的执行流程,但没有给出量化测试结果,更适合当作设计参考。
参数齐全,为什么还不一定能执行
作者把工具调用前的判断分成三种情况:
- 可以执行:必填参数已经齐全,而且操作获得授权。
- 需要澄清:执行所需的信息缺失,或者存在歧义。
- 无法继续:请求无效、不受支持,或者没有授权。
这三个分支解决的是不同问题。「缺少会议开始时间」可以通过提问补齐;「用户无权使用这个日历」则不能靠补参数解决。
参数完整和操作获准,是两个独立条件。
文章开头列出了时间、时长、日历和联系人等潜在缺项,后面的代码却只要求 participant、start、end 三个字段。因此,这只是一个简化模型,并没有覆盖完整的日历预约业务。尤其是 participant 有值,也不能直接证明已经找到了正确的 Alex。
校验器负责发现错误,Agent 负责决定下一步
作者使用 Pydantic 定义 MeetingRequest(BaseModel):participant 是 str,start 和 end 都是 datetime。除了字段要求,还增加了结束时间必须晚于开始时间的检查。
下面这段校验方法用于拦截错误的时间区间,按上下文应放在 MeetingRequest 类中:
@model_validator(mode="after")
def check_time_range(self):
if self.end <= self.start:
raise ValueError("End time must be after start time")
return self
要看的是 self.end <= self.start 这一行:字段存在,并不等于字段组合在业务上成立。
外层的 validate_request(data) 调用 MeetingRequest.model_validate(data)。成功时返回 {"status": "ready", "request": request};捕获 ValidationError 时,返回 status: "needs_review",并通过 exc.errors(include_url=False) 提供错误信息。
这里的 needs_review 还不是最终决策。它既可能对应缺字段,也可能对应时间区间错误,Agent 仍要判断错误能否修复、是否需要用户参与。
校验失败应该触发判断,而不是自动触发工具重试。
例如初始参数是 {"participant": "Alex", "start": null, "end": null},继续向日历 API 发送同样的参数,没有解决任何问题。正确的下一步是询问开始时间和会议时长,再重建请求、重新校验。
少问问题的前提,是知道答案从哪里来
作者也反对逢缺必问。用户如果已经授权默认会议时长,Agent 可以使用这个偏好;可信上下文里如果已经有确定值,也可以取用。
需要区分的是三种来源:已授权的用户偏好、可信上下文中的现有信息,以及模型对未知参数的猜测。前两者可以成为补齐依据,第三种不能悄悄变成确认过的事实。
文章给出的流程是:
用户请求 → 提取参数 → 校验 → 必要时澄清 → 授权 → 执行 → 验证。
这套流程把自然语言理解与外部执行分开,也提醒开发者别把校验成功当成任务完成。即使参数全部通过,API 仍可能超时,日历事件可能被拒绝,也可能更新了错误的外部状态。
因此,执行之后还要验证结果。文章没有说明具体验证机制,也没有展开超时后的恢复策略,这些部分需要实现者继续设计。
我的判断
我认同作者把「是否具备执行条件」放到工具调用之前。对于有写入行为的 Agent,这个判断值得在程序里明确表达。模型可以帮助理解请求、组织澄清问题,确定性的字段约束和时间关系则适合交给校验器。
不过,文章展示的是设计思路,不能当作可靠性已经得到证明的方案。作者称 HEELO 团队通过本地诊断测试,研究过日历参数缺失的失败场景,但没有给出测试规模、成功率、失败率,也没有提供加入澄清步骤前后的对照数据。HEELO 仍在开发中,这部分应视为经验之谈。
JSON Schema、Pydantic 和 LLM 澄清也不必互相替代。前两者适合表达、检查结构约束,LLM 适合把错误转成用户能回答的问题。但文章没有比较这些组合的效果,无法据此判断哪种实现最好。
还有一个边界:示例代码返回 ready,只说明模型校验通过;它没有展示权限检查。因此,业务系统不能把这个状态直接理解成「现在就有权执行」。
能拿来做什么
- 给日历这类写入工具增加独立的参数校验入口,先检查必填字段和业务约束,再进入授权与执行环节;在 Node 服务中也可以沿用这套分工。
- 为日常 AI 编程中的工具失败区分原因。缺少用户信息时发起澄清,请求无效或没有授权时停止,不要把所有错误统一交给模型重试。
- 使用默认值时明确其来源,只复用用户已授权的偏好或可信上下文中的确定信息,不让模型自行决定缺失的会议时间。
- 把执行后的结果核验纳入流程,并在工具返回失败或超时时保留错误处理分支,避免仅凭参数校验通过就向用户报告任务完成。