Skip to content

用固定通用工具与按需 Skill 加载替代 NyxID endpoint tools 展开 #3660

Description

@louis4li

交付方式与阶段

本 issue 是父 issue,按完整用户功能逐步演进,每个阶段都必须能独立演示和验收。协议、adapter、loader、工具和测试作为阶段内实施任务,不再按技术层横向拆分。

实施顺序:阶段 1 → 阶段 2 → 阶段 3 → 阶段 4。各阶段沿用同一契约和执行主链。阶段 1 必须在 Channel 对话中跑通实际服务读取,并证明 endpoint 数量不导致工具目录膨胀;不能把单独完成 skill loader 当作阶段完成。

授权原则:复用既有授权,不新增默认逐次审批。 已授权且现有策略未要求确认的操作直接执行;权限不足返回错误。只有用户或组织已经明确配置审批规则时才遵守原规则,不因写入、skill 或通用工具额外要求确认。

首版允许功能有限,但权限、身份、输入校验和正确失败必须成立。复杂自动修正与恢复后补,不把未支持情况吞成成功。

问题与目标

当前 connected-service 接入会将服务的 OpenAPI endpoints 展开为 LLM-visible tools。Google Workspace 等宽接口服务会让工具数量及 schema 字节数随 operation 数量增长,触发 AgentTurnToolCatalog 预算限制,也增加模型选择负担。

目标:使用固定、少量的通用工具入口,按需发现服务、加载 skill、读取 operation 定义并执行调用,使模型可见的工具数量不随服务及 operation 数量线性增长。

关联 #3657。本 issue 提出对其中“先筛选 operation,再物化 exact tools”路线的替代设计:operation 保留为按需读取的数据和执行契约,不再逐个注册成 LLM tools。保留 #3657 的预算、授权、审批、审计和统一执行主链要求;不自动关闭或修改原 issue。

复用现有职责

系统 职责
NyxID 服务实例发现、凭据与访问控制、有效 skill 推荐、代理调用
Ornn / 已支持的 skill 来源 发布并提供指定版本的 skill 内容及资源
Aevatar 按需加载、模型交互、调用契约校验、统一执行与结果观察

NyxID 已在 PR #1588 增加 recommended_skill_refs。引用包含 source / skill_id / name / version / sha256 / dependencies,同时提供 skills_revisionskills_manifest_digest。这是源码层面的契约依据,真实服务验收前需验证目标部署已支持该响应,且试点服务已经配置有效引用;本地开发与契约测试可先推进。

recommended_skills 是名称推荐;recommended_skill_refs 是固定来源、身份、版本与摘要的引用。配置 refs 时 NyxID 自动派生名称列表。Aevatar 不再维护一套平行的“服务品牌 → skill 名称”映射。

Agent Key 发现接口的版本与凭据前提

NyxID #1599 于北京时间 2026-09-17 22:42:28 合并,版本标记 0.23.3,才将 GET /api/v1/keys 等库存读取接口移出禁止 API key 的路由组。此前普通 Agent Key 会返回 403: API keys cannot access this endpoint。新实现允许普通 Agent Key 读取,并按有效服务 allowlist 过滤;写接口仍不在开放范围。

该结论已核对路由、中间件、handler 和 PR 历史,但尚未使用目标 Channel 的 Agent Key 对目标部署实测。不能把本机 CLI 登录查询成功当成 Agent Key 验证通过。Relay token 仍禁止访问;scheduled-invocation 专用 key 与普通 Agent Key 不可混同;delegated token 依其现有 account:read/路由策略判断。

代码开发可先使用已核对的契约与受控 fixture;首个联调步骤、且在真实服务验收前,必须验证目标部署能力和实际调用凭据类型。命中凭据类别/版本禁用错误时,不要求扩大 service allowlist 或写权限来修复,也不借用其他主体凭据。只在同一权威主体与已有授权链支持的现有发现入口内适配;没有支持入口时明确报告该发现路径不可用,不依赖修改 NyxID 来完成 Aevatar 功能。

发现范围:先查当前调用身份可用的服务及其 skill 引用

默认查询当前执行身份可访问的已连接服务实例,而不是全平台 catalog。主输出是 service_instance_id → effective skill refs,附带服务/账号标签、必要就绪信息及配置版本;服务可用但 refs 为空仍保留该实例,不能误判为没有权限或没有服务。

