T3 Code 非官方中文翻译不是官方产品,也不是 T3 Tools 官方文档。源提交 d2c25950b4d9英文原文GitHub 源文件
Skip to content

添加提供方 ​

衡量一个提供方(provider)集成,要看每一项 T3 功能在它上面是否如实工作,而不是只看回合(turn)能否跑完。本页列出新驱动(driver)需要做出的决定,以及需要拿出的证据。提供方约束和能力系统说明这些规则为何存在。

选择集成形态 ​

  • ACP 智能体从 ACP 注册表 条目开始。这些条目遵循 ACP 规范,没有按智能体单独处理的逻辑。只有当某个智能体需要规范未覆盖的行为时,才为它配备专用驱动;即便如此,它也只是共享 ACP 适配器上的一个小变体,例如 Grok 和 Antigravity。绝不要向通用注册表适配器(adapter)添加 agent-id 检查。
  • 其他协议使用实现 ProviderAdapterV2 的原生适配器,例如 Codex、Claude、Cursor、OpenCode、Pi 和 Muse。

提供方专有的行为留在适配器和驱动里。编排和客户端(client)读取的是能力,而不是驱动种类。

只报告提供方真正做的事 ​

  • **能力。**把 OrchestrationV2ProviderCapabilities 中的每个标志都设成提供方(provider)真正具备的行为。关掉它所没有的分叉、回滚、转向或子智能体支持;编排随后会回退,例如分叉会改用可移植上下文交接。一项能力若保持开启、到运行时却失败,那就是缺陷。
  • **权限模式。**只提供提供方会原生强制执行的模式,通过提供方展示中的 supportedRuntimeModes 来给出(Grok 和 Pi 是例子)。不要在 T3 里代答批准,以此来仿造一个缺失的模式:T3 的检查弱于智能体自己的强制执行。已经存下、但这次没有提供的模式,服务器会按 Supervised 运行(RuntimePolicy.ts)。
  • **批准与问题选项。**提供方自己的选项 ID 原样传递。每个请求都要有一种提供方会遵守的拒绝方式。
  • **交互模式。**除非提供方的计划输出会变成 T3 的提议计划卡片,否则隐藏计划开关(showInteractionModeToggle: false)。

进程、账户与安装边界 ​

  • **实例。**提供方会话(session)状态、目录和凭据属于提供方实例,而不属于驱动(driver)。去掉该实例并未配置的环境中既有凭据,这样两个实例就不会在无声无息中共用同一个账户或同一份账单。
  • **状态检查。**后台的状态刷新和模型刷新,不得打开一个会启动 MCP 服务器、运行钩子或发起登录的提供方会话。更重的探测要留在显式刷新之后。
  • **T3 MCP 工具。**注入该对话线程(thread)的 MCP 服务器,使智能体能够使用 T3 的工具;当这台服务器不可达时,回合(turn)也要能够继续。
  • **更新。**只有能够证明自己拥有该二进制文件的安装程序,才可以用来执行更新;否则保持手动。参见 providerMaintenanceRunner.ts。

测试 ​

用回放夹具证明适配器(adapter)行为:把一份提供方(provider)记录稿,经真实的编排器(orchestrator)、适配器和投影回放一遍。参见测试策略。

  • 用 apps/server/scripts 中的录制脚本(record-*-replay-fixture.ts)从真实提供方录制记录稿。新协议通常需要自己的录制器。
  • 覆盖 testkit/fixtures 下该提供方所支持的共享场景:simple、multi_turn、queued_turn、turn_interrupt、message_steering、provider_thread_resume,以及 tool_call_* 批准用例。共享场景覆盖不到的行为,再补充提供方自己的夹具。
  • 单元测试用于纯逻辑,以及真实提供方无法按需产生的失败。用手工编写的帧去驱动适配器的测试,只是对协议的猜测;实机测试经常会发现这些猜测漏掉的地方。
  • 针对真实二进制文件的门控实机测试可以有,但它不能代替回放,因为 CI 会跳过它。

多个提供方都踩过的陷阱 ​

