# 大模型网关转发接口说明

> 依据：`doc/大模型对外API接口规范_0509.pdf`（OpenAI 兼容 `/v1`）  
> **本文档版本：1.4**（2026-05-25）

---

## 1. 用途

**baqing-admin** 在 `com.ruoyi.web.kb` 包内对外暴露与上游大模型网关 **相同路径** 的 OpenAI 兼容接口，由服务端配置 `ruoyi.kb` 中的上游地址与 API Key 并转发，供：

| 端 | 场景 |
| --- | --- |
| **管理端**（`ruoyi-ui`） | AI 在线接诊 / AI 诊断：`POST /v1/chat/completions` |
| **移动端**（`ruoyi-ui-app`） | AI 助手：`POST /v1/chat/completions` |

会话列表、消息落库仍走若依业务接口；**仅大模型问答**可走本转发层。

---

## 2. 接口列表

| 方法 | 路径 | 说明 |
| --- | --- | --- |
| GET | `/v1/models` | 模型列表，响应体原样转发 |
| POST | `/v1/chat/completions` | 对话补全；`stream: false` 返回 JSON，`stream: true` 返回 SSE |

**服务根地址示例**：`http://{host}:8010`（以 `server.port` 为准，默认 **8010**）。

**完整 URL 示例**：

- `http://localhost:8010/v1/models`
- `http://localhost:8010/v1/chat/completions`

---

## 3. 鉴权与安全

| 项 | 说明 |
| --- | --- |
| **本服务（8010）** | **必须**携带若依登录 Token：`Authorization: Bearer {token}`，与 `/diseaseTreatment/**`、`/app/**` 等业务接口一致；**未登录返回 401** |
| **实现** | `KbOpenAiProxyController` **无** `@Anonymous`，由 `JwtAuthenticationTokenFilter` + Spring Security 校验 |
| **上游大模型网关** | 由服务端 `ruoyi.kb.api-key` 写入转发请求的 `Authorization`，**不**将客户端 Header 中的 Token/Key 用于访问上游 |
| **直连上游（不经本服务）** | 仍可使用 `VUE_APP_LLM_API_KEY` / `LLM_API_KEY` 直连 `host:9107`（与本期转发鉴权策略无关） |
| **生产建议** | API Key 用环境变量 `RUOYI_KB_API_KEY` 注入；限制网关暴露面 |

**请求头（经本服务转发时）**

| 名称 | 必填 | 说明 |
| --- | --- | --- |
| `Authorization` | **是** | `Bearer` + 若依登录后 `getToken()` 返回值 |
| `Content-Type` | POST 必填 | `application/json` |

---

## 4. 配置项（`application.yml`）

前缀：**`ruoyi.kb`**（与知识库文件上传共用）

| 配置键 | 默认值 | 说明 |
| --- | --- | --- |
| `enabled` | `true` | `false` 时调用返回「大模型网关已关闭」 |
| `scheme` / `host` / `port` | 见 yml | 上游网关根地址 |
| `api-key` | 见 yml | 上游 Bearer Token |
| `auth-header-name` | `Authorization` | 上游鉴权头名称 |
| `connect-timeout-ms` | `15000` | 连接超时 |
| `read-timeout-ms` | `120000` | 非流式读超时 |
| `stream-read-timeout-ms` | `300000` | 流式 SSE 读超时 |

知识库文档接口路径为 `/api/v1/kb/**`，对话接口为 `/v1/**`，**共用同一主机、端口与 api-key**。

---

## 5. 请求 / 响应约定

与 **《大模型对外API接口规范_0509.pdf》** 一致（Body 字段不变）。

### 5.1 POST `/v1/chat/completions`

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `model` | string | 如 `auto`、`yak-disease` |
| `messages` | array | OpenAI 风格 `role` / `content` |
| `stream` | boolean | `false`：JSON；`true`：**Server-Sent Events（SSE）**，`Content-Type: text/event-stream` |
| `user` | string | 业务用户标识 |
| `session_id` | string | 多轮会话（上游返回后可回传） |

**SSE 约定（`stream: true`）**

| 项 | 说明 |
| --- | --- |
| 响应类型 | `text/event-stream; charset=UTF-8` |
| 事件格式 | 每行 `data: {json}`，事件以空行 `\n\n` 结束；结束可含 `data: [DONE]` |
| 响应头 | `Cache-Control: no-cache`、`Connection: keep-alive`、`X-Accel-Buffering: no`（禁反代缓冲） |
| 客户端 | 管理端/移动端使用 `fetch` + `Accept: text/event-stream` 解析（见 `llmStreamChat.js`） |

### 5.2 GET `/v1/models`

OpenAI 兼容模型列表 JSON，原样转发。

---

## 6. 前端接入（经本服务 8010 转发）

| 端 | 配置 | 鉴权 Header |
| --- | --- | --- |
| 管理端 | `VUE_APP_LLM_BASE_URL` → `http://localhost:8010`（或反代域名） | **`Authorization: Bearer {getToken()}`**，不可仅用大模型 `VUE_APP_LLM_API_KEY` |
| 移动端 | `LLM_PROXY_TARGET` → 业务网关 8010 | **`Authorization: Bearer {uni storage token}`**，不可仅用 `LLM_API_KEY` |

> 当前管理端 AI 页若仍用 `VUE_APP_LLM_API_KEY` 作为 `Authorization`，在走 8010 转发时会 **401**；需改为若依 Token（与 `request.js` 业务请求一致）。直连上游 `9107` 时仍可用大模型 Key。

---

## 7. 实现类（`com.ruoyi.web.kb`）

| 包路径 | 类 | 职责 |
| --- | --- | --- |
| `support` | `KbApiProperties` | `ruoyi.kb` 配置 |
| `support` | `KnowledgeBaseHttpConfig` | `kbRestTemplate` |
| `service.impl` | `KnowledgeBaseClientImpl` | 知识库 `/api/v1/kb/files` |
| `service.impl` | `KbOpenAiProxyServiceImpl` | 转发 `/v1/models`、`/v1/chat/completions` |
| `controller` | `KbOpenAiProxyController` | 对外 `GET/POST /v1/**`，**须登录** |

**关联文档**：

- `doc/牧业疫病诊疗服务/AI诊断(兽医、机构)/AI诊断(兽医、机构)前端技术方案.md` §4
- `doc/牧业疫病诊疗服务/AI诊断(兽医、机构)/AI诊断(兽医、机构)技术方案.md` §1.2
- `ruoyi-ui-app/doc/Ai.md`
- `doc/大模型/大模型网关转发测试用例.md`

---

## 8. 错误处理

| 场景 | HTTP / 表现 |
| --- | --- |
| 未带若依 Token / Token 无效 | **401**，与业务接口一致 |
| `ruoyi.kb.enabled=false` | 业务异常：网关已关闭 |
| 未配置 `api-key` | 业务异常：未配置密钥 |
| 上游 4xx/5xx（非流式） | 状态码与响应体原样转发 |
| 上游流式失败 | 上游错误体写入 SSE 输出 |

---

## 9. 修订记录

| 版本 | 日期 | 说明 |
| --- | --- | --- |
| 1.0 | 2026-05-25 | 初版 |
| 1.1 | 2026-05-25 | §7 子包结构；UT-006 |
| 1.2 | 2026-05-25 | UT-007 |
| 1.3 | 2026-05-25 | 修复 `PermitAllUrlProperties` PathPattern NPE（历史，曾配合 `@Anonymous`） |
| 1.4 | 2026-05-25 | **`/v1/**` 须若依 Token，取消匿名**；更新 §3、§6、§8 与前端鉴权说明 |
