# caizhi-AGP v2.1

**协议名称**：caizhi-AGP (财智记账 Agent Guide Protocol)  
**版本**：2.1  
**适用平台**：财智记账 (caizhi.tongyueim.com)  
**适用对象**：AI Agent / 调用财智 API 的程序

---

## 一、协议概述

### 1.1 协议目的

caizhi-AGP 是为 **AI Agent 与财智记账平台** 交互而制定的数据传输与行为规范文档。

**核心目标**：
1. 确保所有 Agent 在使用财智平台时遵循统一的操作流程
2. 保证数据准确性和操作规范性
3. **为 Agent 提供"零适配"接入体验**

### 1.2 适用范围

- 所有通过 HTTP API 调用财智记账服务的 AI Agent
- 通过 **MCP Server** 调用的 AI Agent
- Agent 代表用户执行记账、查询、统计操作
- Agent 获取财务数据

### 1.3 基本原则

1. **操作前必查** - 任何写入操作前必须先查询相关数据
2. **严格计算** - 数据统计必须用程序计算，禁止在文字生成中"顺带"写数字
3. **数据准确** - 记录和转述财务数据需准确
4. **用户知情** - 操作需让用户确认
5. **隐私保护** - 不可泄露用户财务数据
6. **错误透明** - 问题需清晰反馈
7. **平台不存语义**— 平台只做协议和数据，**不做 LLM 解析**

---

## 二、认证与身份

### 2.1 两种鉴权方式（并存）

| 场景 | 鉴权方式 | Header |
|------|----------|--------|
| **用户在浏览器/App 登录** | JWT Token | `Authorization: Bearer <jwt_token>` |
| **Agent 在 MCP Server 调用** | **API Key**| `X-API-Key: <api_key>` |

**优先级**：财智服务端 **优先看 X-API-Key**，没有再看 JWT。

### 2.2 与同月平台账号的关系

- 财智记账与同月平台**共用同一套用户体系**
- 一个同月账号 = 一个财智账号 = 一套数据
- 关键标识：**`tongyueNo`**（数字（如 <tongyueNo>））
- **财智只认 tongyueNo**，不认 UUID

### 2.3 JWT 登录

**POST /api/auth/login**

请求：
```json
{
  "user_id": "<tongyueNo>",
  "password": "<your_password>"
}
```

响应（成功）：
```json
{
  "success": true,
  "token": "<jwt_token>",
  "user": {
    "id": "<tongyueNo>",
    "name": "<your_name>"
  }
}
```

**Token Payload**：
```json
{
  "user_id": "<tongyueNo>",
  "tongyue_user_id": <tongyueNo>,
  "iat": <issued_at_timestamp>,
  "exp": <expires_at_timestamp>
}
```

后续请求：
```
Authorization: Bearer <jwt_token>
```

### 2.4 API Key 申请 ⭐

**核心流程**：
```
用户 → 同月平台申请 → 拿到 API Key → 配置到 Agent → Agent 调财智 API
         (X-API-Key)
```

**API Key 特性**：
- **一次性显示**：申请时返回明文 secret，**只显示一次**
- **前缀**：`sk-caizhi-` （类似 OpenAI 的 `sk-`）
- **存储**：同月数据库存 `key_hash`（SHA256），不存明文
- **作用域**：MVP 默认全权限，预留 `scopes` 字段
- **可撤销**：用户可主动 revoke
- **可观测**：记录 `last_used_at`

**申请流程**：

1. 用户登录同月平台
2. 进入 "Agent 集成" 页面
3. 点 "为我的 Claude 申请 API Key"
4. 输入 Key 名称（如 "我的 Claude Desktop"）
5. 同月生成 secret：`sk-caizhi-AbCdEf123...`
6. 用户**立即复制保存**（刷新后不再显示明文）
7. 用户把 secret 配到 Agent 的 MCP 配置

**API Key 调财智**：

```
POST https://caizhi.tongyueim.com/api/v1/expenses/create
Headers:
  X-API-Key: sk-caizhi-AbCdEf123...
  Content-Type: application/json
Body:
  {
    "category_id": 11,
    "amount": 27.40,
    "payment_method": "zfb",
    "date": "2026-06-05"
  }
```