下面每一条都曾弄坏不止一个适配器。你的提供方(provider)能够产生的每一种情况,各备一个回放夹具,就能把它们抓住。

  • **在提供方宣告这些设置之前就写入。**智能体常常在提供方会话(session)打开之后、在稍后的一次更新里,或者直到某个模型运行时,才列出配置选项(例如 effort 选项只存在于带 effort 的模型上)。在那之前,智能体可能接受这次写入,实际却什么也不改。要等该选项被宣告之后再写;实时会话没有提供的已存储选项,应当视为跳过,而不是失败。
  • **“Default”是哨兵值,不是模型。**默认模型这一选择,必须在一个具名模型运行过之后把提供方会话切回去,恢复出来的会话也一样。绝不要把这个哨兵值发给提供方。
  • **回合开始之前就发出了停止。**取消若在提供方登记该提示之前到达,可能被忽略,回合(turn)会一直跑到结束;也可能留下一个提供方从未保存的提供方会话。找到提供方自己的回合已开始信号,并测试刚刚发送就按下停止。
  • **提供方自行启动的工作。**后台命令(command)、子智能体、工作流和目标,可能在 T3 的回合已经结算之后才结束,或才开始一个回合。通过 ProviderContinuationRequests 提供续跑,让父级醒来,并报告 hasPendingBackgroundWork,这样提供方会话就不会被当作空闲而释放。丢掉它,或者杀掉该会话,结果就会丢失。
  • **子智能体比拉起它们的运行活得更久。**子级可能在父级回合结算之后才报告,也可能在后来的一次运行中恢复。按其所属子智能体路由这些更新,而不是按当前哪一次运行正在活跃。
  • **失败或被停止的回合不留下未结束的事项。**结算该回合的工具调用、子智能体,以及仍待处理的批准和问题。每条终态路径都要有自己的回放:完成、停止、提供方失败,以及进程退出。
  • **用量限制不是普通失败。**把配额错误和速率限制错误归类为 usage_limit,并在提供方给出重置时间时带上它,这样对话线程(thread)会显示 Limited,并且可以恢复。
  • **路径与环境。**测试符号链接的工作区,例如 macOS 的 /tmp;比较规范路径的智能体,在那里每个回合都会失败。丢掉该实例并未配置的继承凭据。登录状态未知时,报告为未知,不要报告为已登录。

驱动接在哪里 ​

提供方(provider)放在它自己的 packages/provider-<name> 包里,以 Pi 为参照。尚未迁出的驱动(driver)仍在 provider/Drivers 中。

  • 包导出。./settings 存放实例设置模式,用 contracts 中的 makeProviderSettingsSchema 构建。./client 导出一个 ProviderClientDefinition(标签、设置模式、纯数据图标、徽章),并且必须对浏览器和 React Native 保持安全。./server 导出 ProviderDriver 及其适配器驱动。./testing 暴露服务器回放测试套件所驱动的内部实现;需要编排器(orchestrator)的测试套件留在服务器中。设置位于 providerInstances;新提供方默认关闭。
  • **包边界。**服务器代码只导入 @t3tools/provider-core/server/*、contracts 和 shared。它通过 ProviderHost 访问服务器(路径、设置、后台需求、附件、已存储的凭据),绝不通过 apps/server。测试使用 @t3tools/provider-testing。
  • **服务器注册:**驱动在 builtInDrivers.ts 中的条目。该驱动带有自己的适配器驱动。还要包括它在状态顺序中的位置、model-manifest.json 中的兼容策略(递增 updatedAt;参见模型清单),以及它在 contracts 中的默认模型。
  • **客户端注册:**Web 与移动端提供方注册表中的客户端(client)定义,以及设置搜索词。客户端绘制包中的图标;不要为单个驱动再增加图标分支。
  • **文档:**一篇符合产品口吻的 docs/user/providers-<name>.md 指南、安装表中的一行,以及任何会改变权限模式页面的提供方差异。

非官方译文 · 源提交 d2c25950b4d9 · 不代表 T3 Tools