Files
planet/docs/technical/zh/agents-aiprovider.md
2026-05-10 22:06:01 +08:00

428 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI Provider 指南
## 概览
`aiprovider` 是 Planet 的模型适配服务。
它把模型厂商差异隔离在主后端之外,让系统其它部分可以调用稳定的业务 API
- 调用方服务 -> `planet backend`
- `planet backend` -> `aiprovider`
- `aiprovider` -> 具体模型提供方
推荐默认方式:
- 外部调用方和跨服务调用方统一调用 `planet backend`
- 只有基础设施级内部任务才直接调用 `aiprovider`
## 职责边界
`backend` 负责:
- 身份认证和权限控制
- 业务层请求整理
- 稳定的 `/api/v1/ai/...` 接口
- 面向 `aiprovider` 的内部服务认证
- 读取配置中心保存的默认 provider、模型和每个 provider 的 key并通过内部请求头覆盖 `aiprovider``.env` 默认值
`aiprovider` 负责:
- 模型协议适配
- 在没有后端覆盖头时基于 `.env` 选择 provider
- 超时和轻量重试
- 通过 `X-Request-ID` 串联请求追踪
当前配置采用类似 OpenClaw 的拆分方式:
- `AI_PROVIDER` 标识厂商或逻辑 provider
- `AI_PROVIDER_API` 标识实际请求协议适配器
这个拆分能更清楚地表达 MiniMax、Claude 兼容网关、自托管 OpenAI 兼容服务等情况,避免把所有含义塞进一个配置项。
## 支持的 Provider
`aiprovider` 当前支持以下 provider 标识:
- `openai`
- `anthropic`
- `minimax`
- `ollama`
支持的请求适配器:
- `openai-completions`
- `anthropic-messages`
- `ollama-generate`
仍然兼容的历史别名:
- `openai_compatible`
- `anthropic_compatible`
- `claude_compatible`
推荐映射关系:
- `vLLM``LM Studio``One API``AI_PROVIDER=openai``AI_PROVIDER_API=openai-completions`
- `MiniMax``AI_PROVIDER=minimax``AI_PROVIDER_API=anthropic-messages`
- Claude 兼容网关:`AI_PROVIDER=anthropic``AI_PROVIDER_API=anthropic-messages`
- `Ollama``AI_PROVIDER=ollama``AI_PROVIDER_API=ollama-generate`
## API 面
### 主后端 API
推荐使用的稳定入口:
- `GET /api/v1/ai/provider/status`
- `POST /api/v1/ai/situational-awareness/analyze`
认证方式:
- `Authorization: Bearer <jwt>`
可选追踪头:
- `X-Request-ID: <caller-generated-id>`
后端会把 `X-Request-ID` 透传给 `aiprovider`,并在响应中返回同一个 header。
### 设置中心 API
AI 配置页使用的接口:
- `GET /api/v1/settings/integrations`
- `PUT /api/v1/settings/integrations`
- `POST /api/v1/settings/integrations/ai-provider/connect`
- `GET /api/v1/settings/integrations/ai-provider/secrets`
- `GET /api/v1/settings/integrations/ai-provider/presets`
这些接口都需要用户登录。`secrets` 接口只用于配置页点击显示 key/token 时取回明文,隐藏时前端恢复为脱敏预览。
### AI Provider 内部 API
仅供内部调用的接口:
- `GET /v1/provider/status`
- `POST /v1/analyze`
认证方式:
- `X-Provider-Token: <shared-secret>`
可选追踪头:
- `X-Request-ID: <caller-generated-id>`
## 请求示例
### 通过后端调用
```bash
curl -X POST http://localhost:8000/api/v1/ai/situational-awareness/analyze \
-H "Authorization: Bearer <access_token>" \
-H "X-Request-ID: bgp-incident-20260407-001" \
-H "Content-Type: application/json" \
-d '{
"title": "BGP异常研判",
"objective": "总结当前风险并给出处置建议",
"observations": [
"collector A 在 5 分钟内出现多次 origin 变更",
"异常集中在同一地区前缀"
],
"constraints": [
"不要编造不存在的数据",
"区分事实和推断"
],
"context": {
"source": "bgp-monitor",
"severity": "high"
}
}'
```
### 直接调用 `aiprovider`
```bash
curl -X POST http://localhost:8010/v1/analyze \
-H "X-Provider-Token: change_me" \
-H "X-Request-ID: ai-batch-job-001" \
-H "Content-Type: application/json" \
-d '{
"title": "链路波动分析",
"objective": "给出简要态势摘要和下一步建议",
"observations": [
"多个节点出现延迟上升"
],
"constraints": [
"不要假设根因已经确认"
],
"context": {
"region": "APAC"
}
}'
```
## 响应结构
后端和 `aiprovider` 返回相同的 payload 结构:
```json
{
"provider": "minimax",
"api": "anthropic-messages",
"model": "MiniMax-M2.7",
"content": "1) 态势摘要 ...",
"content_blocks": [],
"text_blocks": [],
"thinking_blocks": [],
"raw_response": {}
}
```
两个服务都会返回:
- `X-Request-ID: <id>`
## 配置
### 运行时配置链路
LLM 的全局默认配置由后端配置中心统一决定。实际调用顺序是:
1. 前端或业务代码调用 `backend``/api/v1/ai/...`
2. `backend` 从 PostgreSQL 的 `system_settings` 表读取 `category = external_integrations`
3. `payload.ai_provider.default_provider` 决定当前默认 provider。
4. `payload.ai_provider.providers[provider]` 提供该 provider 的 `api_key``provider_api``base_url``model``max_tokens``anthropic_version`
5. `backend` 把这些值转换成 `X-AI-Provider``X-AI-Provider-API``X-AI-Base-URL``X-AI-API-Key``X-AI-Model` 等内部请求头。
6. `aiprovider` 收到头后用这些值覆盖自己的 `.env`,再调用真实模型厂商。
因此,只要 AI 设置页保存了新的默认 provider/model/keyPlayground、告警摘要、数据源映射生成等所有后端 AI 调用都会使用同一个新默认配置。
#### 持久化结构
AI 配置仍保存在 PostgreSQL不写入 JSON 文件。核心结构如下:
```json
{
"ai_provider": {
"service_url": "http://localhost:8010",
"service_token": "",
"default_provider": "openai",
"providers": {
"openai": {
"provider_api": "openai-completions",
"base_url": "https://api.openai.com/v1",
"model": "gpt-5.1",
"api_key": "<saved secret>",
"max_tokens": 4096,
"anthropic_version": "2023-06-01"
},
"minimax": {
"provider_api": "anthropic-messages",
"base_url": "https://api.minimaxi.com/anthropic",
"model": "MiniMax-M2.7",
"api_key": "<saved secret>",
"max_tokens": 1200,
"anthropic_version": "2023-06-01"
}
},
"timeout_seconds": 60,
"retry_attempts": 2
}
}
```
历史单槽配置会在读取时兼容映射到当前 provider 的 `providers[provider]`,保存后写回新结构。
#### Key fallback
每个 provider 都有自己的 key 槽。解析顺序是:
1. PostgreSQL 中 `providers[provider].api_key`
2. `aiprovider/.env` 中 preset 对应的专属变量,例如 `OPENAI_API_KEY``MINIMAX_API_KEY``ANTHROPIC_API_KEY`
3. `aiprovider/.env` 中的通用 `AI_API_KEY`
`.env` 只是兜底。配置页保存或测试连接成功后PostgreSQL 中的配置会成为全局默认。
#### 配置页行为
- Provider 下拉框决定当前默认 provider。
- 模型下拉框保存当前 provider 的默认模型。
- LLM API Key 输入框隐藏时显示脱敏预览;有 `-` 前缀的 key 会保留前缀,例如 `sk-********`,没有前缀的 key 全量脱敏。
- 点击眼睛会从后端取回完整明文;再次隐藏会恢复脱敏预览。
- “保存 AI 配置”直接保存当前表单为全局默认配置。
- “测试连接”先用当前表单发起真实模型链路测试,成功后也会保存为全局默认配置;失败不会覆盖旧配置。
- 清空输入框并保存表示保留旧 key不表示删除 key。
### 后端
推荐的后端 `.env`
```env
AI_PROVIDER_SERVICE_URL=http://localhost:8010
AI_PROVIDER_SERVICE_TOKEN=change_me
AI_PROVIDER_TIMEOUT_SECONDS=60
AI_PROVIDER_RETRY_ATTEMPTS=2
```
参考文件:
- [backend/.env.example](/home/ray/dev/linkong/planet/backend/.env.example)
### AI Provider
参考文件:
- [aiprovider/.env.example](/home/ray/dev/linkong/planet/aiprovider/.env.example)
前端本地参考:
- [frontend/.env.example](/home/ray/dev/linkong/planet/frontend/.env.example)
通用配置:
```env
SERVICE_NAME=planet-ai-provider
SERVICE_VERSION=0.1.0
AI_PROVIDER_SERVICE_TOKEN=change_me
AI_TIMEOUT_SECONDS=60
AI_HTTP_RETRY_ATTEMPTS=2
AI_ANALYSIS_SYSTEM_PROMPT=你是态势感知分析助手。请基于输入的上下文、观测与约束,输出结构化、克制、可执行的分析。
```
可选 provider 专属 key
```env
MINIMAX_API_KEY=sk-cp-xxxxx
OPENAI_API_KEY=sk-xxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxx
DEEPSEEK_API_KEY=sk-xxxxx
DASHSCOPE_API_KEY=sk-xxxxx
MOONSHOT_API_KEY=sk-xxxxx
OPENROUTER_API_KEY=sk-or-xxxxx
```
### OpenAI 兼容示例
```env
AI_PROVIDER=openai
AI_PROVIDER_API=openai-completions
AI_BASE_URL=http://127.0.0.1:8001/v1
AI_API_KEY=local-key
AI_MODEL=your-local-model
```
### MiniMax 中国区示例
```env
AI_PROVIDER=minimax
AI_PROVIDER_API=anthropic-messages
AI_BASE_URL=https://api.minimaxi.com/anthropic
AI_API_KEY=sk-cp-xxxxx
AI_MODEL=MiniMax-M2.7
AI_MAX_TOKENS=1200
AI_ANTHROPIC_VERSION=2023-06-01
```
MiniMax 说明:
- 这里使用官方 MiniMax 示例中的 Anthropic Messages 请求结构。
- 对 MiniMax`aiprovider` 默认不会开启 `thinking`,除非调用方显式传入 `thinking` 对象。
- 这个行为和 OpenClaw 对 MiniMax Anthropic 兼容接口的谨慎处理保持一致。
### Anthropic 兼容示例
```env
AI_PROVIDER=anthropic
AI_PROVIDER_API=anthropic-messages
AI_BASE_URL=https://your-claude-compatible-endpoint.example.com/anthropic
AI_API_KEY=your_api_key
AI_MODEL=your-model
AI_MAX_TOKENS=1200
AI_ANTHROPIC_VERSION=2023-06-01
```
### Ollama 示例
```env
AI_PROVIDER=ollama
AI_PROVIDER_API=ollama-generate
AI_BASE_URL=http://127.0.0.1:11434
AI_API_KEY=
AI_MODEL=qwen2.5:7b
```
## 部署模式
### 单机部署
推荐的本地流程:
- `backend` 运行在 `localhost:8000`
- `aiprovider` 运行在 `localhost:8010`
- 本地模型网关运行在 `localhost:11434` 或其它本地端口
仓库内已包含辅助入口:
- [planet.sh](/home/ray/dev/linkong/planet/planet.sh)
- [docker-compose.local-model.yml](/home/ray/dev/linkong/planet/docker-compose.local-model.yml)
### 多机部署
示例拓扑:
- 应用机器:`backend`
- AI 网关机器:`aiprovider`
- 模型机器:本地模型服务或云代理
此时链路变成服务间 HTTP RPC
- caller -> backend
- backend -> `http://10.0.0.12:8010`
- `aiprovider` -> 模型端点
推荐的跨机器后端配置:
```env
AI_PROVIDER_SERVICE_URL=http://10.0.0.12:8010
AI_PROVIDER_SERVICE_TOKEN=change_me
AI_PROVIDER_TIMEOUT_SECONDS=60
AI_PROVIDER_RETRY_ATTEMPTS=2
```
推荐运行规则:
-`aiprovider` 放在私有网络内
- 至少用 `X-Provider-Token` 保护它
- 始终发送 `X-Request-ID`
- 除基础设施任务外,调用方优先走后端 API
## 重试和失败行为
`backend -> aiprovider`
- 对轻量网络错误和 5xx 失败进行重试
- provider 服务不可用时返回 `502`
`aiprovider -> model provider`
- 对轻量网络错误和 5xx 失败进行重试
- 模型提供方不可用时返回 `502`
这个策略故意保持保守:它能吸收短暂抖动,但不会掩盖持续性错误。
## 运维说明
- `./planet.sh start` 会自动启动 `aiprovider`
- `./planet.sh restart -a` 只重启 `aiprovider`
- `./planet.sh log -a` 跟随查看 `aiprovider` 日志
- `./planet.sh health` 会报告 `aiprovider` 健康状态
## 推荐调用策略
- 前端和应用服务:调用 `backend`
- 定时基础设施任务和诊断任务:可选直接调用 `aiprovider`
- 不要让多个业务服务分别接入模型厂商
这样可以集中管理 provider 切换,避免模型相关差异在系统里四处扩散。