**财智服务端处理**：
```
收到 X-API-Key
  ↓
调同月 /api/agent-key/verify
  ↓
拿到 tongyueNo = <your-tongyueNo>
  ↓
挂到 req.user.id
  ↓
正常业务处理
```

**4 个 API Key 接口**（同月平台）：

| 接口 | 方法 | 作用 |
|------|------|------|
| `/api/agent-key/apply` | POST | 申请 Key，返回明文 secret |
| `/api/agent-key/list` | GET | 查看自己的所有 Key（masked） |
| `/api/agent-key/revoke` | POST | 撤销 Key |
| `/api/agent-key/verify` | POST | **内部接口**，给财智用 |

### 2.5 鉴权失败处理

| 错误 | HTTP | 响应 |
|------|------|------|
| 缺 X-API-Key 和 JWT | 401 | `{success: false, error_code: "AUTH_MISSING", hint: "需要 X-API-Key 或 JWT Token"}` |
| X-API-Key 无效 | 401 | `{success: false, error_code: "INVALID_API_KEY", hint: "请到同月平台检查 Key 状态"}` |
| X-API-Key 已撤销 | 401 | `{success: false, error_code: "KEY_REVOKED", hint: "请重新申请"}` |
| JWT 过期 | 401 | `{success: false, error_code: "TOKEN_EXPIRED", hint: "请重新登录"}` |

---

## 三、类别体系

（此章节未变动）

### 3.1 三层结构

| 层级 | 区分方式 | 说明 |
|------|----------|------|
| 第一层 | type（income/expense）| 收入 / 支出 |
| 第二层 | 大类（parent_id=NULL）| 不可直接记账 |
| 第三层 | 细项（parent_id=大类id）| **记账时必须选这一层** |

**⚠️ Agent 必须选择第三层（细项）类别，不能选择大类。**

### 3.2 类别映射表

| 细项 ID | 名称 | 大类 | 适用场景 |
|---------|------|------|----------|
| 11 | 打车（出行）| 出行 | 出租车/网约车 |
| 12 | 地铁（出行）| 出行 | 地铁 |
| 13 | 公交（出行）| 出行 | 公共汽车 |
| 14 | 高铁火车（出行）| 出行 | 高铁/动车/火车 |
| 15 | 飞机（出行）| 出行 | 航班 |
| 16 | 早餐（餐饮）| 餐饮 | |
| 17 | 午餐（餐饮）| 餐饮 | |
| 18 | 晚餐（餐饮）| 餐饮 | |
| 21 | 下午茶（餐饮）| 餐饮 | |
| 72 | 小吃（餐饮）| 餐饮 | |
| 73 | 食材（餐饮）| 餐饮 | |
| 22 | 话费（通讯）| 通讯 | |
| 23 | 流量（通讯）| 通讯 | |
| 24 | 宽带（通讯）| 通讯 | |
| 25 | 日用品（购物）| 购物 | |
| 26 | 服饰（购物）| 购物 | |
| 27 | 电子产品（购物）| 购物 | |
| 28 | 房租（居住）| 居住 | |
| 29 | 水电煤（居住）| 居住 | |
| 30 | 物业（居住）| 居住 | |
| 31 | 游戏（娱乐）| 娱乐 | |
| 32 | 影视（娱乐）| 娱乐 | |
| 33 | 音乐会员（娱乐）| 娱乐 | |
| 34 | 运动健身（娱乐）| 娱乐 | |
| 35 | 体检（医疗）| 医疗 | |
| 36 | 药品（医疗）| 医疗 | |
| 37 | 门诊（医疗）| 医疗 | |
| 38 | 课程（教育）| 教育 | |
| 39 | 书籍（教育）| 教育 | |
| 40 | 培训（教育）| 教育 | |
| 41 | 礼物（人情）| 人情 | |
| 42 | 红包（人情）| 人情 | |
| 43 | 请客（人情）| 人情 | |
| 44 | 其他（其他）| 其他 | |

**Agent 提示**：使用 `category_id` 数字（**不要**传中文名）。

---

## 四、操作规范

### 4.1 记账操作流程（**init + create 两步**）

```
第一步：POST /api/v1/expenses/init
  → 拿到 categories 列表、字段要求、submit_endpoint

第二步：分析 init 响应，选择 category_id

第三步：POST {submit_endpoint} 提交数据
```

