内容
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/t2a-hero-dark.png">
<source media="(prefers-color-scheme: light)" srcset="assets/t2a-hero-light.png">
<img
src="assets/t2a-hero-light.png"
alt="T2A 协议 — Tool-to-Agent 协议"
width="360"
>
</picture>
</p>
<h1 align="center">T2A 协议</h1>
<h3 align="center">工具可以变得智能,而无需嵌入 LLM 调用。</h3>
<p align="center">
T2A 是用于可审计推理交接的 <strong>Tool-to-Agent 协议</strong>。
</p>
<p align="center">
适用于命令行接口、API、软件开发工具包、持续集成作业、工作流和 MCP 服务器。
</p>
<p align="center">
无需工具端 LLM API 密钥 · 无需工具端模型计费 · 无需工具端本地模型
</p>
<p align="center">
<strong>代理推理。</strong><br/>
<strong>工具验证。</strong><br/>
<strong>工作流恢复。</strong>
</p>
## 拥有代理,为什么每个工具都想要另一个模型?
您已经拥有一个智能代理,如 Codex、Claude Code 或 Cursor。
然后,您连接一个工具,该工具达到推理检查点。它可能需要总结证据、分类风险、合并内存或制定计划。
如今,该工具通常要求您再次提供智能:
- 提供您自己的 LLM API 密钥
- 支付工具的托管模型账单
- 运行工具端的本地模型
这是向后兼容的。智能已经可以通过主机代理获得,但用户必须在工具交付价值之前配置另一个模型。
对于用户来说,这意味着另一个密钥、账户、账单、提供商配置或本地运行时。
对于工具作者来说,这种摩擦不仅是维护开销。它是直接的采用问题:每个额外的设置步骤都是用户在体验工具价值之前放弃的另一个机会。
T2A 采用不同的方法:
> 当工具需要智能时,它会从调用它的代理中借用。
工具发出结构化、可审计的推理交接。主机代理使用其现有的模型能力完成推理。工具在更改状态或恢复执行之前验证结构化结果。
**代理推理。工具验证。工作流恢复。**
## 第一个证明:无需内存工具模型密钥的智能内存
`t2a-memory` 是第一个证明,而不是整个协议。
内存是微缩的痛苦。
有用的内存工具需要推理:提取、合并、冲突处理和持久更新。
大多数智能内存工具通过要求模型密钥、模型配置、SaaS 账户或本地模型来解决这个问题。
`t2a-memory` 不这样做。
它是一个本地内存工具:
- 不需要 OpenAI 密钥
- 不需要 Anthropic 密钥
- 不需要 Gemini 密钥
- 不需要 `model`、`base_url` 或 `provider`
- 不创建工具端模型计费
- 不运行工具端本地模型
然而,主机代理可以使用它来创建、合并、验证和提交内存。
```text
用户询问本地代理:
请记住,我更喜欢简洁但结构化的技术建议。
t2a-memory:
创建一个 T2A 交接
主机代理:
读取胶囊
执行推理
编写结构化输出
t2a-memory:
验证输出
提交本地内存
用户:
运行 t2a-memory read
看到内存
```
简化结果:
```text
t2a-memory doctor
T2A 内存医生
工具端模型设置:无
✓ 提供商/模型/base_url 配置:无
✓ 内存工具所需的 API 密钥:否
✓ 直接 LLM SDK 依赖:无
✓ 工具端本地模型要求:否
✓ 内存操作所需的网络:否
结果:正常
t2a-memory read
内存:
- 用户更喜欢简洁但结构化的技术建议。
```
内存工作流变得智能,而无需内存工具成为 LLM 客户端。
这证明了:
- 内存工具不拥有模型调用
- 内存工具不要求模型凭证
- 主机代理执行推理
- 工具验证结构化输出
- 本地内存被提交
- 工作流在无需工具成为 LLM 客户端的情况下完成
这是 T2A 边界在起作用。
## 选择您的路径
| 我想... | 从这里开始 |
| --- | --- |
| 在不安装的情况下感受证明 | [第一个证明](#第一个证明-无需内存工具模型密钥的智能内存) |
| 使用本地代理尝试 | [复制粘贴证明](#复制粘贴证明-询问您的本地代理运行它) |
| 在没有具备能力的代理的情况下尝试 | [手动回退](#手动回退) |
| 在不嵌入 LLM 调用情况下构建智能工具 | [适用于工具作者](#适用于工具作者) |
| 教授主机代理完成 T2A 任务 | [适用于主机代理](#适用于主机代理) |
| 阅读协议 | [T2A 胶囊](#t2a-胶囊)、[规范](spec/v0.1/0001-overview.md) |
## 复制粘贴证明:要求您的本地代理运行它
拥有 Codex、Claude Code、Cursor 或另一个 shell 能力的本地代理吗?复制此提示。它适用于 macOS/Linux/WSL shell 和 Windows PowerShell;代理应检测操作系统并使用匹配的命令。代理将安装软件包、创建 T2A 交接、完成推理任务、验证、提交并读取内存。
证明使用 npm 软件包,因此需要 Node.js 22+ 和 npm。您的本地代理可以首先检查这一点,并在您批准的情况下安装它们(如果缺少)。
将以下内容复制到您的本地代理:
```text
您是我的本地主机代理。
证明 t2a-memory 可以在不拥有模型密钥的情况下为我提供本地内存。
使用用户级工具主页。不要需要全局 npm 权限。
首先,检查 Node.js 22+ 和 npm 是否可用。
如果它们可用,请继续。
如果它们丢失,请告诉我缺少什么,并在安装 Node.js/npm 之前询问我的批准。请使用我操作系统的最不侵入性的标准方法,例如 macOS 上的 Homebrew、Windows 上的 winget 或 Linux 上的系统包管理器/nvm/fnm(如果已可用)。不要在未经询问的情况下安装系统包。
首先,检测我的操作系统和 shell。
如果我在 macOS、Linux 或 WSL 上,请使用此设置:
TOOL_HOME="${T2A_TOOL_HOME:-$HOME/.t2a/tools}"
mkdir -p "$TOOL_HOME"
npm install --prefix "$TOOL_HOME" @t2a-protocol/t2a @t2a-protocol/t2a-memory
T2A="$TOOL_HOME/node_modules/.bin/t2a"
T2A_MEMORY="$TOOL_HOME/node_modules/.bin/t2a-memory"
如果我在 Windows PowerShell 上,请使用此设置:
$ToolHome = if ($env:T2A_TOOL_HOME) { $env:T2A_TOOL_HOME } else { Join-Path $HOME ".t2a\tools" }
New-Item -ItemType Directory -Force -Path $ToolHome | Out-Null
npm install --prefix $ToolHome @t2a-protocol/t2a @t2a-protocol/t2a-memory
$T2A = Join-Path $ToolHome "node_modules\.bin\t2a.cmd"
$T2AMemory = Join-Path $ToolHome "node_modules\.bin\t2a-memory.cmd"
然后运行医生检查并显示结果:
macOS/Linux/WSL:
"$T2A_MEMORY" doctor
Windows PowerShell:
& $T2AMemory doctor
为以下事实创建内存交接:
"我更喜欢简洁但结构化的技术建议。"
运行匹配的命令:
macOS/Linux/WSL:
"$T2A_MEMORY" remember "我更喜欢简洁但结构化的技术建议。"
Windows PowerShell:
& $T2AMemory remember "我更喜欢简洁但结构化的技术建议。"
解析 `t2a-memory remember` 的 JSON 输出。
从返回的 `local.task_dir` 设置 `TASK_DIR`(在 macOS/Linux/WSL 上)或 `$TaskDir`(在 Windows PowerShell 上)。
在任务目录中验证和提交:
- 读取 `task.json`
- 检查 `prompt.md`、`input.json`、权限和 `output.schema.json`
- 仅写入任务目录中的 `output.json`
- 运行核心 T2A 验证
- 运行 T2A 内存验证
- 验证失败时修复输出
- 仅在验证通过后提交
- 运行 `t2a-memory read` 并向我显示提交的内存
使用匹配的命令:
macOS/Linux/WSL:
"$T2A" validate "$TASK_DIR"
"$T2A_MEMORY" validate "$TASK_DIR"
"$T2A_MEMORY" commit "$TASK_DIR"
"$T2A_MEMORY" read
Windows PowerShell:
& $T2A validate $TaskDir
& $T2AMemory validate $TaskDir
& $T2AMemory commit $TaskDir
& $T2AMemory read
安全约束:
- 不要为 t2a-memory 配置 LLM 提供商。
- 不要为内存工具添加 OPENAI_API_KEY、ANTHROPIC_API_KEY、GEMINI_API_KEY、model、base_url 或提供商配置。
- 不要读取无关的用户文件。
- 在进行破坏性更改之前询问。
- 对于软件包安装,仅写入 T2A 用户级工具主页。
- 在交接和内存工作流期间,仅写入 T2A/t2a-memory 任务和内存位置。
完成后,用一段话解释发生了什么:
代理推理,工具验证,工作流恢复。
```
<details>
<summary>代理应在内部执行的操作</summary>
- 检测操作系统和 shell。
- 将软件包安装到 `~/.t2a/tools` 或另一个用户级工具主页,使用 `npm install --prefix`。
- 在 Windows PowerShell 上使用 `.cmd` 二进制文件。
- 运行 `t2a-memory doctor`。
- 运行 `t2a-memory remember`。
- 解析 `local.task_dir`。
- 编写 `output.json`。
- 使用 `t2a` 和 `t2a-memory` 验证。
- 使用 `t2a-memory` 提交。
- 使用 `t2a-memory read` 读取。
</details>
成功意味着:
- `t2a-memory doctor` 报告没有工具端模型设置
- 创建了 T2A 交接
- 主机代理编写了结构化输出
- 验证通过
- 本地提交了内存
- `t2a-memory read` 显示内存
- 内存工具仍然没有工具端模型密钥或模型配置
可选:为未来会话安装可重用的代理技能。
(不适用于上述证明。)
```bash
TOOL_HOME="${T2A_TOOL_HOME:-$HOME/.t2a/tools}"
"$TOOL_HOME/node_modules/.bin/t2a-memory" install --agent auto
```
这可能会将 T2A 和 T2A 内存技能文件写入本地代理技能目录,例如 `.agents` 或 `.claude`。
<a id="manual-fallback"></a>
<details>
<summary>没有本地代理?手动检查协议</summary>
此路径适用于没有本地 shell 能力的代理、无法可靠地编辑文件的代理或希望手动检查协议的用户。
在 Windows PowerShell 上,使用 `node_modules\.bin` 下的 `.cmd` 二进制文件和 PowerShell 变量语法。
安装软件包:
```bash
TOOL_HOME="${T2A_TOOL_HOME:-$HOME/.t2a/tools}"
export T2A_TOOL_HOME="$TOOL_HOME"
npm install --prefix "$TOOL_HOME" @t2a-protocol/t2a @t2a-protocol/t2a-memory
```
创建内存交接:
```bash
"$TOOL_HOME/node_modules/.bin/t2a-memory" remember "我更喜欢简洁但结构化的技术建议。"
```
从 JSON 输出中复制 `local.task_dir`:
```bash
TASK_DIR="<t2a-memory remember 打印的任务目录>"
```
检查胶囊:
```bash
cat "$TASK_DIR/task.json"
cat "$TASK_DIR/prompt.md"
cat "$TASK_DIR/input.json"
cat "$TASK_DIR/output.schema.json"
```
手动创建 `output.json`,或要求单独的聊天模型生成匹配 `output.schema.json` 的 JSON。使用来自 `input.json` 的真实 `event_id`:
```json
{
"event_id": "<来自 input.json 的 event_id>",
"decision": "commit",
"operations": [
{
"op": "add",
"topic": "communication-style",
"statement": "我更喜欢简洁但结构化的技术建议。",
"source_event_ids": ["<来自 input.json 的 event_id>"]
}
],
"rationale": "用户表达了持久的沟通偏好。"
}
```
然后验证、提交并读取:
```bash
"$TOOL_HOME/node_modules/.bin/t2a" validate "$TASK_DIR"
"$TOOL_HOME/node_modules/.bin/t2a-memory" validate "$TASK_DIR"
"$TOOL_HOME/node_modules/.bin/t2a-memory" commit "$TASK_DIR"
"$TOOL_HOME/node_modules/.bin/t2a-memory" read
```
手动路径不是主要的 wow 路径。主要的 wow 路径是本地主机代理完成交接。
</details>
## 刚刚发生了什么?
工具达到推理检查点。
它没有嵌入 LLM 客户端,而是发出 T2A 胶囊。
胶囊包含:
- 任务元数据
- 有界输入
- 提示
- 输出模式
- 验证边界
主机代理完成推理并编写结构化输出。
工具在提交状态或恢复确定性执行之前验证输出。
代理推理。工具验证。工作流恢复。
## 简单流程
```mermaid
flowchart LR
工具["工具达到推理检查点"] --> 胶囊["发出 T2A 胶囊"]
胶囊 --> 代理["主机代理推理"]
代理 --> 输出["编写结构化输出"]
输出 --> 验证["工具验证"]
验证 --> 恢复["工作流恢复"]
```
## 为什么边界很重要
T2A 不是关于移除模型使用。
而是将模型使用放在正确的边界上。
主机代理已经拥有用户选择的推理能力。
工具是领域约束所在的地方:文件路径、源 ID、内存模式、风险标签、提交规则和验证逻辑。
当工具嵌入自己的模型调用时,这些边界会崩溃。
工具开始拥有提示、提供商配置、模型选择、凭证、计费和故障恢复。
当工具发出 T2A 交接时,边界保持可见:
- 工具声明任务
- 代理执行推理
- 工具验证结构化输出
- 工作流仅在验证后恢复
通常的替代方案都会增加用户摩擦和工具作者的采用风险。
### 1. 提供您自己的 LLM API 密钥
现在每个工具都需要您的 OpenAI、Anthropic、Gemini、Cohere、Voyage 或本地兼容 API 密钥。
您可能没有一个。您可能只有代理产品订阅。您可能不想将计费凭证交给您尝试的每个工具。您可能不知道工具发送的提示或将花费多少。
对于工具作者来说,BYOK 不仅仅是一个集成挑战。每个提供商都有不同的模型、有效载荷、错误、速率限制、基本 URL、流式传输行为、身份验证格式和计费假设。 当您的工具要求 `api_key`、`model`、`base_url` 或 `provider` 时,设置摩擦成为您的产品的一部分,而用户没有密钥、不信任计费路径或不想为另一个提供商表单时,可能永远不会达到第一个成功的运行。
### 2. 支付工具的托管模型账单
工具可以将模型调用隐藏在其自己的云服务后面。
这消除了 API 密钥表单,但创建了新的账户、新的账单、新的数据边界和新的信任决定。用户已经为具有推理能力的代理付费;现在每个智能工具都想为另一片智能收费。
对于工具作者来说,托管模型调用意味着定价、计量、滥用预防、隐私问题、延迟、支持负担和模型成本风险。它们还会将采用问题转移到您的渠道:用户必须创建或信任另一个账户、接受另一个数据边界,并相信您的工具值得另一个经常性智能账单。
### 3. 运行工具端的本地模型
本地优先听起来不错,但并非每台笔记本电脑都能运行有用的模型。本地模型会消耗 CPU、GPU、RAM、磁盘和电池。小型本地模型可能比用户已经拥有的主机代理弱。
对于工具作者来说,本地模型支持意味着另一个设置路径、另一个故障模式和另一个质量问题。如果用户的机器无法很好地运行,或者本地模型给出弱结果,用户会将其视为您的工具失败。
## 嵌入式 LLM 调用 vs T2A 交接
| 嵌入式 LLM 调用内部工具 | T2A 交接 |
| --- | --- |
| 工具要求提供商密钥 | 主机代理使用其现有的模型能力 |
| 工具处理模型/提供商差异 | 主机代理拥有模型表面 |
| 工具可能接收计费凭证 | 工具接收结构化输出 |
| 隐藏的提示/输出 | 可审计的胶囊和结构化输出 |
| 工具拥有模型计费 | 工具保持无模型 |
| 工具直接信任模型输出 | 工具在提交/恢复之前验证 |
| 每个工具重新发明提供商配置 | 一个主机代理可以为许多工具推理 |
T2A 不会消除 LLM。它将模型调用从工具移出到主机代理边界。
## 协议映射
如果您思考代理协议映射,T2A 适合如下:
| 协议 | 方向 | 它标准化什么 |
| --- | --- | --- |
| MCP | 代理 -> 工具 | 代理调用工具并访问上下文 |
| A2A | 代理 <-> 代理 | 代理与其他代理协调 |
| T2A | 工具 -> 代理 | 工具交出推理检查点 |
T2A 不会取代 MCP 或 A2A。它完成了缺失的方向:代理调用工具后,工具可以将推理检查点交回给主机代理。
但 T2A 不仅限于 MCP 服务器。发布工具可以是 CLI、API、SDK、CI 作业、工作流或 MCP 服务器。
## T2A 胶囊
T2A 胶囊是一种持久的推理工作订单。在 v0.1 版本中,它是本地且基于文件的。其入口文档是 `task.json`。
```text
.t2a/tasks/<task-id>/
task.json
prompt.md
inputs/ # 通用胶囊输入目录
input.json # 某些工具(如 t2a-memory)可能使用单个输入文件
output.schema.json
output.json # 由主机代理稍后生成
validation.json # 由验证稍后生成
```
在交接时,`task.json`、`prompt.md`、已声明的输入和 `output.schema.json` 存在。
一些工具可能使用单个 `input.json`;其他工具可能使用 `inputs/` 目录。
主机代理稍后写入 `output.json`。
`validation.json` 由验证生成。
T2A 核心验证协议信封和输出模式。发布工具验证领域语义。
## T2A 交接结果
T2A 交接结果是工具在需要推理时返回的可机器读取的信号。代理不应需要猜测何时使用 T2A。
最小本地形状:
```json
{
"type": "t2a.handoff",
"t2a_version": "0.1",
"task_id": "memory-123",
"local": {
"task_dir": ".t2a/tasks/memory-123",
"task_file": ".t2a/tasks/memory-123/task.json"
}
}
```
远程交接模式已记录,但 v0.1 版本首先发布本地文件基流。
</div>
## 适用于工具作者
您的目标不是采用框架。
> 用一次 T2A 交接替换一次嵌入式 LLM 调用。
> 保持您的工具其余部分不变。
从这里开始: [T2A 工具作者工具包](docs/tool-authors/README.md)
快速通道:
1. 将工具作者工具包设置提示复制到 Codex / Claude Code / Cursor。
2. 让它运行 `t2a install tool-author-kit --agent auto`。
3. 检查其单检查点迁移计划。
4. 批准最小的本地 T2A 交接。
5. 运行 `t2a validate <task-dir>`。
工具包包括:
- 编码代理迁移提示
- 工具作者技能
- 可运行的最小 CLI 示例
- 具体的本地交接模板
- 兼容性检查清单
概念上:
```text
之前:
工具 -> 嵌入式 LLM 提供商调用 -> 解析结果 -> 修改状态
之后:
工具 -> 发出 T2A 胶囊
主机代理 -> 写入 output.json
工具 -> 验证 -> 提交/恢复
```
## 适用于主机代理
主机代理通过遵循胶囊完成 T2A 任务,而不是通过猜测。
1. 首先读取 `task.json`。
2. 检查声明的输入和权限。
3. 遵循 `prompt.md`。
4. 生成与 `output.schema.json` 匹配的 `output.json`。
5. 在安全时运行验证。
6. 在验证通过之前修复。
7. 除非明确要求,否则在恢复前停止。
最小主机支持:
- 识别 `type: "t2a.handoff"`
- 打开 `local.task_file`
- 读取声明的输入和提示
- 写入声明的输出路径
- 在可用时运行验证
- 不自动恢复
通用主机代理指令文件位于 [skills/t2a/SKILL.md](skills/t2a/SKILL.md)。
`t2a-memory` 还提供可安装的技能模板:
- `integrations/t2a-memory/templates/skills/t2a/SKILL.md`
- `integrations/t2a-memory/templates/skills/t2a-memory/SKILL.md`
## 验证、恢复、继续
`validate` 是确定性检查。
`resume` 属于发出工具。
`continue` 表示 `validate_then_resume`。
在 v0.1 中,T2A CLI 首先验证,然后打印恢复/继续指导。它不执行任意的工具所有命令。
## 本地优先 v0.1
v0.1 是本地优先、协议优先且故意简洁的。它首先实现了基于本地文件的胶囊。
远程 API、SDK 和 MCP 服务器被记录为交接模式,但该存储库不包括托管服务器、SDK、调度器、守护进程或 MCP 桥的实现。
## 零工具侧模型设置
该存储库不得添加工具侧 LLM API 调用,不得要求 `model`、`base_url`、`api_key`、`provider` 或 LLM SDK 配置。
主机代理可以使用其自己的模型能力。工具不拥有模型调用。
## 常见问题和其他
**问:T2A 是否完全移除模型使用?**
答:否。它意味着没有工具侧的嵌入式 LLM 调用。主机代理仍然执行推理。
**问:T2A 是内存数据库吗?**
答:否。`t2a-memory` 是第一个证明。T2A 是推理交接的协议。
**问:T2A 是 MCP 替换品吗?**
答:否。T2A 补充 MCP 和 A2A。
**问:T2A 是否仅限于 MCP 服务器?**
答:否。T2A 适用于可以发出推理交接的任何工具:CLI、API、SDK、CI 作业、工作流或 MCP 服务器。MCP 采样是 MCP 特有的;T2A 是具有胶囊、验证和提交/恢复的通用工具到代理交接模式。
**问:T2A 是代理框架吗?**
答:否。T2A 定义交接边界。
**问:为什么不直接调用 OpenAI/Anthropic 工具内部?**
答:因为用户可能已经有一个可信的主机代理,拥有模型访问权限。嵌入另一个模型调用迫使工具拥有提供商配置、凭证、计费、提示和恢复。T2A 将推理保留给主机代理,并使检查点可审计和可验证。
## T2A 一句话
> T2A 允许智能工具将推理交接给主机代理,而不是嵌入 LLM 调用。
## T2A 一个循环
```text
工具命中推理检查点
-> 发出 T2A 胶囊
-> 主机代理推理
-> 工具验证
-> 工作流恢复
```
如果这个边界引起共鸣,请给存储库加星,以关注协议、示例和 T2A 兼容的工具。
## 示例
- [integrations/t2a-memory/](integrations/t2a-memory/):一个内存工具记录确定性输入,主机代理合并它,工具验证并提交本地内存。您的代理获得内存。内存工具没有模型密钥。
- [examples/tool-author-minimal-cli/](examples/tool-author-minimal-cli/):一个小型可运行的工具作者示例,用一个本地 T2A 交接替换一个嵌入式模型调用路径。
- [examples/retrieval-brief/](examples/retrieval-brief/):一个检索工具收集有界证据,主机代理编写一个扎实的简报,发出工具可以验证源 ID。
- [examples/change-risk-review/](examples/change-risk-review/):一个变更工具记录确定性变更输入,主机代理分类风险,发出工具可以验证资源 ID 然后继续。
## 从源代码/开发
需要 Node.js 22 或更新版本。
核心 CLI 源代码快速开始:
```bash
cd cli
npm install
npm run build
node dist/index.js inspect ../examples/retrieval-brief/.t2a/tasks/demo
node dist/index.js validate ../examples/retrieval-brief/.t2a/tasks/demo
node dist/index.js continue ../examples/retrieval-brief/.t2a/tasks/demo
```
本地包烟雾测试:
```bash
cd cli
npm install
cd ../integrations/t2a-memory
npm install
npm run dogfood:pack-smoke
```
烟雾测试构建并打包两个本地包,将它们安装到临时工具主目录,模拟主机代理输出步骤,验证,提交,读取内存,并检查路径边界。参见 [integrations/t2a-memory/README.md](integrations/t2a-memory/README.md)。
## 存储库布局
- `spec/v0.1/`:规范协议文档。
- `schemas/v0.1/`:JSON Schema 2020-12 协议模式。
- `cli/`:用于本地胶囊检查、验证和继续指导的 TypeScript CLI。
- `docs/`:概念、快速入门、胶囊、交接、验证、继续、安全性和延迟/远程交接说明。
- `examples/`:本地胶囊示例。
- `skills/t2a/`:用于完成 T2A 胶囊的主机代理技能。
- `skills/t2a-tool-author/`:用于将一个工具推理检查点转换为 T2A 的编码代理技能。
- `prompts/`:用于主机代理和编码代理的复制粘贴提示。
- `templates/`:具体的 T2A 编写模板。
- `integrations/`:集成模板和说明。
- `integrations/t2a-memory/`:用户级内存证明和包烟雾流程。
- `scripts/dogfood/`:本地包烟雾测试。
- `conformance/`:实施者的验证夹具。
## 许可证
代码和规范材料根据 Apache License, Version 2.0 授权。
连接信息
猜你喜欢
暂无推荐服务器