news 2026/9/29 21:38:41

treg 工具解析机制全解析:URL 主机匹配 + 最长前缀如何决定 API 路由

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
treg 工具解析机制全解析:URL 主机匹配 + 最长前缀如何决定 API 路由

treg 工具解析机制全解析:URL 主机匹配 + 最长前缀如何决定 API 路由

【免费下载链接】tregOpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn项目地址: https://gitcode.com/GitHub_Trending/treg/treg

如果你正在使用 treg 这个"AI Agent 的工具网关",一定好奇:当你只输入一个 API 地址,treg 是怎么知道该用哪个团队的凭据、该转发到哪个上游服务的?答案就在它的目标解析机制里——先按 URL 主机(host)圈定候选工具,再用最长 base_url 前缀(longest prefix)从中选出唯一赢家。这套机制藏在 resolve.py 中,是 treg 被称为"agent 工具的 OpenRouter"的核心原因。

为什么需要"工具解析"?

treg 的定位是让 AI Agent 不持有任何厂商密钥就能安全调用各家 API:Agent 只管发出请求,treg 在转发途中注入凭据、审计、计费。

关键问题在于:Agent 只会说"我要访问https://api.stripe.com/v1/charges",它不知道 treg 内部的工具名。于是 treg 需要一种零词汇量的解析方式——你写的就是原生 API 地址,路由由地址本身决定。

两种请求形态:URL 透传 vs 命名调用

进入/call/的请求(路由定义见 call.py)共有两种形态:

形态长什么样解析方式
URL 透传(Agent 原生)/call/https://api.intercom.io/me主机 + 最长前缀匹配
命名(CLI/遗留)/call/my-tool/<path>直接按工具名精确查找

本文的主角是第一种。它的完整流水线只有一句话:解析 → 授权 → 扣费 → 忠实转发,其中"解析"阶段就产出了ResolvedTarget(工具, 上游URL)这个结果。

三步解析:主机圈定 → 前缀筛选 → 最长者胜

以下逻辑对应 resolve.py 中的_resolve_call函数:

第一步:提取主机并命中索引

把透传 URL 解析出 netloc(主机名,统一转小写),然后按带索引的Tool.host字段查询——这是 models.py 中专门设计的一列,注释写着"netloc of base_url — indexed for URL-passthrough resolution"。所有查询都限定在调用者自己的 org内,两个团队即使注册了相同主机也不会互相干扰。

第二步:路径分段边界上的前缀匹配

每个候选工具都有自己的base_url。匹配规则不是朴素的字符串前缀,而是要求落在路径分段边界上:

  • ✅.../v2匹配.../v2本身,或.../v2/...
  • ❌.../v2绝不匹配.../v20/...

这一条看似苛刻的规则防止了一个真实事故:把 v2 的凭据错误注入到未注册的兄弟路径/v20上。

第三步:最长前缀胜出

多个工具可能同时命中同一主机(比如团队同时连接了同一供应商的多个 API 子域)。此时比较去掉尾部斜杠后的base_url长度,最长者获胜:

base_url = https://api.example.com/v1 (13 字符路径) ← 胜出 base_url = https://api.example.com (更短) 请求 = https://api.example.com/v1/users

比较前会先做rstrip("/")归一化,所以.../v1和.../v1/算等长——这不是"悄悄分出胜负",而是会被如实判定为一次真正的冲突(409)。

平局怎么破?409 错误与注册表优先

当最长前缀出现平局,treg 的处理非常克制(resolve.py):

  1. 注册表连接优先:如果平局中只有一个工具绑定的是"注册表 OAuth 凭据"(provider-backed),直接选它。因为这种连接往往是用户刚刚授权、正在使用的"活连接",而手动注册的旧工具很可能拿着过期密钥——对永远不打工具名的 Agent 调用方来说,409 是纯粹的打断。
  2. 仍是平局 → 409:返回target_ambiguous,错误信息列出所有冲突的工具名,并明确指示"改用无歧义的/call/<name>/<path>形式"。