“用户连接过”不等于“当前应用或 Channel 可调用”。候选范围必须同时满足用户/组织对实例的访问资格、当前应用/委托/Agent Key 的已有授权边界,以及已知连接、凭据和节点就绪要求。读取身份与执行身份必须属于同一经验证主体及明确授权链。执行时仍按操作检查当前权限,不把发现列表当作所有下游 API 的授权证明。

若现有读取能力可见范围比执行授权更宽,应在已有强类型权限边界内收窄;不知道权限时返回未核实状态,不宣称可用。不得使用本机其他登录身份、Bot 所有者身份或更高权限凭据来扩大查询。

  • 主列表只向模型返回任务相关的可用实例和推荐目录,不批量加载 skill 正文、附件或 OpenAPI。
  • 只有用户指定的服务没有可用匹配时,才查询当前身份有权读取的相关连接诊断信息;不枚举与任务无关的被拒绝实例,不探测不可见账号。
  • 确实需要连接新服务时,再按需读取公共 catalog 的对应服务说明;catalog 条目只证明“平台支持接入”,不证明用户已经连接或授权。
  • 结果缺失不得直接归因为未连接或无权限:有明确证据才返回对应原因;没有证据时表述为“当前调用身份未发现可用连接”。
  • 区分:未连接、应用服务授权不足、凭据失效、下游 OAuth scope 不足、资源 ACL 不足、节点不可用、skill 推荐缺失、私有 skill 读取权限不足。只针对已证实且与当前任务相关的缺口提供下一步,不默认要求 All services、管理员权限或重新连接。

服务 ID 查询条件与授权事实分开

  • 使用同一个受限普通 Agent Key 发现和调用,且目标 NyxID 已支持相应版本时,直接复用 NyxID 返回的有效服务范围;Aevatar 不再维护、同步或推导第二份 Agent Key service allowlist。
  • 已知一个或多个服务实例 ID 时,支持可选 service_ids 查询条件,只读取/返回这些实例对应的有效 skill refs。该字段只收窄查询,不授予权限,不是持久化的第二套权限配置;未知 ID 或不可见 ID 不泄露其存在性。
  • 未知目标实例时,在当前凭据可见范围内返回有界目录,由 LLM 选择。即使设置 allow_all_services=true,也不全量塞入上下文;条数/字节上限与权限过滤是两个不同问题。上游不支持批量 ID 查询时,adapter 可在有传输上限的响应上做请求内过滤,不宣称是上游过滤。
  • Channel 现有 inventory 可能使用 verified sender 派生的 bearer,而调用受 registration Agent Key 约束,不能把 sender inventory 误认为已按该 key 过滤。实施时先确定并记录实际凭据链,通过已有权威授权契约求得当前可执行范围;无法确认时显式返回未核实状态,不通过更换主体或提高权限兜底。

交互与调用流程

用户任务
  → LLM 按 NyxID skill 查询当前身份可用的服务实例与有效 skill refs
  → 有匹配:选择具体账号和所需 skill 引用
      → LLM 显式加载该精确 skill 的主文档与资源目录
      → 信息不足时才读取指定资源 / operation 定义
      → 通过通用入口调用选定实例并返回结果
  → 无匹配:按需诊断与任务相关的可见连接
      → 有证据的连接/授权/就绪缺口:引导对应处理
      → 无证据:说明当前未发现可用连接,必要时再查公共 catalog

复用现有 skill 与执行入口

本地 NyxID skill 已说明 nyxid service list --output jsonnyxid catalog show/endpointsnyxid proxy request --via-service。优先复用这些已发布能力;不要因为功能名不同,再创建平行服务发现体系。

  • 有现成、受约束且可绑定当前调用身份的 CLI 执行入口时,由 LLM 按 NyxID skill 调用 CLI,并在工具返回模型前做确定性字段投影与条数/字节限制。
  • Channel 无此执行入口时,扩展已有 nyxid_service_inventory 及 NyxID API adapter;不要为了运行 CLI 新开一个无限制 shell。
  • 两种接入方式复用同一份身份、有效推荐及错误语义,不要求同时实现两条路径。初始上下文提供简短发现/加载指引,不能依赖“先发现服务才能加载、又必须先加载才能发现”的循环。
  • CLI service list 当前已验证版本没有原生 query/limit/cursor;Aevatar 可在请求内过滤和有界投影,不能把本地过滤描述为上游分页,也不能默认上游响应无限大。