**为什么需要 init**：
- 拿到**最新的**类别表（避免硬编码过期）
- 拿到**字段要求**（payment_method 哪些可选）
- 拿到**submit_endpoint**（避免猜错地址）

**为什么不跳过 init**：
- 类别 ID 可能新增/废弃
- 直接硬编码会出错
- init 是"动态发现"的保证

### 4.2 MCP Server 调用

**MCP Server 是首选调用方式**，比直接 HTTP 更友好。

#### 配置示例

Claude Desktop 配置（`claude_desktop_config.json`）：
```json
{
  "mcpServers": {
    "caizhi": {
      "command": "npx",
      "args": ["-y", "caizhi-mcp-server"],
      "env": {
        "CAIZHI_API_KEY": "sk-caizhi-你的key",
        "CAIZHI_BASE": "https://mcp.caizhi.tongyueim.com"
      }
    }
  }
}
```

**stdio 模式**：本地运行，**不走公网流量**  
**SSE 模式**：公网 endpoint，零配置

---

### 五、MCP Tool Schemas

**这是 LLM 真正"看到"的部分**。tool description 已经内嵌 AGP 关键规则。

### 5.1 list_categories

**作用**：获取所有支出/收入类别（**Agent 自动发现用**）

**Tool Schema**：
```typescript
{
  name: "list_categories",
  description: `
    获取财智记账的所有支出/收入类别列表。
    
    【AGP 协议 v2 关键规则】
    - 必须返回细项类别（不是大类）
    - type 参数必填：'expense' 或 'income'
    - 返回的 category_id 是数字，记账时直接用
    
    使用场景：Agent 第一次记账前调用，确认类别 ID
  `,
  inputSchema: {
    type: "object",
    properties: {
      type: { 
        type: "string", 
        enum: ["expense", "income"],
        description: "类别类型：expense=支出，income=收入"
      }
    },
    required: ["type"]
  }
}
```

**返回**：
```json
{
  "success": true,
  "categories": [
    { "id": 11, "name": "打车", "parent_name": "出行", "icon": "🚕" },
    { "id": 12, "name": "地铁", "parent_name": "出行", "icon": "🚇" },
    ...
  ]
}
```

### 5.2 record_expense

**作用**：记一笔支出（**最常用**）

**Tool Schema**：
```typescript
{
  name: "record_expense",
  description: `
    记一笔支出到财智记账。
    
    【AGP 协议 v2 关键规则 - 必读】
    - category_id 必须是【细项类别】的 ID（如 11=打车, 16=早餐）
    - 不是大类 ID（不能用 1, 2 这种）
    - 不确定时，先调用 list_categories 查
    
    【字段规范】
    - category_id: 整数（细项）
    - amount: 数字，保留 2 位小数
    - payment_method: 'wx' | 'zfb' | 'card' | 'cash' 之一
      · wx = 微信支付
      · zfb = 支付宝
      · card = 银行卡
      · cash = 现金
    - date: YYYY-MM-DD 格式
    - note: 备注（可选）
    
    【使用流程】
    1. 如不知 category_id，先调 list_categories
    2. 调 init 拿最新字段要求（可选）
    3. 调本接口提交
    
    成功返回：{ success: true, data: { id, amount, ... } }
  `,
  inputSchema: {
    type: "object",
    properties: {
      category_id: { 
        type: "integer",
        description: "细项类别ID（必填）"
      },
      amount: { 
        type: "number",
        description: "金额（必填，2位小数）"
      },
      payment_method: { 
        type: "string", 
        enum: ["wx", "zfb", "card", "cash"],
        description: "支付方式（必填）"
      },
      date: { 
        type: "string",
        description: "日期 YYYY-MM-DD（必填）"
      },
      note: { 
        type: "string",
        description: "备注（可选）"
      }
    },
    required: ["category_id", "amount", "payment_method", "date"]
  }
}
```

### 5.3 record_income

（同 record_expense，type=income）

### 5.4 get_balance

**作用**：查询当前余额

