news 2026/5/23 21:35:33

手搓 AI 工具系统:协议、权限、可观测,一个都不能少

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手搓 AI 工具系统:协议、权限、可观测,一个都不能少

先说结论

  • 生产环境中的 Function Calling 远不止定义 JSON Schema,协议统一、权限边界、执行可观测是三大硬门槛。

  • 三层架构(service/domain/infra)能有效隔离业务逻辑与工具实现,但代价是增加了抽象层与维护成本。

  • 双重权限过滤与渐进式 skill 披露能显著减少无效 token 消耗,但引入意图识别可能增加首次调用的延迟。

从踩坑反思的角度,拆解生产级工具系统在协议、权限、可观测性的真实取舍与设计代价。

先说结论:生产级工具系统到底在解决什么

很多人对 Function Calling 的理解还停留在“定义 JSON Schema -> 大模型调用函数 -> 返回数据”的阶段。但在真实生产环境里,三件事会立刻让你头疼:

  1. 协议不统一——团队里有人用 Json Schema,有人自定义,工具定义散乱无法复用。
  2. 权限边界模糊——大模型可能越权调用不该访问的工具,安全风险不可控。
  3. 执行过程黑盒——用户等了几秒突然出结果,中间发生了什么完全不可知。

这三点,是生产级工具系统必须跨过的门槛。

[图片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 之间的依赖关系,以及各层的关键职责。

权限设计:双重过滤真能防越权?

原文采用了两层权限过滤:

  1. 获取工具列表时——根据用户的 user_id、org_id、角色(管理员/普通)筛选可见工具,只把有权限的 tools 发给大模型。
  2. 调用具体 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 兼容性,你会怎么选?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/23 21:34:56

C++中组合详解及其作用介绍

案例在平面上两点连成一条直线, 求直线的长度和直线中点的坐标. 要求:基类: Dot派生类: Line (同时组合)派生类 Line 从基类 Dot 继承的 Dot 数据, 存放直线的中点坐标Line 类再增加两个 Dot 对象, 分别存放两个端点的坐标Dot 类:1234567891011121314151617#ifndef PROJECT5_DO…

作者头像 李华
网站建设 2026/5/23 21:34:13

用C++手搓一个简易RTSP服务器(支持H264推流与VLC播放)

用C从零构建RTSP服务器&#xff1a;H264推流与VLC播放实战指南 在音视频开发领域&#xff0c;实时流媒体传输协议&#xff08;RTSP&#xff09;扮演着核心角色。本文将带您用C实现一个支持H264视频推流的简易RTSP服务器&#xff0c;并通过VLC播放器验证其功能。不同于理论讲解&…

作者头像 李华
网站建设 2026/5/23 21:34:01

【 linux 】理解进程状态

目录 1.僵尸进程与孤儿进程 1.1 孤儿进程 1.2 僵尸进程&#xff08;Z&#xff09; 2.进程状态 3.进程退出与进程等待 3.1 进程退出 3.2 进程等待 3.2.1 wait和waitpid对比 3.3 WEXITSTATUS 和 WIFEXITED 1.僵尸进程与孤儿进程 1.1 孤儿进程 父进程结束了子进程还没有…

作者头像 李华
网站建设 2026/5/23 21:29:28

使用PythonOpenAI兼容SDK分钟级接入Taotoken全模型

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 使用Python OpenAI兼容SDK分钟级接入Taotoken全模型 对于习惯使用OpenAI官方Python SDK的开发者来说&#xff0c;接入Taotoken平台…

作者头像 李华