先说结论生产环境中的 Function Calling 远不止定义 JSON Schema协议统一、权限边界、执行可观测是三大硬门槛。三层架构service/domain/infra能有效隔离业务逻辑与工具实现但代价是增加了抽象层与维护成本。双重权限过滤与渐进式 skill 披露能显著减少无效 token 消耗但引入意图识别可能增加首次调用的延迟。从踩坑反思的角度拆解生产级工具系统在协议、权限、可观测性的真实取舍与设计代价。先说结论生产级工具系统到底在解决什么很多人对 Function Calling 的理解还停留在“定义 JSON Schema - 大模型调用函数 - 返回数据”的阶段。但在真实生产环境里三件事会立刻让你头疼协议不统一——团队里有人用 Json Schema有人自定义工具定义散乱无法复用。权限边界模糊——大模型可能越权调用不该访问的工具安全风险不可控。执行过程黑盒——用户等了几秒突然出结果中间发生了什么完全不可知。这三点是生产级工具系统必须跨过的门槛。[图片1] 一张对比图左侧是简单 demo 的直调用右侧是生产环境的复杂架构标注协议、权限、可观测三个环节。为什么协议统一是第一道坎自研 vs Json Schema 的取舍原文作者没有直接采用 Json Schema而是仿照它定义了一套轻量协议。理由是 Json Schema“有点重可读性不高”。站在纯技术角度看这个选择可以理解。如果你的系统规模不大团队对 Json Schema 不够熟悉自研一套更简洁的协议能降低心智负担。而且后期可以通过适配层兼容 Json Schema不算死路。但代价也很明显自研协议意味着你必须自行维护解析、校验、序列化逻辑同时第三方工具和库的兼容性会打折扣。如果团队后期需要对接外部系统适配成本会逐步累积。我更倾向于这样判断如果你只是内部工具、团队可控自研没问题但如果需要开放给第三方或长期维护Json Schema 的生态成熟度是更好的起点。三层架构解耦的甜头与维护的代价原文将系统拆分为 service、domain、infra 三层。domain 层定义协议接口包括工具的元数据、入参出参等。这是整个系统的“宪法”。service 层业务编排比如根据用户权限筛选可见工具、组装 prompt。infra 层技术实现比如用 Eino 框架处理工具调用落库用 GORM。这种拆法好处明显权限策略调整只改 service换 AI 框架只改 infra互不干扰。但实际跑起来你可能会遇到一个问题层与层之间的边界容易模糊。尤其是 service 层很容易变成“万能胶水层”既做业务判断又做数据转换逐渐臃肿。另外三层架构增加了代码跳转与调试成本对于小团队来说可能反而拖慢迭代速度。所以三层架构更适合有一定规模、多人协作的项目。如果只是个人项目或 MVP可能一层简单封装更现实。[图片2] 一张架构分层示意图显示 service、domain、infra 之间的依赖关系以及各层的关键职责。权限设计双重过滤真能防越权原文采用了两层权限过滤获取工具列表时——根据用户的 user_id、org_id、角色管理员/普通筛选可见工具只把有权限的 tools 发给大模型。调用具体 tool 时——再次校验权限防止大模型在推理过程中绕开第一层限制。双重过滤的策略在逻辑上确实比单层更安全。但值得注意的是权限数据本身也依赖上层应用的正确传递。如果上游用户身份信息被篡改或遗漏再多的过滤也无用。另外权限粒度需要仔细设计。如果给每个工具都分配独立的 capability后期管理会非常麻烦。原文建议按角色分配 resource capability类似 RBAC 的思路这个方向是对的。性能优化从全量注入到意图识别的进化原文提到了三种优化策略基础无权限用户直接走纯文本跳过 ReAct省 token。渐进式 skill 披露先只暴露工具的基本信息名称、一句话描述等大模型选中后再提供详细参数。意图识别让大模型自己判断需要什么工具然后去“搜索”工具而不是一股脑全塞进去。前两种已经比较成熟代价是增加了开发复杂度。而意图识别虽然激进但它真正解决了“工具数量爆炸”时上下文塞不下的问题。代价也很明显首次调用延迟会增加因为大模型需要多一轮“思考”。如果用户对响应速度敏感这个方案不一定适用。所以一个更现实的策略是根据用户历史行为或业务场景预加载最可能用到的 top K 个工具而不是完全取消全量注入。用户体验让用户看到“AI 在干嘛”比什么都重要很多 AI 应用只关心最终结果忽略了过程的可感知性。原文通过 tool_call_started 和 tool_call_finished 事件让前端实时展示执行进度。此外错误预校验也值得借鉴。如果工具调用参数格式错误允许大模型重试两次但如果是必要参数缺失需要用户补充才结束本轮对话。这避免了无意义的循环提升了用户体验。不过这种设计依赖于错误类型的准确区分。如果模型误判可能导致对话提前终止或无限重试。在实际中可以增加重试次数上限和人工干预入口。适用边界与权衡综合来看原文的设计思路适合中大型项目团队有 3 人以上有明确分工。工具数量超过 20 个权限粒度要求细致。对安全性和可观测性有较高要求。不适合个人开发者快速验证 MVP三层架构和双重过滤会增加不必要的复杂度。工具数量极少5权限简单直接硬编码反而更快。团队对 Go 或 Eino 框架不熟悉学习成本太高。如果让我选我更倾向于从最简单的单层协议开始根据实际痛点逐步引入架构拆分和优化策略。不要一开始就追求完美先跑通再迭代。你可能会问那我到底该不该自研协议这个问题没有标准答案取决于你的团队规模、技术栈和长期规划。但至少现在你知道了每个选择背后的代价和边界。最后留一个讨论点你在实际项目中是选择自研轻量工具协议还是直接复用 Json Schema自研的灵活性 vs 兼容性你会怎么选
手搓 AI 工具系统:协议、权限、可观测,一个都不能少
发布时间:2026/5/23 21:35:51
先说结论生产环境中的 Function Calling 远不止定义 JSON Schema协议统一、权限边界、执行可观测是三大硬门槛。三层架构service/domain/infra能有效隔离业务逻辑与工具实现但代价是增加了抽象层与维护成本。双重权限过滤与渐进式 skill 披露能显著减少无效 token 消耗但引入意图识别可能增加首次调用的延迟。从踩坑反思的角度拆解生产级工具系统在协议、权限、可观测性的真实取舍与设计代价。先说结论生产级工具系统到底在解决什么很多人对 Function Calling 的理解还停留在“定义 JSON Schema - 大模型调用函数 - 返回数据”的阶段。但在真实生产环境里三件事会立刻让你头疼协议不统一——团队里有人用 Json Schema有人自定义工具定义散乱无法复用。权限边界模糊——大模型可能越权调用不该访问的工具安全风险不可控。执行过程黑盒——用户等了几秒突然出结果中间发生了什么完全不可知。这三点是生产级工具系统必须跨过的门槛。[图片1] 一张对比图左侧是简单 demo 的直调用右侧是生产环境的复杂架构标注协议、权限、可观测三个环节。为什么协议统一是第一道坎自研 vs Json Schema 的取舍原文作者没有直接采用 Json Schema而是仿照它定义了一套轻量协议。理由是 Json Schema“有点重可读性不高”。站在纯技术角度看这个选择可以理解。如果你的系统规模不大团队对 Json Schema 不够熟悉自研一套更简洁的协议能降低心智负担。而且后期可以通过适配层兼容 Json Schema不算死路。但代价也很明显自研协议意味着你必须自行维护解析、校验、序列化逻辑同时第三方工具和库的兼容性会打折扣。如果团队后期需要对接外部系统适配成本会逐步累积。我更倾向于这样判断如果你只是内部工具、团队可控自研没问题但如果需要开放给第三方或长期维护Json Schema 的生态成熟度是更好的起点。三层架构解耦的甜头与维护的代价原文将系统拆分为 service、domain、infra 三层。domain 层定义协议接口包括工具的元数据、入参出参等。这是整个系统的“宪法”。service 层业务编排比如根据用户权限筛选可见工具、组装 prompt。infra 层技术实现比如用 Eino 框架处理工具调用落库用 GORM。这种拆法好处明显权限策略调整只改 service换 AI 框架只改 infra互不干扰。但实际跑起来你可能会遇到一个问题层与层之间的边界容易模糊。尤其是 service 层很容易变成“万能胶水层”既做业务判断又做数据转换逐渐臃肿。另外三层架构增加了代码跳转与调试成本对于小团队来说可能反而拖慢迭代速度。所以三层架构更适合有一定规模、多人协作的项目。如果只是个人项目或 MVP可能一层简单封装更现实。[图片2] 一张架构分层示意图显示 service、domain、infra 之间的依赖关系以及各层的关键职责。权限设计双重过滤真能防越权原文采用了两层权限过滤获取工具列表时——根据用户的 user_id、org_id、角色管理员/普通筛选可见工具只把有权限的 tools 发给大模型。调用具体 tool 时——再次校验权限防止大模型在推理过程中绕开第一层限制。双重过滤的策略在逻辑上确实比单层更安全。但值得注意的是权限数据本身也依赖上层应用的正确传递。如果上游用户身份信息被篡改或遗漏再多的过滤也无用。另外权限粒度需要仔细设计。如果给每个工具都分配独立的 capability后期管理会非常麻烦。原文建议按角色分配 resource capability类似 RBAC 的思路这个方向是对的。性能优化从全量注入到意图识别的进化原文提到了三种优化策略基础无权限用户直接走纯文本跳过 ReAct省 token。渐进式 skill 披露先只暴露工具的基本信息名称、一句话描述等大模型选中后再提供详细参数。意图识别让大模型自己判断需要什么工具然后去“搜索”工具而不是一股脑全塞进去。前两种已经比较成熟代价是增加了开发复杂度。而意图识别虽然激进但它真正解决了“工具数量爆炸”时上下文塞不下的问题。代价也很明显首次调用延迟会增加因为大模型需要多一轮“思考”。如果用户对响应速度敏感这个方案不一定适用。所以一个更现实的策略是根据用户历史行为或业务场景预加载最可能用到的 top K 个工具而不是完全取消全量注入。用户体验让用户看到“AI 在干嘛”比什么都重要很多 AI 应用只关心最终结果忽略了过程的可感知性。原文通过 tool_call_started 和 tool_call_finished 事件让前端实时展示执行进度。此外错误预校验也值得借鉴。如果工具调用参数格式错误允许大模型重试两次但如果是必要参数缺失需要用户补充才结束本轮对话。这避免了无意义的循环提升了用户体验。不过这种设计依赖于错误类型的准确区分。如果模型误判可能导致对话提前终止或无限重试。在实际中可以增加重试次数上限和人工干预入口。适用边界与权衡综合来看原文的设计思路适合中大型项目团队有 3 人以上有明确分工。工具数量超过 20 个权限粒度要求细致。对安全性和可观测性有较高要求。不适合个人开发者快速验证 MVP三层架构和双重过滤会增加不必要的复杂度。工具数量极少5权限简单直接硬编码反而更快。团队对 Go 或 Eino 框架不熟悉学习成本太高。如果让我选我更倾向于从最简单的单层协议开始根据实际痛点逐步引入架构拆分和优化策略。不要一开始就追求完美先跑通再迭代。你可能会问那我到底该不该自研协议这个问题没有标准答案取决于你的团队规模、技术栈和长期规划。但至少现在你知道了每个选择背后的代价和边界。最后留一个讨论点你在实际项目中是选择自研轻量工具协议还是直接复用 Json Schema自研的灵活性 vs 兼容性你会怎么选