按需加载职责

推荐列表只是目录。选择服务不等于加载该服务的所有推荐 skill。LLM 根据任务显式选择引用,运行时负责精确解析与校验;主文档只附资源目录,文件正文另行按需读取。引用未配置不触发授权提示,而是走已有正式 operation 文档或明确报告缺少用法。相同精确引用可共享知识内容,但每个调用继续显式绑定服务实例,不能去重掉账号归属。

已加载且仍在模型上下文中的精确内容可以复用;上下文压缩后正文不可见时,允许按原精确引用重新读取,不仅凭“曾加载”标志假设模型仍掌握内容,也不因此切换最新版。

operation 查询为可选辅助:已加载说明足够时直接构造调用;执行端仍依权威契约校验。不另设每轮语义筛选器,不在加载后动态展开 endpoint tools。

当前核验基线(2026-09-18)

本机 CLI 0.13.0 的查询返回 30 个用户服务,全部没有非空推荐 skill;Google Workspace catalog 的 recommended_skill_refs 为 null、skills_revision 为 0,catalog endpoints 可返回 25 个操作。说明查询入口与新字段已可用,但这次样本中的映射尚未配置。该本机账户样本不代表全部用户、全部服务或 Channel 执行授权。

首版精确加载验收必须使用已发布且已经有有效映射的受控样例,或明确区分测试 fixture 与真实服务验证;不得把 refs 为空解释为用户权限不足,也不能把合并源码当作所有部署和数据已准备完毕。

核心行为

1. 精确 skill 加载与继承

  • 消费 NyxID 返回的有效推荐,区分公共 catalog 定义 ID 与用户服务实例 ID。
  • 尊重现有覆盖规则:实例级 recommended_skills 已配置时,不自行补入 catalog refs,绕过实例覆盖语义。
  • 支持的来源必须有明确解析器;校验身份、精确版本及按来源规范定义的内容摘要。不要仅验证 hash 字符串格式就宣称内容已验证。
  • 精确引用不存在、来源不支持、版本不兼容或摘要不符时,返回结构化错误,不静默切换同名 skill 或最新版。
  • 明确依赖的加载与版本冲突行为,检测循环并限制依赖规模;不要把依赖列表存在视为依赖已自动安装。
  • 只有旧名称推荐时,允许明确标识的名称发现路径;没有推荐时,允许基于正式 operation 文档发现能力或返回缺失配置,不猜测 skill 映射。
  • skills_revision / skills_manifest_digest 用于识别推荐配置变化,不能替代单个 skill 的版本和内容摘要。运行中已加载的 skill 固定到精确引用,后续升级前滚。

2. Operation discovery 与通用调用

  • 有 OpenAPI / typed operations:按需返回 operation 摘要,选中后读取完整输入契约。执行端从权威定义解析 method/path/schema,校验参数、服务绑定、权限、风险和审批;不信任模型提供的 URL、风险标签或 skill 文本作为授权依据。
  • 同一调用入口可以执行多个 operation;operation 数量不影响 tool 数量。动态业务参数在外部协议 adapter 边界处理,内部稳定语义使用强类型 Protobuf 契约。
  • 只有文档、没有 typed operations 的小众服务:可使用已验证 skill 指导受约束的 NyxID proxy 调用,但必须明确标识为文档指导路径。限定目标服务、路由和凭据边界,保留审批与审计;不宣称具备 schema 校验,也不自动开放任意 URL 作为兜底。现有运行时不允许该路径时,明确返回不支持。
  • 多账号必须绑定确定的服务实例;信息不足时澄清,不根据 skill 名称或服务 slug 任意选择账号。

3. 上下文与执行边界

  • 服务目录、skill 内容、关联资源、operation 定义及调用结果都有独立的大小与分页限制,避免把“工具膨胀”转移为“文档膨胀”。
  • Skill 负责操作知识,不授予权限,不保证外部 API 永远成功。参数错误、重新授权、权限不足、限流、服务异常和执行结果不确定需要可区分的结果。
  • 通用工具接入既有 command/event/actor 执行及流式观察主链,不新增平行执行系统。需要跨请求持有的执行、审批、幂等和重试事实由 actor 或既有分布式机制拥有,不放进中间层进程内字典。
  • 写操作超时不得盲目重试;依据下游幂等能力和既有执行记录处理。同步 ACK 只表达实际达到的阶段。