**Tool Schema**：
```typescript
{
  name: "get_balance",
  description: `
    查询当前用户的总余额。
    
    【AGP 协议 v2】
    - 返回 snapshot_balance（5月底快照）+
            this_month_income（本月收入）-
            this_month_expenses（本月支出）
    - 单位：元，2 位小数
    
    使用场景：用户问"我还有多少钱"
  `,
  inputSchema: {
    type: "object",
    properties: {}
  }
}
```

---

## 六、字段规范

| 字段 | 类型 | 必填 | 说明 | 示例 |
|------|------|------|------|------|
| date | string | ✅ | YYYY-MM-DD | "2026-06-05" |
| category_id | integer | ✅ | **细项**类别 ID | 11 |
| amount | number | ✅ | 数字，2位小数 | 27.40 |
| payment_method | string | ✅ | wx/zfb/card/cash | "zfb" |
| merchant | string | ❌ | 商户名称 | "肯德基" |
| note | string | ❌ | 备注 | "午餐" |
| tags | array | ❌ | 标签 | ["餐饮"] |

**支付方式映射**（必填，**不能**传中文）：
- 微信支付 → `wx`
- 支付宝 → `zfb`
- 银行卡 → `card`
- 现金 → `cash`

---

## 七、错误处理（Agent 友好）

### 7.1 错误响应格式

```json
{
  "success": false,
  "error_code": "STANDARD_CODE",
  "error": "人类可读描述",
  "hint": "Agent 可读的修复建议",
  "docs_url": "https://docs.caizhi.tongyueim.com/errors/CODE"
}
```

### 7.2 标准错误码（Agent 友好版）

| error_code | HTTP | error | hint |
|------------|------|-------|------|
| `AUTH_MISSING` | 401 | 缺少鉴权 | "需要 X-API-Key header 或 Authorization Bearer token" |
| `INVALID_API_KEY` | 401 | API Key 无效 | "请到同月平台检查 Key 状态或重新申请" |
| `KEY_REVOKED` | 401 | Key 已撤销 | "请重新申请 API Key" |
| `TOKEN_EXPIRED` | 401 | JWT 过期 | "请用户重新登录" |
| `CATEGORY_NOT_FOUND` | 400 | 类别不存在 | "调用 list_categories 拿最新类别 ID" |
| `INVALID_AMOUNT` | 400 | 金额格式错 | "amount 应为数字，如 27.40" |
| `MISSING_REQUIRED` | 400 | 缺必填字段 | "必填: category_id, amount, payment_method, date" |
| `DATE_FORMAT_ERROR` | 400 | 日期格式错 | "date 格式应为 YYYY-MM-DD" |
| `INVALID_PAYMENT_METHOD` | 400 | 支付方式错 | "payment_method 应为 wx/zfb/card/cash 之一" |
| `NOT_FOUND` | 404 | 记录不存在 | "检查 ID 是否正确" |
| `RATE_LIMIT_EXCEEDED` | 429 | 调用太频繁 | "60 秒后再试" |
| `INTERNAL_ERROR` | 500 | 服务异常 | "请稍后重试，或联系管理员" |

### 7.3 错误转述模板

| 场景 | Agent 转述 |
|------|-----------|
| 成功 | "[操作]成功" |
| 简单失败 | "[操作]失败：[error]" |
| 有建议 | "[操作]失败：[error]。请[hint]" |
| 带文档 | "[操作]失败：[error]。参考：{docs_url}" |

---

## 八、永久记忆内容（Agent 必须记住）

**Agent 启动时把以下内容注入到自己的 MEMORY.md**：

```
# 财智记账 AGP v2 必记规则

1. **鉴权**：
   - 优先用 X-API-Key（Agent 场景）
   - 用户登录用 Authorization: Bearer JWT

2. **记账流程**：
   - 第一步：POST /api/v1/expenses/init（拿最新类别和字段）
   - 第二步：POST /api/v1/expenses/create（提交数据）
   - 不能跳过 init

3. **类别规则**：
   - category_id 必须是【细项】ID（如 11=打车）
   - 不能用大类 ID（1=出行）
   - 不确定时调 list_categories

4. **字段规范**：
   - date: YYYY-MM-DD
   - amount: 数字，2位小数
   - payment_method: wx/zfb/card/cash（不能传中文）

5. **错误处理**：
   - 看到 error_code 字段（不是 error 字符串）
   - 用 hint 字段指导用户

6. **MCP 优先**：
   - 优先用 MCP Server 接入（标准化）
   - LLM 看到的 tool description 已含 AGP 规则
```

