Files
Cyrene/docs/api/backend-services/ai-core.md
T
AskaEth 91c9ee4b2d fix: 修复 AI 回复无法送达发送者 + 重复消息 + action角色泄露 + OS环境支持
广播逻辑重构:
- AI 回复 (stream_start/response/stream_segments/multi_message/stream_end) 改用 broadcastToUser 发送给所有客户端
- 用户消息回显保持 broadcastToUserExcept 排除发送者

消息去重与角色修复:
- CacheMessage(user) 移至回复生成后,避免本轮 LLM 调用出现重复用户消息
- action 角色消息在 DB 存储时映射为 assistant,DeepSeek 等模型不支持自定义角色
- stream_end defer 机制确保错误路径也会终止客户端思考指示器

OS 完整环境支持:
- host 包重构为 HostBackend 接口 + Direct/WSL/Docker 三种后端
- 新增 os_exec/os_file/os_system 工具供 AI 在完整 Linux 环境中自由操作

其他:
- 视觉模型注入 + 图片预处理后清空 Images 避免传给 Chat 模型
- 图片 URL 相对路径→绝对 URL 转换
- DevTools 链路追踪页面 + 重启修复
- 记忆搜索模糊匹配增强
- 后台思考定时调度支持
- 管理后台页面 (模型配置/用户管理等)
- docs/api 更新广播机制说明

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 12:46:17 +08:00