对应的行为测试见 test_passthrough.py:test_longest_prefix_wins验证最长前缀胜出,test_ambiguous_host_409验证真正的平局返回 409。

权限过滤:先用 ACL 缩小候选集,再比长短

一个容易被忽略的顺序细节:权限过滤发生在最长前缀比较之前(proxy-model.md 中的 "ACL-filtered candidates" 一节)。

同主机所有工具 → 用 ACL(项目范围 + 工具白名单)过滤 → 剩下的人里才比前缀

为什么顺序重要?一个你根本看不见的同主机工具,不应当让你收到 409——它不配参与你视野内的竞争。同时这个过滤只缩小候选集,永远不放大:任何解析结果之后仍会经过完整的访问策略闸门。

由此还能区分两种失败:

  • 403:主机上有匹配工具,但全被 ACL 过滤掉了 → "你有工具但没权限,找管理员开"
  • 404:这个主机压根没有注册工具 → "no registered tool for upstream ..."

403 的措辞只点出你输入的主机名,绝不泄露被隐藏的工具内部名字。

小结:一张图看懂路由决策

/call/https://api.x.com/v1/users │ ├─ 1. host = api.x.com ──命中索引──> 本 org 内同主机工具 │ ├─ 2. ACL 过滤(看不见的不许参赛) │ ├─ 3. 路径分段边界前缀匹配 │ 无匹配 → 403(被 ACL 挡)/ 404(不存在) │ ├─ 4. 最长 base_url 者胜(去尾斜杠后比长度) │ 平局 → 注册表连接优先,否则 409 │ └─ 5. 产出 ResolvedTarget → 授权 → 计费 → 忠实转发

这套"主机 + 最长前缀"的设计,本质是把 DNS 的"最长标签匹配"思想搬到了凭据路由上:既让 Agent 零学习成本地直接喊出原生 API 地址,又保证每一次注入都有唯一、可解释、可审计的依据。

延伸阅读:完整的代理与转发契约见 proxy-model.md,凭据注入与忠实转发的规则也写在其中。

【免费下载链接】tregOpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn项目地址: https://gitcode.com/GitHub_Trending/treg/treg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

033_匹配网络损耗对输出功率的隐性吞噬

033、匹配网络损耗对输出功率的隐性吞噬 一个让我半夜爬起来改板的功率对不上事件 前年做一个工业加热电源项目,指标要求输出到负载的功率不低于某个值,前级逆变出来的功率按理论计算是够的,留了大概百分之十五的余量。样机装好之后,老问题来了:负载上实测功率比仿真值低…

作者头像 李华
网站建设 2026/9/29 21:37:40

赶 DDL 的那一周:为什么“少切几个软件“比“多几个功能“更救急

距离提交还有七天&#xff0c;论文还停在第二章。这时候最要命的不是不会写&#xff0c;而是时间被切碎了&#xff1a; 写稿用一个工具&#xff0c;查重换一个网站&#xff0c;降重找第三个平台&#xff0c;排版又要回头翻学校模板文件&#xff0c;答辩 PPT 再从零开始搭。每切…

作者头像 李华
网站建设 2026/9/29 21:37:26

10GB 数据 12 秒入库,计算比 Python 快 71 倍!DolphinDB 新能源场景实测曝光

在我国“双碳”目标驱动下&#xff0c;新能源装机规模持续增长&#xff0c;新能源场站正加速向规模化、智能化演进&#xff0c;随之而来的是设备监测数据量的极速攀升。与此同时&#xff0c;光伏、储能、叶片监测等业务场景多元发展&#xff0c;数据来源多样、格式繁杂、时效要…

作者头像 李华
网站建设 2026/9/29 21:36:51

OpenClaw 配 TaoToken:小红书自动运营的 config.toml 骨架与 MCP Skill 验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华