实施范围与顺序

  1. 完整读取闭环([阶段 1] 通过 NyxID 推荐 Skill 与通用工具完成服务读取 #3661:一个明确服务实例、一个来自 Ornn 的有效精确 skill ref、无依赖主文档、一个读取场景;接入实际 Channel 路径,使用固定通用工具返回结果。先核对现有来源的版本和摘要契约。
  2. 已授权写入([阶段 2] 通过通用工具完成已授权服务写入 #3662:扩展同一入口支持普通写入,返回明确结果并处理重复提交与不确定结果;不新增默认逐次审批。
  3. 多服务与选择分支([阶段 3] 支持多服务、多账号及 Skill 资源按需发现 #3663:增加多账号选择、按需资源、简单有界 operation discovery、依赖处理,以及符合现有代理边界的文档型服务分支。
  4. 恢复能力([阶段 4] 完善服务调用的错误修正与恢复执行 #3664:补齐参数修正、重新授权后的继续、有限重试和超时对账;跨请求事实归属既有 actor/分布式机制。

相关现有入口:

  • src/Aevatar.AI.ToolProviders.NyxId/NyxIdConnectedServiceToolSource.cs
  • src/Aevatar.AI.ToolProviders.NyxId/ConnectedServices/NyxIdServiceInstanceClient.cs
  • src/Aevatar.AI.ToolProviders.NyxId/ConnectedServices/nyxid_service_tools.proto
  • src/Aevatar.AI.ToolProviders.Skills/UseSkillTool.cs
  • src/Aevatar.AI.ToolProviders.Ornn/OrnnExactRemoteSkillFetcher.cs

首版复用已发布 skill 与已配置映射。自动生成 skill、公共 skill 搜索/审核/发布平台不作为运行闭环的前置依赖。后续可复用公共 skill,或从小众服务的 OpenAPI / 官方文档生成候选 skill,经验证发布后由维护方绑定 refs;不要在每次用户调用中重新生成。

验收标准

  • 宽接口服务不再默认展开全部 endpoint tools;工具数量与 schema 字节数保持在固定入口的预算内,不随 operation 数量线性增长。
  • 用相同通用工具配置比较少量 operation 与数百个 operation 的服务,LLM tool 名称和 schema 不发生随 endpoint 数量增长的变化。
  • 服务、skill、资源与 operation discovery 都有界;启动时不读取全部 skill 内容或完整 OpenAPI。
  • 覆盖 refs 精确加载、名称推荐、无推荐、实例覆盖、未知来源、版本不兼容、摘要不符、依赖缺失与冲突。
  • 默认只展示当前执行身份可用的实例与推荐目录;可见但不可调用的实例不得进入主可用列表,未知权限不得冒充已授权。
  • 无匹配时才执行目标相关诊断或 catalog 查询;不默认枚举全部公共服务或加载其 skill。
  • 服务可用但 refs 为空不会触发新增授权提示;私有 skill 读取失败不会被解释成下游服务权限不足。
  • 发现、加载、调用保持同一调用主体及明确授权链;多账号选择不被 CLI 全局登录、Bot 所有者身份或内容去重改变。
  • 多账号共享同一 skill,执行仍准确绑定所选服务实例;错误实例绑定被拒绝。
  • typed operation 在发送前校验输入;无效参数、无权限及已有策略要求审批但尚未批准的操作不产生下游副作用。
  • 文档型服务验证受约束 proxy 路径,并明确其校验能力边界,不作为 typed operation 校验失败后的逃生通道。
  • 读取与已授权写入均可走通,未配置审批时直接执行,已有显式审批策略仍生效,结果进入统一流式观察链;重复提交和写操作超时遵守幂等约束。
  • 不通过提高 tool schema 预算、静默加载最新版或动态展开全部 operations 达成测试通过。
  • 同步更新架构文档与流程图;相关 build/test、架构门禁及修改测试涉及的稳定性门禁通过。

非目标

  • 完全消除工具执行入口。
  • 新增默认逐次审批,或把所有写操作视为需要再次授权。
  • 把 skill 当作权限、审批或调用 schema 的替代品。
  • 为 Aevatar 再建服务到 skill 的权威映射库。
  • 要求先完成复杂自动 skill 生成系统,才解决 tool 暴露过多问题。
  • 承诺消除凭据失效、权限不足、限流或外部服务故障。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions