KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
04. Registry 和 Executor 怎样形成白名单? — keel 龙骨
模型返回的工具名是不可信输入。程序不能按字符串寻找任意函数,只能从已经注册的能力中选择。
模型返回的工具名是不可信输入。程序不能按字符串寻找任意函数,只能从已经注册的能力中选择。
Registry 保存的是什么
name
description
version
effect
arguments_model
result_model
handler
handler 是实现,其他字段决定它怎样被描述、校验、授权和观察。Registry 同时是模型可见工具和执行器允许工具的来源,避免两边漂移。
Executor 的固定顺序
flowchart TD
A[ToolCall] --> B{注册?}
B -->|否| C[unknown_tool]
B -->|是| D[输入 schema]
D -->|失败| E[invalid_arguments]
D -->|通过| F[业务与权限策略]
F -->|拒绝| G[policy_denied/approval_required]
F -->|允许| H[调用 handler]
H --> I{业务成功?}
I -->|否| J[结构化 ToolError]
I -->|是| K[输出 schema]
K -->|失败| L[invalid_tool_output]
K -->|通过| M[ToolResult ok=true]
所有检查发生在模型之外。模型不能跳过注册、校验或权限。
运行确定性拒绝实验
python courses/foundation/tool-calling/course/project/examples/02_validated_dispatch.py
依次观察:
- 合法查询返回结构化结果;
- 未知名称被 Registry 拒绝;
- 错误事件编号被输入 schema 拒绝;
- 写工具没有审批记录时返回
approval_required; - handler 返回缺字段时被输出 schema 拒绝。
这些测试不需要 Ollama,因为白名单和校验是程序不变量。
为什么不让函数自己处理所有错误
如果先执行 function(**arguments),再等函数崩溃,你无法稳定区分协议错误、业务错误和实现异常。Executor 应把预期领域错误转成稳定的 ToolError,把未预期异常转为内部错误并将堆栈留在受保护日志中。
本章自测
输入值格式正确但用户无权访问,应该在哪一步拒绝?不是 schema,而是策略。工具名称不存在,应该在哪一步拒绝?不是 handler,而是 Registry。