---

## 九、API 接口完整参考

### 9.1 认证

| 接口 | 方法 | 鉴权 | 功能 |
|------|------|------|------|
| `/api/auth/login` | POST | 无 | 登录拿 JWT |
| `/api/agent-key/apply` | POST | JWT | 申请 API Key（同月） |
| `/api/agent-key/list` | GET | JWT | 查看 Key 列表（同月） |
| `/api/agent-key/revoke` | POST | JWT | 撤销 Key（同月） |
| `/api/agent-key/verify` | POST | 内部 | 验证 Key 拿 tongyueNo |

### 9.2 支出

| 接口 | 方法 | 鉴权 | 功能 |
|------|------|------|------|
| `/api/v1/expenses/init` | POST | JWT/X-API-Key | 拿字段和类别 |
| `/api/v1/expenses/create` | POST | JWT/X-API-Key | 创建支出 |
| `/api/v1/expenses` | GET | JWT/X-API-Key | 列表 |
| `/api/v1/expenses/:id` | GET | JWT/X-API-Key | 单条 |
| `/api/v1/expenses/:id` | PUT | JWT/X-API-Key | 更新 |
| `/api/v1/expenses/:id` | DELETE | JWT/X-API-Key | 删除 |

### 9.3 收入

| 接口 | 方法 | 鉴权 | 功能 |
|------|------|------|------|
| `/api/v1/incomes` | POST | JWT/X-API-Key | 创建 |
| `/api/v1/incomes` | GET | JWT/X-API-Key | 列表 |
| `/api/v1/incomes/:id` | PUT/DELETE | JWT/X-API-Key | 更新/删除 |

### 9.4 类别

| 接口 | 方法 | 鉴权 | 功能 |
|------|------|------|------|
| `/api/v1/categories` | GET | JWT/X-API-Key | 类别树 |
| `/api/v1/categories` | POST | JWT/X-API-Key | 创建私有 |
| `/api/v1/categories/:id` | PUT | JWT/X-API-Key | 更新私有 |
| `/api/v1/categories/:id` | DELETE | JWT/X-API-Key | 删除私有 |

### 9.5 余额

| 接口 | 方法 | 鉴权 | 功能 |
|------|------|------|------|
| `/api/v1/balance` | GET | JWT/X-API-Key | 当前余额 |

---

## 十、MCP Server 集成（已部署）⭐

### 10.1 官方 MCP Server（推荐使用）

财智记账提供官方 **MCP Server**（`caizhi-mcp-server`），让 Claude Desktop / Cursor / Cline / Continue 等任何支持 MCP 协议的 AI 客户端能**以调用本地函数的方式调财智 API**。

- **本项目位置**：`D:\OpenClawData\.openclaw\workspace\caizhi-mcp-server\`
- **服务器位置**：`/home/admin/caizhi-mcp-server/`
- **零依赖** — 纯 Node.js 18+ 原生 fetch
- **协议** — JSON-RPC 2.0 over stdio

### 10.2 工具清单（7 个）

| # | 工具 | 说明 |
|---|------|------|
| 1 | `caizhi_init_expense` | 获取支出记账引导（**调用 create 前必先调**）|
| 2 | `caizhi_init_income` | 获取收入记账引导 |
| 3 | `caizhi_create_expense` | 提交支出 |
| 4 | `caizhi_create_income` | 提交收入 |
| 5 | `caizhi_get_balance` | 查询余额 |
| 6 | `caizhi_list_categories` | 列出类别（带 10min 缓存）|
| 7 | `caizhi_quick_record` | 一键记账（自动路由 expense/income）|

### 10.3 端到端流程

```
用户: "记一笔打车27.4元"
  ↓
Claude Desktop (LLM)
  ↓ 看到 tool schema（来自 MCP tools/list）
  ↓ 推理出 {category_id: 11, amount: 27.4, payment_method: "zfb"}
  ↓
MCP Server (caizhi-mcp-server)
  ↓ 调财智 API，带 X-API-Key: sk-caizhi-xxx
  ↓
财智 API
  ↓ X-API-Key → 调同月 verify → 拿 tongyueNo=<your-tongyueNo>
  ↓ INSERT INTO expenses
  ↓
