docs: 更新三份 README 文档以反映实际项目情况
This commit is contained in:
@@ -116,8 +116,11 @@ backend/
|
||||
├── migrations/ # 数据库迁移
|
||||
│ └── 20260421000001_initial_schema.sql
|
||||
├── tests/ # 集成测试
|
||||
│ ├── helpers.go
|
||||
│ └── integration/
|
||||
│ ├── helpers.go # 测试辅助函数
|
||||
│ ├── config/ # 测试配置
|
||||
│ ├── integration/ # 集成测试
|
||||
│ │ └── e2e_conversion_test.go # E2E 协议转换测试
|
||||
│ └── mocks/ # Mock 实现
|
||||
├── Makefile
|
||||
├── go.mod
|
||||
└── README.md
|
||||
@@ -146,6 +149,120 @@ Client Request (clientProtocol)
|
||||
|
||||
同协议时自动透传,跳过序列化开销。
|
||||
|
||||
## 协议转换架构
|
||||
|
||||
### Canonical Model 中间表示
|
||||
|
||||
所有协议转换都经过 Canonical Model 中间表示层,实现 Hub-and-Spoke 架构:
|
||||
|
||||
```
|
||||
OpenAI Request → Canonical Request → Anthropic Request
|
||||
(中间表示)
|
||||
OpenAI Response ← Canonical Response ← Anthropic Response
|
||||
```
|
||||
|
||||
**CanonicalRequest 核心字段**:
|
||||
- `Model` - 统一模型 ID
|
||||
- `Messages` - 消息列表(支持 text、tool_use、tool_result、thinking 类型)
|
||||
- `Tools` - 工具定义
|
||||
- `Thinking` - 推理配置(`budget_tokens`、`effort`)
|
||||
- `Parameters` - 通用参数(`max_tokens`、`temperature`、`top_p` 等)
|
||||
|
||||
### Smart Passthrough 机制
|
||||
|
||||
同协议请求走 Smart Passthrough 路径,**零序列化开销**:
|
||||
|
||||
```
|
||||
1. 检测 clientProtocol == providerProtocol
|
||||
2. 仅改写请求体中的 model 字段:unified_id → upstream_model_name
|
||||
3. 直接转发请求到上游
|
||||
4. 响应中仅改写 model 字段:upstream_model_name → unified_id
|
||||
```
|
||||
|
||||
### 流式转换器层次
|
||||
|
||||
```
|
||||
StreamConverter (接口)
|
||||
├── PassthroughStreamConverter # 直接透传,无任何处理
|
||||
├── SmartPassthroughStreamConverter # 同协议 + 逐 chunk 改写 model
|
||||
└── CanonicalStreamConverter # 跨协议完整转换(decode → encode)
|
||||
```
|
||||
|
||||
### InterfaceType 枚举
|
||||
|
||||
| 类型 | 说明 |
|
||||
|------|------|
|
||||
| `CHAT` | 对话补全(chat/completions、messages) |
|
||||
| `MODELS` | 模型列表 |
|
||||
| `MODEL_INFO` | 模型详情 |
|
||||
| `EMBEDDINGS` | 嵌入接口 |
|
||||
| `RERANK` | 重排序接口 |
|
||||
| `PASSTHROUGH` | 未知接口,直接透传 |
|
||||
|
||||
## 协议适配器特性
|
||||
|
||||
### OpenAI 适配器
|
||||
|
||||
**特有字段支持**:
|
||||
- `reasoning_effort` - 映射到 Canonical Thinking 配置(`none` → 禁用,其他 → `effort`)
|
||||
- `reasoning_content` - 非标准字段,映射到 Canonical thinking 块
|
||||
- `max_completion_tokens` - 新字段,优先于 `max_tokens`
|
||||
- `refusal` - 非标准字段,作为 text 块处理
|
||||
|
||||
**废弃字段兼容**:
|
||||
- `functions` / `function_call` - 自动转换为 `tools` / `tool_choice`
|
||||
|
||||
**消息处理**:
|
||||
- 合并连续同角色消息(Anthropic 不支持连续同角色)
|
||||
- 工具选择映射:`any` → `required`
|
||||
|
||||
### Anthropic 适配器
|
||||
|
||||
**特有字段支持**:
|
||||
- `thinking` - 推理配置(`type: enabled`、`budget_tokens`、`effort`)
|
||||
- `output_config` - 结构化输出配置
|
||||
- `disable_parallel_tool_use` - 禁用并行工具调用
|
||||
- `container` - 工具容器字段
|
||||
|
||||
**不支持的功能**:
|
||||
- Embeddings 接口(返回 `INTERFACE_NOT_SUPPORTED` 错误)
|
||||
|
||||
### 跨协议转换注意事项
|
||||
|
||||
| 源协议 | 目标协议 | 转换说明 |
|
||||
|--------|----------|----------|
|
||||
| OpenAI | Anthropic | `reasoning_effort` → `thinking`,消息角色合并 |
|
||||
| Anthropic | OpenAI | `thinking` 块 → `reasoning_content`,工具选择转换 |
|
||||
|
||||
## 错误码
|
||||
|
||||
### ConversionError 错误码
|
||||
|
||||
| 错误码 | 说明 |
|
||||
|--------|------|
|
||||
| `INVALID_INPUT` | 输入数据无效 |
|
||||
| `MISSING_REQUIRED_FIELD` | 缺少必填字段 |
|
||||
| `INCOMPATIBLE_FEATURE` | 功能不兼容(如跨协议不支持某特性) |
|
||||
| `FIELD_MAPPING_FAILURE` | 字段映射失败 |
|
||||
| `TOOL_CALL_PARSE_ERROR` | 工具调用解析错误 |
|
||||
| `JSON_PARSE_ERROR` | JSON 解析错误 |
|
||||
| `STREAM_STATE_ERROR` | 流式状态错误 |
|
||||
| `UTF8_DECODE_ERROR` | UTF-8 解码错误(流式 chunk 截断) |
|
||||
| `PROTOCOL_CONSTRAINT_VIOLATION` | 协议约束违反 |
|
||||
| `ENCODING_FAILURE` | 编码失败 |
|
||||
| `INTERFACE_NOT_SUPPORTED` | 接口不支持(如 Anthropic Embeddings) |
|
||||
|
||||
### AppError 预定义错误
|
||||
|
||||
| 错误 | HTTP 状态码 | 说明 |
|
||||
|------|-------------|------|
|
||||
| `ErrModelNotFound` | 404 | 模型未找到 |
|
||||
| `ErrModelDisabled` | 404 | 模型已禁用 |
|
||||
| `ErrProviderNotFound` | 404 | 供应商未找到 |
|
||||
| `ErrInvalidProviderID` | 400 | 供应商 ID 格式无效 |
|
||||
| `ErrDuplicateModel` | 409 | 同一供应商下模型名称重复 |
|
||||
| `ErrImmutableField` | 400 | 不可修改字段(如供应商 ID) |
|
||||
|
||||
## 运行方式
|
||||
|
||||
### 安装依赖
|
||||
@@ -278,10 +395,10 @@ goose -dir migrations sqlite3 ~/.nex/config.db up
|
||||
#### OpenAI 协议
|
||||
|
||||
```
|
||||
POST /openai/v1/chat/completions
|
||||
GET /openai/v1/models
|
||||
POST /openai/v1/embeddings
|
||||
POST /openai/v1/rerank
|
||||
POST /openai/chat/completions
|
||||
GET /openai/models
|
||||
POST /openai/embeddings
|
||||
POST /openai/rerank
|
||||
```
|
||||
|
||||
#### Anthropic 协议
|
||||
@@ -322,7 +439,7 @@ GET /anthropic/v1/models
|
||||
- Anthropic 协议:配置到域名,不包含版本路径,如 `https://api.anthropic.com`
|
||||
|
||||
**对外 URL 格式**:
|
||||
- OpenAI 协议:`/{protocol}/{endpoint}`,如 `/openai/chat/completions`、`/openai/models`
|
||||
- OpenAI 协议:`/{protocol}/{endpoint}`,如 `/openai/chat/completions`、`/openai/models`、`/openai/embeddings`
|
||||
- Anthropic 协议:`/{protocol}/v1/{endpoint}`,如 `/anthropic/v1/messages`、`/anthropic/v1/models`
|
||||
|
||||
#### 模型管理
|
||||
|
||||
Reference in New Issue
Block a user