341 lines
7.9 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-Core Service API
**Base URL:** `http://<host>:8081` | **Auth:** 无(/internal 路由除外)
AI-Core 是 LLM 编排引擎,负责对话处理、意图分析、子会话调度、结果合成。所有对话和记忆端点通过 **Server-Sent Events (SSE)****JSON** 返回。
---
## 目录
1. [POST /api/v1/chat — 对话](#1-post-apiv1chat)
2. [GET /api/v1/memory/search — 记忆搜索](#2-get-apiv1memorysearch)
3. [GET /api/v1/memory — 记忆列表](#3-get-apiv1memory)
4. [POST /api/v1/memory — 添加记忆](#4-post-apiv1memory)
5. [DELETE /api/v1/memory — 删除记忆](#5-delete-apiv1memory)
6. [POST /api/v1/internal/presence — 在线状态](#6-post-apiv1internalpresence)
7. [GET /api/v1/system/info — OS 环境信息](#7-get-apiv1systeminfo)
8. [GET /api/v1/tools/calls — 工具调用日志](#8-get-apiv1toolscalls)
9. [GET /api/v1/llm-calls — LLM 调用日志](#9-get-apiv1llm-calls)
10. [GET /api/v1/health — 健康检查](#10-get-apiv1health)
11. [Model Selector 路由说明](#11-model-selector-路由说明)
---
## 1. POST /api/v1/chat
**类型:** SSE 流式 | **Content-Type:** `application/json``text/event-stream`
### 请求体 (JSON)
| JSON 字段 | Go 类型 | 必填 | 说明 |
|-----------|---------|------|------|
| `user_id` | string | 是 | 用户 ID |
| `session_id` | string | 是 | 会话 ID |
| `message` | string | 是 | 用户消息文本(纯图片时可留空 `""` |
| `images` | []string | 否 | 图片 URL 数组(data URL 或 https URL |
| `mode` | string | 否 | 默认 `"text"` |
| `nickname` | string | 否 | 用户昵称 |
> **图片预处理:** 当 `images` 非空时,AI-Core 使用视觉模型 (`routing.vision`) 自动分析图片:
> - 纯图片 (`message=""`) → 生成场景描述作为用户消息
> - 文字+图片 → 视觉分析追加到消息末尾
> - 原始图片仍传递给下游 LLM(如模型支持多模态)
### SSE 事件
**delta** — 逐 token 发送
```json
{ "delta": "token 文本", "message_id": "msg-1717000000000000000" }
```
**segments** — 断句事件(生成完成后)
```json
{
"message_id": "string",
"mode": "string",
"segments": [
{ "index": 0, "text": "第一句话" },
{ "index": 1, "text": "第二句话" }
]
}
```
**review** — 审查后结构化消息(action/chat 分离)
```json
{
"message_id": "string",
"review_messages": [
{ "type": "action", "content": "打开灯光", "delay_ms": 0 },
{ "type": "chat", "content": "好的,已为你打开客厅的灯光。", "delay_ms": 200 }
]
}
```
**tool_progress** — 工具执行进度
```json
{
"type": "tool_progress",
"tool_name": "host_exec",
"status": "started|running|completed|failed",
"progress": 0.5,
"message": "正在执行 host_exec",
"message_id": "string"
}
```
**done** — 流结束
```json
{ "message_id": "string", "mode": "string", "done": true }
```
**error** — 错误
```json
{ "delta": "", "error": "错误描述" }
```
终端标记: `data: [DONE]\n\n`
### HTTP 状态码
| 状态码 | 含义 |
|--------|------|
| 200 | 流开始 |
| 400 | JSON 解析失败 |
| 405 | 非 POST 请求 |
| 500 | 服务端不支持流式 |
---
## 2. GET /api/v1/memory/search
### Query 参数
| 参数 | 必填 | 说明 |
|------|------|------|
| `user_id` | 是 | 用户 ID |
| `q` | 是 | 搜索关键词 |
### 响应 200
```json
{
"user_id": "string",
"query": "搜索词",
"memories": [ MemoryEntry, ... ],
"total": 5
}
```
### 错误 (200 + error 字段)
```json
{
"user_id": "string",
"query": "string",
"memories": [],
"error": "错误描述",
"errorType": "memory_store_unavailable|retrieve_failed",
"hint": "解决方案 (仅 memory_store_unavailable)"
}
```
---
## 3. GET /api/v1/memory — 记忆列表
`?user_id=xxx` 最大返回 50 条。
```json
{
"user_id": "string",
"memories": [ MemoryEntry, ... ],
"total": 3
}
```
---
## 4. POST /api/v1/memory — 添加记忆
```json
// 请求
{
"user_id": "string (必填)",
"content": "string (必填)",
"category": "string (默认 other)",
"priority": 1
}
// 响应 201
{
"status": "saved",
"memory": MemoryEntry
}
```
### 错误
| 状态码 | errorType | 说明 |
|--------|-----------|------|
| 400 | — | 缺少 user_id 或 content |
| 500 | `save_failed` | 保存失败 |
| 503 | `memory_store_unavailable` | 存储未初始化 |
---
## 5. DELETE /api/v1/memory — 删除记忆
`?id=<memory_id>`
```json
// 响应 200
{ "status": "deleted", "memory_id": "string" }
```
### 错误
| 状态码 | errorType |
|--------|-----------|
| 400 | 缺少 id 参数 |
| 500 | `delete_failed` |
| 503 | `memory_store_unavailable` |
---
## 6. POST /api/v1/internal/presence
**Auth:** `X-Internal-Token` header。Gateway 内部调用的用户上线/下线通知。
```json
// 请求
{
"user_id": "string (必填)",
"status": "online|offline (必填)",
"session_id": "string (必填)"
}
// 响应 200
{ "status": "ok" }
```
| 状态码 | 含义 |
|--------|------|
| 200 | 成功 |
| 400 | JSON 无效 |
| 401 | Token 无效 |
---
## 7. GET /api/v1/system/info
返回 OS 环境状态信息(WSL/Docker 后端状态、系统信息、磁盘使用)。
```json
{
"os_enabled": true,
"backend": "wsl",
"system": { "hostname": "...", "os": "linux", "arch": "amd64", "cpu_cores": 12, "total_memory": "16.0 GB" },
"disk": { "path": "/", "total": "250.0 GB", "used": "120.0 GB", "free": "130.0 GB", "used_percent": 48.0 }
}
```
`os_enabled=false` 表示未配置 OS 后端。
---
## 8. GET /api/v1/tools/calls
工具调用日志(分页)。
| Query 参数 | 说明 |
|-----------|------|
| `tool_name` | 按工具名过滤 |
| `limit` | 每页条数 (默认 50, 最大 500) |
| `page` | 页码 (从 1 开始) |
```json
{
"calls": [ CallLogRecord ],
"total": 100,
"total_pages": 2,
"page": 1,
"limit": 50
}
```
### GET /api/v1/tools/calls/stats — 工具调用统计
返回各工具的调用次数、成功率等统计信息。
---
## 9. GET /api/v1/llm-calls
LLM 调用日志(调试用)。
`?limit=50` (默认 50, 最大 500)
```json
{
"calls": [ LLMCallRecord ],
"total": 50
}
```
---
## 10. GET /api/v1/health
```json
{
"status": "ok",
"service": "ai-core",
"model": "gpt-4o"
}
```
---
## 11. Model Selector 路由说明
AI-Core 使用基于用途的模型路由。模型配置从 `models.json` 加载,回退到 `.env` 环境变量。
### Purpose 常量
| Purpose | 常量 | 用途 |
|---------|------|------|
| `chat` | `PurposeChat` | 通用对话 |
| `deep_thinking` | `PurposeDeepThinking` | 后台深度思考 |
| `intent_analysis` | `PurposeIntentAnalysis` | 意图分析 |
| `tool_calling` | `PurposeToolCalling` | 工具调用 |
| `memory_extraction` | `PurposeMemoryExtraction` | 记忆提取 |
| `vision` | `PurposeVision` | 图片理解/视觉分析 (图片预处理、vision_analyze 工具) |
| `ocr` | `PurposeOCR` | 专用 OCR 文字提取 |
### 路由策略
1. `models.json` 存在 → 按 `routing.<purpose>.fallback_chain` 顺序尝试
2. `models.json` 不存在 → 回退到 `.env``LLM_API_URL`/`LLM_API_KEY`/`LLM_MODEL`
3. 全部失败 → 返回 `DefaultAdapter()` 使用 fallback model
### MemoryEntry 结构
| JSON 字段 | Go 类型 | 说明 |
|-----------|---------|------|
| `id` | string | UUID |
| `user_id` | string | 所属用户 |
| `content` | string | 完整内容 |
| `summary` | string | 摘要 |
| `category` | string | `user_preference`, `personal_info`, `conversation`, `knowledge`, `event`, `task`, `relationship` |
| `priority` | int | 0=Temp, 1=Normal, 2=Important, 3=Core |
| `importance` | int | 1-10 |
| `keywords` | []string | 关键词标签 |
| `session_id` | string | 来源会话 |
| `source` | string | `conversation`, `thinking`, `manual` |
| `access_count` | int | 访问次数 |
| `last_access` | time | 最近访问 |
| `created_at` | time | 创建时间 |
| `updated_at` | time | 更新时间 |
| `expires_at` | *time | 临时记忆过期(可空) |