返回 {success: true, id: 119}
  ↓
LLM: "已记录：打车 27.40 元"
```

### 10.4 部署模式

| 模式 | 状态 | 说明 |
|------|------|------|
| **stdio** | ✅ **已部署** | 用户本地或服务器 `/home/admin/caizhi-mcp-server/src/index.js` |
| **SSE** | ⏸️ 未部署 | 计划中：MCP stdio 不支持推送，SSE 模式待设计 |

**当前推荐**：用 stdio 模式。Agent 通过 MCP client 启动 stdio 进程，无需服务器暴露端口。

### 10.5 Claude Desktop 配置示例（stdio 模式）

```json
{
  "mcpServers": {
    "caizhi": {
      "command": "node",
      "args": ["D:/OpenClawData/.openclaw/workspace/caizhi-mcp-server/src/index.js"],
      "env": {
        "CAIZHI_API_KEY": "sk-caizhi-你的key"
      }
    }
  }
}
```

**获取 API Key**：
```bash
# 1) 登录同月平台
curl -X POST https://www.tongyueim.com/api/users/login \
  -H "Content-Type: application/json" \
  -d '{"login":"<邮箱>","password":"<密码>"}'

# 2) 用 JWT 申请 Key
curl -X POST https://www.tongyueim.com/api/agent-key/apply \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{"name":"我的 Claude Desktop"}'
# 响应里的 secret 就是 sk-caizhi-xxxxx（只显示一次，妥善保存）
```

### 10.6 安全设计

1. **API Key 永不明文返** — `agent-key/list` 只返 prefix
2. **错误码完整** — 业务错误返 `isError: true` + `code + hint` 让 Agent 自我纠错
3. **并发请求** — 多个工具调用并行不阻塞
4. **Buffer 10MB 上限** — 防 DoS
5. **SIGTERM 优雅退出** — 等 in-flight 请求最多 3 秒

---

## 十一、AGP 协议自身获取（B 方案）⭐⭐

### 11.1 问题

财智 AGP 文档本身 14,595 字符。如果在**每次登录**或**每次 Agent 启动**都把全文作为 prompt 注入，会浪费**~10K token**（中文为主）。

### 11.2 解决方案（B 方案）

**B 方案 = 被动元数据 + 主动拉取 + ETag 缓存**（类似 HTTP 缓存标准）：

1. **登录响应**只返 AGP 元数据（约 100 字节），不返 content
2. **Agent 决策**是否需要拉取
3. **主动拉取**走标准 HTTP 缓存：
   - 首次 `GET /api/v1/agp` → 200 + 完整 content + ETag header
   - 后续 `GET` + `If-None-Match: "<etag>"` → **304 Not Modified**（0 字节 body）
4. **元数据快速校验**走 `?format=metadata`（仅返元数据，<300 字符）

### 11.3 三种接入方式对比

| 方式 | 响应大小 | 适用场景 |
|------|----------|----------|
| **登录响应** | ~440 字符 | 拿 URL + version + checksum，Agent 决策 |
| **`GET /api/v1/agp`** | 14,595 字符（首次）<br>0 字节（304 命中）| Agent 拉取完整规范 |
| **`GET /api/v1/agp?format=metadata`** | ~280 字符 | 快速校验版本/校验和 |

### 11.4 完整示例

**Step 1：Agent 首次登录**
```bash
POST /api/auth/login
→ 200 OK
{
  "token": "eyJ...",
  "user": {...},
  "AGP": {
    "url": "https://caizhi.tongyueim.com/api/v1/agp",
    "version": "2.1",
    "checksum": "sha256:9f89f6a99de71...",
    "content_length": 14595
  }
}
```

**Step 2：Agent 主动拉取（如需）**
```bash
GET /api/v1/agp
→ 200 OK
ETag: "9f89f6a99de719fe870d3da350c94712d438896d82fe80cf1faa8a14e13aed0f"
{
  "data": {
    "filename": "caizhi-AGP-v2.md",
    "version": "2.1",
    "content": "... 14,595 字符完整 AGP ...",
    "checksum": "sha256:9f89f6a99de71..."
  }
}
```

**Step 3：Agent 后续拉取（带 ETag）**
```bash
GET /api/v1/agp
If-None-Match: "9f89f6a99de71..."
→ 304 Not Modified
（无 body）
```

**Step 4：AGP 更新后（自动拿到新内容）**
```bash
GET /api/v1/agp
If-None-Match: "旧 etag"
→ 200 OK + 新 content + 新 ETag
```

### 11.5 为什么选 B 方案

| 方案 | token 成本 | 实现复杂度 | 推荐度 |
|------|-----------|-----------|--------|
| **A：被动全量**（旧方案） | ~10K / 登录 | ⭐ | ❌ |
| **B：被动元数据 + 主动拉 + ETag** | ~150 / 登录 | ⭐⭐ | ✅ **推荐** |
| **C：DB 记录"是否已发"** | ~10K / 首次 | ⭐⭐⭐ | ❌（过度设计）|

B 方案的优势：
- **完全符合 HTTP 缓存标准**（OpenID Connect Discovery、JSON Schema Registry 都是这么做）
- **零状态**（不需要 DB 字段记录"用户是否拿过"）
- **Agent 决策**（Agent 拿到元数据后自己决定要不要拉）
- **代价最小**（登录响应只多 ~100 字节）

### 11.6 字段含义

| 字段 | 含义 | 用途 |
|------|------|------|
| `url` | AGP 拉取端点 | Agent 决定要不要 fetch |
| `version` | 文档版本（语义化）| Agent 判断是否过期 |
| `checksum` | SHA256 完整哈希 | Agent 校验完整性（去重用）|
| `content_length` | 文档字符数 | Agent 估算拉取代价 |

### 11.7 与同月 AGP 的协同

- **同月 AGP**：登录时同月返回自己的 AGP 元数据
- **财智 AGP**：登录时财智返回自己的 AGP 元数据
- **Agent 同时拿到两个 URL**，独立决定是否需要 fetch

### 11.8 与 MCP Server 的关系

- AGP 文档定义了**接口规范**（HTTP REST）
- MCP Server 是 **AGP 的 LLM-friendly 包装**（JSON Schema 工具定义）
- 两者**互补不冲突**：Agent 既可走 MCP（推荐），也可直接读 AGP 调 HTTP

---

## 十二、版本历史

| 版本 | 日期 | 更新内容 |
|------|------|----------|
| **2.0** | 2026-06-05 | API Key 鉴权 + MCP Server 集成 + 错误码标准化 |
| **2.1** | 2026-06-06 | §10 修正为 stdio 实际部署 + §11 新增 B 方案（被动元数据 + 主动拉取 + ETag） |

---

## 附录 A：完整类别 ID 速查表

| 类别 | 细项 ID | 名称 |
|------|---------|------|
| 出行 | 11 | 打车 |
| 出行 | 12 | 地铁 |
| 出行 | 13 | 公交 |
| 出行 | 14 | 高铁火车 |
| 出行 | 15 | 飞机 |
| 餐饮 | 16 | 早餐 |
| 餐饮 | 17 | 午餐 |
| 餐饮 | 18 | 晚餐 |
| 餐饮 | 21 | 下午茶 |
| 餐饮 | 72 | 小吃 |
| 餐饮 | 73 | 食材 |
| 通讯 | 22 | 话费 |
| 通讯 | 23 | 流量 |
| 通讯 | 24 | 宽带 |
| 购物 | 25 | 日用品 |
| 购物 | 26 | 服饰 |
| 购物 | 27 | 电子产品 |
| 居住 | 28 | 房租 |
| 居住 | 29 | 水电煤 |
| 居住 | 30 | 物业 |
| 娱乐 | 31 | 游戏 |
| 娱乐 | 32 | 影视 |
| 娱乐 | 33 | 音乐会员 |
| 娱乐 | 34 | 运动健身 |
| 医疗 | 35 | 体检 |
| 医疗 | 36 | 药品 |
| 医疗 | 37 | 门诊 |
| 教育 | 38 | 课程 |
| 教育 | 39 | 书籍 |
| 教育 | 40 | 培训 |
| 人情 | 41 | 礼物 |
| 人情 | 42 | 红包 |
| 人情 | 43 | 请客 |
| 其他 | 44 | 其他 |

---

**本文档由财智记账平台制定，解释权归财智记账平台所有。**
