Cherry Studio 客户端优化
All checks were successful
Build and Push OCI GenAI Gateway Docker Image / docker-build-push (push) Successful in 35s

This commit is contained in:
2025-12-10 17:40:43 +08:00
parent 0840f35408
commit 95722c97e4
10 changed files with 1515 additions and 69 deletions

View File

@@ -0,0 +1,354 @@
# Cherry Studio 客户端优化
本文档说明针对 Cherry Studio 客户端的专属优化功能。
## 优化内容
### 1. 客户端名称日志显示
**功能描述**
- 从请求头 `x-title` 中提取客户端名称
- 在日志中显示客户端信息,便于追踪和调试
- 支持任何设置 `x-title` 头的客户端,不限于 Cherry Studio
**日志格式**
```
2025-12-10 15:09:17 - api.routers.chat - INFO - Chat completion request for model: google.gemini-2.5-pro, client: Cherry Studio
```
**实现位置**
- [src/api/routers/chat.py](../src/api/routers/chat.py#L295-L296)
**使用示例**
```bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-oci-genai-default-key" \
-H "x-title: Cherry Studio" \
-d '{
"model": "google.gemini-2.5-pro",
"messages": [{"role": "user", "content": "Hello"}]
}'
```
### 2. thinking_budget 到 reasoning_effort 的自动映射
**功能描述**
- Cherry Studio 使用 Google Gemini 的 `thinking_budget` 参数控制推理深度
- 网关自动将 `thinking_budget` 映射到 OCI SDK 的 `reasoning_effort` 参数
- 支持 meta、xai、google、openai 提供商的模型(不支持 Cohere
- 对其他客户端透明,不影响标准 OpenAI API 兼容性
**映射规则**
| thinking_budget 值 | reasoning_effort | 说明 |
|-------------------|------------------|------|
| ≤ 1760 | `low` | 快速响应,较少推理 |
| 1760 < X ≤ 16448 | `medium` | 平衡速度和推理深度 |
| > 16448 | `high` | 深度推理,更完整的答案 |
| -1 | None | 使用模型默认值 |
**extra_body 结构**
Cherry Studio 通过 `extra_body` 传递 Google Gemini 特定的配置:
```json
{
"model": "google.gemini-2.5-pro",
"messages": [...],
"extra_body": {
"google": {
"thinking_config": {
"thinking_budget": 1760,
"include_thoughts": true
}
}
}
}
```
**实现位置**
- 映射函数: [src/api/routers/chat.py](../src/api/routers/chat.py#L37-L102)
- `map_thinking_budget_to_reasoning_effort()` - 将 thinking_budget 数值映射到 reasoning_effort 枚举值
- `extract_reasoning_effort_from_extra_body()` - 从 extra_body 中提取 thinking_budget 并执行映射
- OCI 客户端: [src/core/oci_client.py](../src/core/oci_client.py#L333-L336)
**日志输出**
```
2025-12-10 15:09:17 - api.routers.chat - INFO - Chat completion request for model: google.gemini-2.5-pro, client: Cherry Studio
2025-12-10 15:09:17 - api.routers.chat - INFO - Cherry Studio thinking_budget 1760 mapped to reasoning_effort: low
2025-12-10 15:09:17 - core.oci_client - INFO - Setting reasoning_effort to LOW for google model
```
## Cherry Studio 使用示例
### 基本对话
```bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-oci-genai-default-key" \
-H "x-title: Cherry Studio" \
-d '{
"model": "google.gemini-2.5-pro",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}'
```
### 使用 thinking_budget (低推理深度)
```bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-oci-genai-default-key" \
-H "x-title: Cherry Studio" \
-d '{
"model": "google.gemini-2.5-pro",
"messages": [
{"role": "user", "content": "What is 2+2?"}
],
"extra_body": {
"google": {
"thinking_config": {
"thinking_budget": 1000
}
}
}
}'
```
### 使用 thinking_budget (中等推理深度)
```bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-oci-genai-default-key" \
-H "x-title: Cherry Studio" \
-d '{
"model": "google.gemini-2.5-pro",
"messages": [
{"role": "user", "content": "Explain quantum entanglement"}
],
"extra_body": {
"google": {
"thinking_config": {
"thinking_budget": 5000
}
}
}
}'
```
### 使用 thinking_budget (高推理深度)
```bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-oci-genai-default-key" \
-H "x-title: Cherry Studio" \
-d '{
"model": "google.gemini-2.5-pro",
"messages": [
{"role": "user", "content": "Solve this complex math problem: ..."}
],
"extra_body": {
"google": {
"thinking_config": {
"thinking_budget": 20000
}
}
}
}'
```
## 验证日志
启动服务并查看日志以验证 Cherry Studio 优化功能:
```bash
# 启动服务(开发模式)
cd src
python main.py
# 查看日志(另一个终端)
tail -f logs/app.log | grep -E "(client:|thinking_budget|reasoning_effort)"
```
期望看到的日志:
```
2025-12-10 15:09:17 - api.routers.chat - INFO - Chat completion request for model: google.gemini-2.5-pro, client: Cherry Studio
2025-12-10 15:09:17 - api.routers.chat - INFO - Cherry Studio thinking_budget 1760 mapped to reasoning_effort: low
2025-12-10 15:09:17 - core.oci_client - INFO - Setting reasoning_effort to LOW for google model
```
## 技术实现
### Schema 变更
在 [src/api/schemas.py](../src/api/schemas.py) 中添加了 `extra_body` 字段:
```python
class ChatCompletionRequest(BaseModel):
# ... 其他字段 ...
extra_body: Optional[Dict[str, Any]] = None # Cherry Studio and other client extensions
```
### 映射函数
实现了两个工具函数来处理 Cherry Studio 的 thinking_budget
1. **map_thinking_budget_to_reasoning_effort**: 将 thinking_budget 数值映射到 reasoning_effort 枚举值
2. **extract_reasoning_effort_from_extra_body**: 从 extra_body 中提取 thinking_budget 并执行映射
```python
def map_thinking_budget_to_reasoning_effort(thinking_budget: int) -> Optional[str]:
"""Map Cherry Studio's thinking_budget to OCI's reasoning_effort parameter."""
if thinking_budget == -1:
return None
elif thinking_budget <= 1760:
return "low"
elif thinking_budget <= 16448:
return "medium"
else:
return "high"
def extract_reasoning_effort_from_extra_body(extra_body: Optional[dict]) -> Optional[str]:
"""Extract reasoning_effort from Cherry Studio's extra_body parameter."""
if not extra_body:
return None
try:
google_config = extra_body.get("google", {})
thinking_config = google_config.get("thinking_config", {})
thinking_budget = thinking_config.get("thinking_budget")
if thinking_budget is not None and isinstance(thinking_budget, (int, float)):
effort = map_thinking_budget_to_reasoning_effort(int(thinking_budget))
if effort:
logger.info(f"Cherry Studio thinking_budget {thinking_budget} mapped to reasoning_effort: {effort}")
return effort
except (AttributeError, TypeError, KeyError) as e:
logger.debug(f"Failed to extract thinking_budget from extra_body: {e}")
return None
```
### OCI SDK 集成
更新了 `OCIGenAIClient.chat()` 方法和 `_build_generic_request()` 方法,支持传递 `reasoning_effort` 参数到 OCI SDK 的 `GenericChatRequest`
## 兼容性
### 支持的模型
**reasoning_effort 参数支持**(通过 thinking_budget 映射):
- ✅ Google Gemini 模型 (google.gemini-2.5-pro, google.gemini-2.0-flash-exp)
- ✅ Meta Llama 模型 (meta.llama-3.1-405b-instruct, meta.llama-3.2-90b-vision-instruct)
- ✅ xAI 模型
- ✅ OpenAI 模型
- ❌ Cohere 模型(不支持 reasoning_effort 参数)
**注意**: reasoning_effort 是可选参数,如果模型不支持,会自动忽略并记录警告日志。
### 向后兼容性
- ✅ 不提供 `extra_body` 时,行为与之前完全一致
- ✅ 不提供 `x-title` 时,客户端名称显示为 "Unknown"
- ✅ 其他客户端不受影响,可以继续正常使用
- ✅ 标准 OpenAI API 兼容性完全保留
### 与其他客户端的兼容性
虽然此优化专为 Cherry Studio 设计,但实现方式确保了:
1. **其他客户端不受影响**:不使用 `extra_body.google.thinking_config` 的客户端完全不受影响
2. **标准 API 兼容**:所有标准 OpenAI API 功能仍然正常工作
## 故障排除
### 问题 1: thinking_budget 参数未生效
**症状**:日志中没有看到 "mapped to reasoning_effort" 消息
**解决方案**
1. 确认 `extra_body` 结构正确,嵌套路径为 `extra_body.google.thinking_config.thinking_budget`
2. 确认使用的是支持的模型meta、xai、google、openai不支持 Cohere
3. 检查 thinking_budget 值是否有效(非 null 的数字)
4. 查看日志中是否有错误或警告信息
**验证 extra_body 结构**
```bash
# 正确的结构
{
"extra_body": {
"google": { # 必须是 "google" 键
"thinking_config": { # 必须是 "thinking_config" 键
"thinking_budget": 5000 # 必须是 "thinking_budget" 键,值为数字
}
}
}
}
```
### 问题 2: 客户端名称显示为 "Unknown"
**症状**:日志中客户端显示为 "Unknown" 而不是 "Cherry Studio"
**解决方案**
1. 确认请求头中包含 `x-title` 字段
2. 检查 Cherry Studio 是否正确设置了自定义请求头
3. 尝试手动添加请求头进行测试
**测试命令**
```bash
curl http://localhost:8000/v1/chat/completions \
-H "x-title: Cherry Studio" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-oci-genai-default-key" \
-d '{"model": "google.gemini-2.5-pro", "messages": [{"role": "user", "content": "test"}]}'
```
### 问题 3: thinking_budget 映射到错误的 reasoning_effort
**症状**:期望的 reasoning_effort 与实际不符
**验证映射规则**
- thinking_budget ≤ 1760 → low
- 1760 < thinking_budget ≤ 16448 → medium
- thinking_budget > 16448 → high
- thinking_budget = -1 → None (使用模型默认)
**示例**
```python
# thinking_budget = 1000 → low ✓
# thinking_budget = 5000 → medium ✓
# thinking_budget = 20000 → high ✓
# thinking_budget = -1 → None (默认) ✓
```
## 测试
### 自动化测试
运行 Cherry Studio 优化测试脚本:
```bash
./tests/test_cherry_studio_optimization.sh
```
测试脚本会验证以下场景:
1. thinking_budget = 1000 → reasoning_effort = low
2. thinking_budget = 5000 → reasoning_effort = medium
3. thinking_budget = 20000 → reasoning_effort = high
4. thinking_budget = -1 → 使用模型默认值
5. 无 extra_body正常请求
6. 不同客户端名称(验证 x-title 识别)
## 参考资料
- [OCI GenAI Python SDK - GenericChatRequest](https://docs.oracle.com/en-us/iaas/tools/python/latest/api/generative_ai_inference/models/oci.generative_ai_inference.models.GenericChatRequest.html)
- [OpenAI API - Reasoning Models](https://platform.openai.com/docs/guides/reasoning)
- [Google Gemini - Thinking](https://ai.google.dev/gemini-api/docs/thinking)

View File

@@ -0,0 +1,750 @@
# 环境变量配置说明
本文档详细说明 OCI GenAI 网关支持的所有环境变量及其配置方法。
## 📋 目录
- [快速配置](#快速配置)
- [API 设置](#api-设置)
- [认证设置](#认证设置)
- [OCI 配置](#oci-配置)
- [模型设置](#模型设置)
- [嵌入设置](#嵌入设置)
- [流式响应设置](#流式响应设置)
- [日志设置](#日志设置)
- [配置示例](#配置示例)
- [常见配置场景](#常见配置场景)
## 快速配置
1. 复制示例配置文件:
```bash
cp .env.example .env
```
2. 编辑 `.env` 文件,至少配置以下必需项:
```bash
API_KEYS=["sk-your-secret-key"]
OCI_CONFIG_PROFILE=DEFAULT
```
3. 确保 OCI 配置文件存在:
```bash
cat ~/.oci/config
```
## API 设置
### API_TITLE
- **说明**API 服务的标题,显示在 OpenAPI 文档中
- **类型**:字符串
- **默认值**`OCI GenAI to OpenAI API Gateway`
- **示例**
```bash
API_TITLE=My AI Gateway
```
### API_VERSION
- **说明**API 服务的版本号
- **类型**:字符串
- **默认值**`0.0.1`
- **示例**
```bash
API_VERSION=1.0.0
```
### API_PREFIX
- **说明**API 路由前缀,符合 OpenAI API 规范
- **类型**:字符串
- **默认值**`/v1`
- **可选值**:任何有效的 URL 路径
- **注意**:不建议修改,以保持与 OpenAI SDK 的兼容性
- **示例**
```bash
API_PREFIX=/v1
```
### API_PORT
- **说明**:服务监听端口
- **类型**:整数
- **默认值**`8000`
- **范围**1-65535
- **示例**
```bash
API_PORT=8080
```
### API_HOST
- **说明**:服务监听地址
- **类型**:字符串
- **默认值**`0.0.0.0`(监听所有网络接口)
- **可选值**
- `0.0.0.0` - 监听所有接口(生产环境)
- `127.0.0.1` - 仅本地访问(开发环境)
- 特定 IP 地址
- **示例**
```bash
API_HOST=127.0.0.1
```
### DEBUG
- **说明**:启用调试模式
- **类型**:布尔值
- **默认值**`false`
- **可选值**`true` / `false`
- **影响**
- 启用时会显示详细的错误堆栈
- 自动重载代码变更
- 启用 FastAPI 的交互式文档
- **注意**:生产环境应设置为 `false`
- **示例**
```bash
DEBUG=true
```
## 认证设置
### API_KEYS
- **说明**API 密钥列表,用于客户端认证
- **类型**JSON 数组
- **默认值**`["sk-oci-genai-default-key"]`
- **格式**JSON 数组字符串
- **用途**:客户端通过 `Authorization: Bearer <key>` 头进行认证
- **安全建议**
- 使用强密钥(至少 32 个字符)
- 定期轮换密钥
- 不同环境使用不同的密钥
- 不要将密钥提交到版本控制系统
- **示例**
```bash
# 单个密钥
API_KEYS=["sk-prod-a1b2c3d4e5f6g7h8"]
# 多个密钥(支持不同的客户端)
API_KEYS=["sk-admin-key123","sk-user-key456","sk-app-key789"]
```
## OCI 配置
### OCI_CONFIG_FILE
- **说明**OCI 配置文件路径
- **类型**:字符串(文件路径)
- **默认值**`~/.oci/config`
- **用途**:指定 OCI SDK 使用的配置文件位置
- **配置文件格式**
```ini
[DEFAULT]
user=ocid1.user.oc1...
fingerprint=aa:bb:cc:dd...
key_file=~/.oci/oci_api_key.pem
tenancy=ocid1.tenancy.oc1...
region=us-chicago-1
```
- **示例**
```bash
OCI_CONFIG_FILE=~/.oci/config
OCI_CONFIG_FILE=/custom/path/to/oci_config
```
### OCI_CONFIG_PROFILE
- **说明**OCI 配置文件中的 profile 名称
- **类型**:字符串(支持逗号分隔的多个值)
- **默认值**`DEFAULT`
- **用途**
- 单个 profile使用指定的 OCI 配置
- 多个 profiles自动 round-robin 负载均衡
- **要求**:每个 profile 必须包含 `region` 和 `tenancy` 字段
- **示例**
```bash
# 单配置
OCI_CONFIG_PROFILE=DEFAULT
# 多配置(负载均衡)
OCI_CONFIG_PROFILE=DEFAULT,CHICAGO,ASHBURN
# 跨区域配置
OCI_CONFIG_PROFILE=US_WEST,US_EAST,EU_FRANKFURT
```
### OCI_AUTH_TYPE
- **说明**OCI 认证类型
- **类型**:字符串
- **默认值**`api_key`
- **可选值**
- `api_key` - 使用 API 密钥认证(推荐用于本地开发)
- `instance_principal` - 使用实例主体认证(推荐用于 OCI 实例)
- **使用场景**
- **api_key**本地开发、Docker 容器、非 OCI 环境
- **instance_principal**OCI Compute 实例、Container Engine、Functions
- **示例**
```bash
OCI_AUTH_TYPE=api_key
OCI_AUTH_TYPE=instance_principal
```
### OCI_CONNECT_TIMEOUT
- **说明**OCI API 连接超时时间(秒)
- **类型**:整数
- **默认值**`10`
- **范围**1-300
- **用途**:限制建立与 OCI API 连接的最大时间
- **调优建议**
- 网络稳定保持默认值10 秒)
- 网络不稳定:增加到 20-30 秒
- 快速失败:减少到 5 秒
- **示例**
```bash
OCI_CONNECT_TIMEOUT=10
OCI_CONNECT_TIMEOUT=30 # 网络较慢时
```
### OCI_READ_TIMEOUT
- **说明**OCI API 读取超时时间(秒)
- **类型**:整数
- **默认值**`360`6 分钟)
- **范围**30-600
- **用途**:限制等待 OCI API 响应的最大时间
- **调优建议**
- 简单查询120 秒
- 复杂对话300-360 秒
- 长文档处理600 秒
- **注意**:设置过小可能导致长时间运行的请求超时
- **示例**
```bash
OCI_READ_TIMEOUT=360
OCI_READ_TIMEOUT=600 # 处理长文档时
```
### GENAI_ENDPOINT
- **说明**:专用模型端点(可选)
- **类型**字符串URL
- **默认值**:无(自动根据 region 构建)
- **用途**:指定自定义的 OCI GenAI 端点
- **使用场景**
- 使用专用端点
- 测试环境
- 企业私有部署
- **注意**:通常不需要设置,系统会自动使用正确的端点
- **示例**
```bash
GENAI_ENDPOINT=https://your-dedicated-endpoint.oraclecloud.com
```
## 模型设置
### MAX_TOKENS
- **说明**:默认最大 token 数
- **类型**:整数
- **默认值**`4096`
- **范围**1-模型最大限制
- **用途**:当客户端未指定 `max_tokens` 时使用
- **不同模型的限制**
- Cohere Command R+128k
- Meta Llama 3.1 405B128k
- Google Gemini 2.5 Pro2M
- **注意**:实际限制取决于具体模型
- **示例**
```bash
MAX_TOKENS=4096
MAX_TOKENS=8192 # 长对话场景
```
### TEMPERATURE
- **说明**:默认温度参数
- **类型**:浮点数
- **默认值**`0.7`
- **范围**0.0-2.0
- **用途**:控制生成文本的随机性
- **效果**
- 0.0:确定性输出(适合事实查询)
- 0.7:平衡创造性和准确性(默认)
- 1.0-2.0:更有创造性(适合创意写作)
- **示例**
```bash
TEMPERATURE=0.7
TEMPERATURE=0.0 # 事实性问答
TEMPERATURE=1.2 # 创意写作
```
## 嵌入设置
### EMBED_TRUNCATE
- **说明**:嵌入文本截断策略
- **类型**:字符串
- **默认值**`END`
- **可选值**
- `END` - 保留文本开头,截断末尾
- `START` - 保留文本末尾,截断开头
- **用途**:当输入文本超过模型限制时的处理方式
- **使用场景**
- **END**:搜索查询、文档摘要(重点在开头)
- **START**:对话历史、日志分析(重点在结尾)
- **示例**
```bash
EMBED_TRUNCATE=END
EMBED_TRUNCATE=START
```
## 流式响应设置
### ENABLE_STREAMING
- **说明**:全局流式响应开关
- **类型**:布尔值
- **默认值**`true`
- **可选值**`true` / `false`
- **用途**:控制是否允许流式响应
- **行为**
- `true`:允许流式响应(客户端需设置 `stream=true`
- `false`:强制禁用流式响应(即使客户端设置 `stream=true`
- **使用场景**
- 启用:交互式聊天、实时响应
- 禁用批处理、API 集成测试
- **注意**:设置为 `false` 会覆盖客户端的流式请求
- **示例**
```bash
ENABLE_STREAMING=true
ENABLE_STREAMING=false # 调试或批处理时
```
### STREAM_CHUNK_SIZE
- **说明**:模拟流式响应的分块大小(字符数)
- **类型**:整数
- **默认值**`1024`
- **范围**100-4096
- **用途**:仅在 OCI 返回非流式响应时使用fallback 模式)
- **调优建议**
- 快速网络1024-2048
- 慢速网络512-1024
- 视觉效果优先256-512
- **注意**:不影响真实流式响应的性能
- **示例**
```bash
STREAM_CHUNK_SIZE=1024
STREAM_CHUNK_SIZE=512 # 更频繁的更新
```
## 日志设置
### LOG_LEVEL
- **说明**:日志级别
- **类型**:字符串
- **默认值**`INFO`
- **可选值**
- `DEBUG` - 详细调试信息(包含所有日志)
- `INFO` - 一般信息(推荐生产环境)
- `WARNING` - 警告信息
- `ERROR` - 错误信息
- `CRITICAL` - 严重错误
- **使用场景**
- 开发环境:`DEBUG`
- 生产环境:`INFO` 或 `WARNING`
- 最小日志:`ERROR`
- **示例**
```bash
LOG_LEVEL=INFO
LOG_LEVEL=DEBUG # 开发调试
```
### LOG_REQUESTS
- **说明**:启用请求详细日志
- **类型**:布尔值
- **默认值**`false`
- **可选值**`true` / `false`
- **用途**:记录所有传入请求的详细信息
- **包含内容**
- HTTP 方法和 URL
- 查询参数
- 请求头(敏感信息自动过滤)
- 请求体JSON 格式化)
- **性能影响**:轻微(主要是日志写入)
- **安全性**:自动过滤 API 密钥等敏感信息
- **示例**
```bash
LOG_REQUESTS=false
LOG_REQUESTS=true # 调试 API 集成时
```
### LOG_RESPONSES
- **说明**:启用响应详细日志
- **类型**:布尔值
- **默认值**`false`
- **可选值**`true` / `false`
- **用途**:记录所有发出响应的详细信息
- **包含内容**
- HTTP 状态码
- 响应处理时间
- 响应头
- 响应体JSON 格式化)
- **注意**:流式响应不会记录完整响应体
- **示例**
```bash
LOG_RESPONSES=false
LOG_RESPONSES=true # 调试响应格式时
```
### LOG_FILE
- **说明**:日志文件路径
- **类型**:字符串(文件路径)
- **默认值**`./logs/app.log`
- **用途**:指定日志文件保存位置
- **行为**
- 如果未设置,仅输出到控制台
- 如果设置,同时输出到文件和控制台
- **注意**:目录必须存在或有创建权限
- **示例**
```bash
LOG_FILE=./logs/app.log
LOG_FILE=/var/log/oci-genai/app.log
```
### LOG_FILE_MAX_SIZE
- **说明**单个日志文件最大大小MB
- **类型**:整数
- **默认值**`10`
- **范围**1-1000
- **用途**:日志文件轮转的大小限制
- **行为**:超过限制时自动创建新文件
- **建议值**
- 低流量10 MB
- 中等流量50 MB
- 高流量100-200 MB
- **示例**
```bash
LOG_FILE_MAX_SIZE=10
LOG_FILE_MAX_SIZE=50 # 高流量场景
```
### LOG_FILE_BACKUP_COUNT
- **说明**:保留的备份日志文件数量
- **类型**:整数
- **默认值**`5`
- **范围**0-100
- **用途**:控制日志文件轮转时保留的历史文件数
- **存储计算**:总空间 = MAX_SIZE × (BACKUP_COUNT + 1)
- **示例**
```bash
LOG_FILE_BACKUP_COUNT=5
LOG_FILE_BACKUP_COUNT=10 # 需要更长的历史记录
```
## 配置示例
### 开发环境配置
```bash
# 开发环境 - 本地调试
DEBUG=true
LOG_LEVEL=DEBUG
LOG_REQUESTS=true
LOG_RESPONSES=true
API_PORT=8000
API_HOST=127.0.0.1
API_KEYS=["sk-dev-key-123"]
OCI_CONFIG_PROFILE=DEFAULT
OCI_AUTH_TYPE=api_key
MAX_TOKENS=4096
TEMPERATURE=0.7
ENABLE_STREAMING=true
STREAM_CHUNK_SIZE=512
LOG_FILE=./logs/dev.log
LOG_FILE_MAX_SIZE=10
LOG_FILE_BACKUP_COUNT=3
```
### 生产环境配置
```bash
# 生产环境 - 多区域负载均衡
DEBUG=false
LOG_LEVEL=INFO
LOG_REQUESTS=false
LOG_RESPONSES=false
API_PORT=8000
API_HOST=0.0.0.0
# 使用强密钥
API_KEYS=["sk-prod-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"]
# 多区域配置
OCI_CONFIG_PROFILE=DEFAULT,CHICAGO,ASHBURN
OCI_AUTH_TYPE=api_key
# 超时配置
OCI_CONNECT_TIMEOUT=15
OCI_READ_TIMEOUT=360
# 模型配置
MAX_TOKENS=4096
TEMPERATURE=0.7
# 流式配置
ENABLE_STREAMING=true
STREAM_CHUNK_SIZE=1024
# 日志配置
LOG_FILE=/var/log/oci-genai/app.log
LOG_FILE_MAX_SIZE=50
LOG_FILE_BACKUP_COUNT=10
```
### Docker 容器配置
```bash
# Docker 环境
DEBUG=false
LOG_LEVEL=INFO
API_PORT=8000
API_HOST=0.0.0.0
API_KEYS=["sk-docker-key-abc123"]
OCI_CONFIG_FILE=/app/.oci/config
OCI_CONFIG_PROFILE=DEFAULT
OCI_AUTH_TYPE=api_key
# 适当的超时设置
OCI_CONNECT_TIMEOUT=20
OCI_READ_TIMEOUT=360
ENABLE_STREAMING=true
# 容器内日志路径
LOG_FILE=/app/logs/app.log
LOG_FILE_MAX_SIZE=20
LOG_FILE_BACKUP_COUNT=5
```
### OCI 实例配置
```bash
# OCI Compute 实例 - 使用实例主体认证
DEBUG=false
LOG_LEVEL=INFO
API_PORT=8000
API_HOST=0.0.0.0
API_KEYS=["sk-instance-key-xyz789"]
# 使用实例主体认证
OCI_AUTH_TYPE=instance_principal
# 注意:使用实例主体时不需要 OCI_CONFIG_FILE
ENABLE_STREAMING=true
LOG_FILE=/var/log/oci-genai/app.log
LOG_FILE_MAX_SIZE=50
LOG_FILE_BACKUP_COUNT=10
```
## 常见配置场景
### 场景 1: 单区域简单部署
```bash
API_KEYS=["sk-simple-key"]
OCI_CONFIG_PROFILE=DEFAULT
OCI_AUTH_TYPE=api_key
LOG_LEVEL=INFO
```
### 场景 2: 多区域高可用部署
```bash
API_KEYS=["sk-ha-key-primary","sk-ha-key-backup"]
OCI_CONFIG_PROFILE=US_EAST,US_WEST,EU_FRANKFURT
OCI_AUTH_TYPE=api_key
OCI_CONNECT_TIMEOUT=20
OCI_READ_TIMEOUT=360
LOG_LEVEL=WARNING
```
### 场景 3: 调试和开发
```bash
DEBUG=true
LOG_LEVEL=DEBUG
LOG_REQUESTS=true
LOG_RESPONSES=true
API_HOST=127.0.0.1
STREAM_CHUNK_SIZE=256
```
### 场景 4: 高性能生产环境
```bash
DEBUG=false
LOG_LEVEL=WARNING
LOG_REQUESTS=false
LOG_RESPONSES=false
OCI_CONFIG_PROFILE=DEFAULT,REGION2,REGION3
ENABLE_STREAMING=true
MAX_TOKENS=8192
OCI_READ_TIMEOUT=600
LOG_FILE_MAX_SIZE=100
LOG_FILE_BACKUP_COUNT=20
```
### 场景 5: 批处理/API 测试
```bash
ENABLE_STREAMING=false
MAX_TOKENS=2048
TEMPERATURE=0.0
LOG_LEVEL=INFO
LOG_REQUESTS=true
LOG_RESPONSES=true
```
## 环境变量优先级
配置加载顺序(后者覆盖前者):
1. 应用默认值(代码中定义)
2. `.env` 文件
3. 系统环境变量
4. OCI 配置文件(`~/.oci/config`
**示例**
```bash
# .env 文件中
LOG_LEVEL=INFO
# 命令行覆盖
LOG_LEVEL=DEBUG python main.py
```
## 配置验证
### 检查配置是否生效
启动服务后查看日志:
```bash
cd src
python main.py
```
查看启动日志确认配置:
```
2025-12-10 10:00:00 - INFO - Starting OCI GenAI Gateway
2025-12-10 10:00:00 - INFO - API Port: 8000
2025-12-10 10:00:00 - INFO - OCI Profiles: DEFAULT, CHICAGO
2025-12-10 10:00:00 - INFO - Streaming: Enabled
2025-12-10 10:00:00 - INFO - Log Level: INFO
```
### 常见配置错误
1. **API_KEYS 格式错误**
```bash
# 错误
API_KEYS=sk-key-123
# 正确
API_KEYS=["sk-key-123"]
```
2. **布尔值格式错误**
```bash
# 错误
DEBUG=True
ENABLE_STREAMING=yes
# 正确
DEBUG=true
ENABLE_STREAMING=true
```
3. **路径错误**
```bash
# 错误(相对路径不明确)
OCI_CONFIG_FILE=oci/config
# 正确
OCI_CONFIG_FILE=~/.oci/config
OCI_CONFIG_FILE=/absolute/path/to/config
```
## 安全建议
1. **保护 API 密钥**
- 使用强密钥(至少 32 个字符)
- 不要将 `.env` 文件提交到版本控制
- 定期轮换密钥
2. **生产环境设置**
- `DEBUG=false`
- `LOG_LEVEL=INFO` 或 `WARNING`
- `LOG_REQUESTS=false`
- `LOG_RESPONSES=false`
3. **日志管理**
- 定期清理旧日志
- 限制日志文件大小
- 确保日志不包含敏感信息
## 故障排除
### 配置未生效
1. 检查 `.env` 文件是否在正确位置
2. 确认环境变量名称拼写正确
3. 检查值的格式JSON、布尔值等
4. 查看启动日志确认配置加载
### 连接超时
```bash
# 增加超时时间
OCI_CONNECT_TIMEOUT=30
OCI_READ_TIMEOUT=600
```
### 日志文件无法创建
```bash
# 检查目录是否存在
mkdir -p logs
# 检查权限
chmod 755 logs
```
## 参考资料
- [.env.example](../.env.example) - 完整的配置示例文件
- [OCI SDK 配置](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm) - OCI 配置文件格式
- [FastAPI Settings](https://fastapi.tiangolo.com/advanced/settings/) - FastAPI 设置管理

362
docs/OCI-SETUP-GUIDE.md Normal file
View File

@@ -0,0 +1,362 @@
# OCI Generative AI 访问配置指南
## 📖 概述
本指南将帮助您快速配置 Oracle Cloud Infrastructure (OCI) 以使用 Generative AI 服务。
## 🚀 快速开始
### 方法一:使用自动化脚本(推荐)
#### 1. 在 Oracle Cloud Shell 中运行脚本
```bash
bash <(curl -sL https://gitea.bcde.io/wangdefa/oracle-openai/raw/branch/main/script/setup-oci-genai-access.sh)
```
#### 2. 按提示输入信息
脚本会询问您:
- **用户组名称**(默认: `GenAI-Users`
- **用户名**(默认: `genai-api-user`
- **策略名称**(默认: `GenAI-Access-Policy`
您可以直接按回车使用默认值,或输入自定义名称。
#### 3. 脚本将自动完成以下操作
✅ 检查 OCI CLI 环境
✅ 创建 IAM 用户组
✅ 创建并配置策略
✅ 创建新用户
✅ 将用户添加到组
✅ 生成配置信息文件
#### 4. 完成配置
脚本执行完成后,会生成一个配置文件(如 `oci-genai-setup-20241209-143022.txt`),其中包含:
- 所有创建的资源 OCID
- 策略语句
- 详细的后续步骤说明
### 方法二:手动配置
#### 1. 创建用户组
```bash
oci iam group create \
--compartment-id <tenancy-ocid> \
--name "GenAI-Users" \
--description "用于访问 OCI Generative AI 服务的用户组"
```
#### 2. 创建策略
```bash
oci iam policy create \
--compartment-id <tenancy-ocid> \
--name "GenAI-Access-Policy" \
--description "允许 GenAI-Users 组访问 Generative AI 服务" \
--statements '["ALLOW GROUP GenAI-Users to manage generative-ai-family IN TENANCY"]'
```
#### 3. 创建用户
```bash
oci iam user create \
--compartment-id <tenancy-ocid> \
--name "genai-api-user" \
--description "用于通过 API 访问 OCI Generative AI 服务的用户"
```
#### 4. 添加用户到组
```bash
oci iam group add-user \
--user-id <user-ocid> \
--group-id <group-ocid>
```
## 🔑 创建 API Key
### 通过 OCI 控制台
1. 登录 [OCI 控制台](https://cloud.oracle.com)
2. 导航到:**Identity & Security** → **Users** → 选择您创建的用户
3. 点击左侧 **API Keys**
4. 点击 **Add API Key** 按钮
5. 选择 **Generate API Key Pair**
6. **下载私钥文件**`oci_api_key.pem`)并妥善保管
7. **复制并保存公钥指纹**fingerprint
### 通过 OCI CLI高级用户
```bash
# 生成 API Key 对
mkdir -p ~/.oci
openssl genrsa -out ~/.oci/oci_api_key.pem 2048
chmod 600 ~/.oci/oci_api_key.pem
# 生成公钥
openssl rsa -pubout -in ~/.oci/oci_api_key.pem -out ~/.oci/oci_api_key_public.pem
# 上传公钥到 OCI
oci iam user api-key upload \
--user-id <user-ocid> \
--key-file ~/.oci/oci_api_key_public.pem
```
## ⚙️ 配置 OCI CLI
### 1. 创建配置文件
创建或编辑 `~/.oci/config` 文件:
```ini
[DEFAULT]
user=ocid1.user.oc1..aaaaaaaa...
fingerprint=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
key_file=~/.oci/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaa...
region=us-chicago-1
```
**参数说明**
- `user`: 用户的 OCID从配置文件或控制台获取
- `fingerprint`: API Key 的指纹(创建 API Key 时显示)
- `key_file`: 私钥文件路径
- `tenancy`: 租户的 OCID
- `region`: 您的 OCI 区域(如 `us-chicago-1`, `us-ashburn-1` 等)
### 2. 设置文件权限
```bash
chmod 600 ~/.oci/oci_api_key.pem
chmod 600 ~/.oci/config
```
### 3. 测试配置
```bash
# 测试 OCI CLI 配置
oci iam region list
# 测试 Generative AI 访问
oci generative-ai model list --compartment-id <tenancy-ocid>
```
如果命令执行成功并返回结果,说明配置正确。
## 🌍 支持的 OCI 区域
Generative AI 服务目前在以下区域可用:
| 区域代码 | 区域名称 | Endpoint |
|---------|----------|----------|
| `us-chicago-1` | US East (Chicago) | 推荐 |
| `us-ashburn-1` | US East (Ashburn) | 可用 |
| `uk-london-1` | UK South (London) | 可用 |
| `eu-frankfurt-1` | Germany Central (Frankfurt) | 可用 |
**注意**:请选择距离您最近或延迟最低的区域。
## 🔧 多区域配置(可选)
如果您需要访问多个区域或进行负载均衡,可以配置多个 profile
```ini
[DEFAULT]
user=ocid1.user.oc1..aaaaaaaa...
fingerprint=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
key_file=~/.oci/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaa...
region=us-chicago-1
[CHICAGO]
user=ocid1.user.oc1..aaaaaaaa...
fingerprint=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
key_file=~/.oci/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaa...
region=us-chicago-1
[ASHBURN]
user=ocid1.user.oc1..aaaaaaaa...
fingerprint=aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
key_file=~/.oci/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaaaaaa...
region=us-ashburn-1
```
然后在 Gateway 的 `.env` 文件中配置:
```bash
OCI_CONFIG_PROFILE=DEFAULT,CHICAGO,ASHBURN
```
## 🐳 配置 OCI GenAI Gateway
### 1. 克隆项目
```bash
git clone <repository-url>
cd oracle-openai
```
### 2. 配置环境变量
复制并编辑环境变量文件:
```bash
cp .env.example .env
```
编辑 `.env` 文件,设置:
```bash
# API Keys
API_KEYS=["sk-oci-genai-default-key","sk-your-custom-key"]
# OCI 配置
OCI_CONFIG_FILE=~/.oci/config
OCI_CONFIG_PROFILE=DEFAULT # 或多个: DEFAULT,CHICAGO,ASHBURN
OCI_AUTH_TYPE=api_key
# 其他配置(可选)
MAX_TOKENS=4096
TEMPERATURE=0.7
ENABLE_STREAMING=true
LOG_LEVEL=INFO
```
### 3. 启动服务
**使用 Python 直接运行**
```bash
# 安装依赖
pip install -r requirements.txt
# 启动服务
cd src
python main.py
```
**使用 Docker**
```bash
docker-compose up
```
### 4. 测试服务
```bash
# 健康检查
curl http://localhost:8000/health
# 列出可用模型
curl http://localhost:8000/v1/models \
-H "Authorization: Bearer sk-oci-genai-default-key"
# 测试对话
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-oci-genai-default-key" \
-d '{
"model": "google.gemini-2.5-pro",
"messages": [{"role": "user", "content": "你好!"}]
}'
```
## ❓ 常见问题
### 1. 脚本执行失败:权限不足
**错误**
```
ServiceError: Authorization failed or requested resource not found
```
**解决方案**
- 确保您使用的账号具有管理员权限
- 或至少具有以下权限:
- `MANAGE groups IN TENANCY`
- `MANAGE users IN TENANCY`
- `MANAGE policies IN TENANCY`
### 2. 无法创建 API Key
**错误**
```
The user already has the maximum allowed number of API keys (3)
```
**解决方案**
- 删除不再使用的旧 API Key
- 或使用现有的 API Key
### 3. 策略不生效
**问题**:创建了策略但用户仍无法访问 Generative AI
**解决方案**
- 等待 1-2 分钟让策略生效
- 确认用户已添加到正确的用户组
- 检查策略语句是否正确:
```
ALLOW GROUP GenAI-Users to manage generative-ai-family IN TENANCY
```
### 4. Region 不支持 Generative AI
**错误**
```
Service generativeai is not available in region us-sanjose-1
```
**解决方案**
- 切换到支持的区域(如 `us-chicago-1`, `us-ashburn-1`
- 更新 `~/.oci/config` 中的 `region` 参数
### 5. 模型列表为空
**问题**Gateway 启动时无法获取模型列表
**解决方案**
- 确认 OCI 配置正确:`oci iam region list`
- 测试 Generative AI 访问:
```bash
oci generative-ai model list --compartment-id <tenancy-ocid>
```
- 检查区域是否支持 Generative AI
- 确认策略已生效
## 📚 相关文档
- [OCI Generative AI 官方文档](https://docs.oracle.com/en-us/iaas/Content/generative-ai/home.htm)
- [OCI CLI 配置指南](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm)
- [OCI IAM 策略参考](https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/policygetstarted.htm)
- [项目 README](../README.md)
## 🆘 获取帮助
如果您遇到问题:
1. 查看自动生成的配置文件(`oci-genai-setup-*.txt`
2. 检查 OCI 控制台中的资源状态
3. 查看 Gateway 日志:`tail -f logs/app.log`
4. 提交 GitHub Issue
## 📄 许可证
本项目基于 UPL (Universal Permissive License) 开源。
---
**⭐ 如果这个指南对您有帮助,请给项目一个 Star**