Files
life-echo/api/README.md

519 lines
14 KiB
Markdown
Raw Normal View History

# Life Echo API
Life Echo 后端服务,基于 FastAPI 构建的实时语音对话回忆录生成系统。
## 项目简介
Life Echo API 是一个智能对话系统,通过 WebSocket 实时连接,使用 LangChain Agent 引导用户进行回忆录访谈对话,并将口语内容自动整理为结构化的书面章节,最终生成回忆录 PDF。
refactor(api,expo): 多智能体与会话收敛、回忆录兼容层移除、后端测试集大幅删减 - 对齐「多智能体收敛」与「回忆录 stories-first / markdown-first」方向:收紧运行时契约、 删除过渡兼容路径与双轨逻辑,并同步更新客户端与文档。 - Chat:以 ChatOrchestrator 为实时编排入口;删除独立 conversation_agent,精简 prompts。 - Memoir:删除 memory_agent;MemoirOrchestrator、classification / story_route 与 prompts 收敛到 prepare_batches + run_story_pipeline_for_category_batch 主链路。 - 将 agents 侧 processor 迁入 feature 层为 background_runner,并移除 features 下重复/过时 processor 封装。 - 新增 history_store,强化「conversation_messages 为 DB 真源、Redis 为缓存」模型。 - 调整 models、repo、service、session_history;精简 WS message_types,重构 pipeline 与 router。 - 移除章节占位、整章再生等旧路径;章节列表与封面逻辑要求 story 关联;收紧 cover 资格与 enqueue。 - helpers、repo、service、router、reading_segment_materialize、story_pipeline_sync、pdf_service 等按 canonical markdown / cover_asset_id 收缩;删除 memoir_images/provider 等冗余。 - tasks:memoir_tasks、chapter_cover_tasks 等大幅瘦身;story_image_tasks 等与当前图片任务对齐。 - core:config、logging、redis、task_tracker 小幅调整。 - auth / user / payment / quota:路由或服务侧删减过时接口或逻辑(如 payment router 行数减少)。 - pyproject.toml、development.sh、.env.example / .env.production、README 等同步说明或变量。 - Alembic 0001_initial_schema 微调(与当前 schema 叙事一致的小改动)。 - 回忆录:types / mappers / api、章节页与 memoir 页与后端契约对齐;markdown-renderer 调整。 - 语音:删除 voice/player,voice-segment-store 相应精简。 - api/tests:删除 conftest 及绝大部分既有测试文件(websocket_baseline、conversation、memoir 图片、PDF、SMS 等),属有意收缩/待按 backend-test-system 重建的信号。 - docs:新增多智能体收敛与移除兼容层计划摘要;更新 story-first 设计、backend-test-system、 multi-agent-refactor-plan、实施总结等。 BREAKING CHANGE: 后端对外契约、回忆录章节字段与若干路由/任务行为已变更;大量 API 测试被移除, CI 若依赖这些用例需按新策略补测或调整流水线。
2026-03-22 16:45:57 +08:00
### 架构要点(多 Agent 收敛)
- **会话真源**`conversation_messages`DB+ Redis 缓存;**实时编排入口**`ChatOrchestrator`
- **图像管线**:正文主图 `generate_story_image`;章节封面 `try_enqueue_generate_chapter_cover``generate_chapter_cover`
- **回忆录批次**`MemoirOrchestrator.prepare_batches` 显式分桶后,`process_memoir_segments` 按类别加锁并调用 `run_story_pipeline_for_category_batch`(含 `StoryRouteAgent.plan_batch` 多 unit 写入)。
## 技术栈
- **Web 框架**: FastAPI 0.115.0
- **WebSocket**: websockets 14.1
- **AI 框架**: LangChain 0.3.7 + DeepSeek/兼容 OpenAI 的 LLM
- **数据库**: PostgreSQL 17 + SQLAlchemy 2.0.36 (asyncpg)
- **缓存/队列**: Redis 7 + Celery 5.3
- **PDF 生成**: ReportLab 4.2.2 + WeasyPrint 62.3
- **ASR/TTS**: OpenAI Whisper API
- **认证**: JWT (python-jose) + bcrypt
- **其他**: Pydantic, python-dotenv
## 项目结构
```
api/
├── main.py # 应用入口uvicorn 启动)
├── app/ # 应用主包
│ ├── main.py # FastAPI 应用定义
│ ├── core/ # 核心基础设施
│ │ ├── config.py # 配置pydantic-settings
│ │ ├── db.py # 数据库连接
│ │ ├── redis.py # Redis 服务
│ │ ├── security.py # JWT、密码哈希
│ │ └── task_tracker.py # 任务状态追踪
│ ├── features/ # 功能模块(各模块含 router、service、repo
│ │ ├── auth/ # 认证(注册、登录、短信验证码)
│ │ ├── user/ # 用户信息
│ │ ├── conversation/ # 对话、WebSocket
│ │ ├── memory/ # 记忆检索
│ │ ├── memoir/ # 回忆录、章节、PDF、图像生成
│ │ ├── payment/ # 支付
│ │ ├── plan/ # 套餐
│ │ ├── quota/ # 配额
│ │ ├── tasks/ # 任务状态 API
│ │ └── content/ # 内容TTS 等)
│ ├── adapters/ # 外部能力适配器ASR、TTS、LLM、短信、存储等
│ ├── ports/ # 能力契约Protocol
│ └── agents/ # LangChain Agent
├── tasks/ # Celery 后台任务
│ └── memoir_tasks.py # 回忆录处理任务
└── docs/ # 详细文档
```
## 环境配置
### 1. 安装依赖
```bash
cd api
pip install -r requirements.txt
```
### 2. 环境变量配置
创建 `.env` 文件(在 `api/` 目录下):
```env
# DeepSeek API 配置(推荐,优先使用)
DEEPSEEK_API_KEY=your_deepseek_api_key_here
DEEPSEEK_BASE_URL=https://api.deepseek.com # 可选,默认值
DEEPSEEK_MODEL=deepseek-chat # 可选,默认值
# 或使用通用 LLM 配置(支持其他兼容 OpenAI 的 LLM
LLM_API_KEY=your_llm_api_key_here
LLM_BASE_URL=https://api.your-llm-provider.com # 可选
LLM_MODEL=your-model-name # 可选,默认 deepseek-chat
LLM_TEMPERATURE=0.7 # 可选,默认 0.7
# 数据库配置PostgreSQL推荐
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/life_echo
# Redis 配置
REDIS_URL=redis://localhost:6379/0
# 认证配置
SECRET_KEY=your-secret-key-here # JWT签名密钥建议使用随机字符串
ALGORITHM=HS256 # JWT算法默认HS256
ACCESS_TOKEN_EXPIRE_MINUTES=120 # 访问令牌过期时间分钟默认120即2小时
# 服务器配置(可选)
HOST=0.0.0.0
PORT=8000
```
**LLM 配置优先级**
1. `DEEPSEEK_API_KEY` - 优先使用 DeepSeek推荐
2. `LLM_API_KEY` - 通用 LLM 配置(支持其他兼容 OpenAI 格式的 LLM
**DeepSeek 配置示例**
```env
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxx
DEEPSEEK_MODEL=deepseek-chat
```
### 3. 数据库迁移
数据库 schema 由 Alembic 管理,首次或 schema 变更后执行:
```bash
cd api
uv run alembic upgrade head
```
## 快速启动
### 本地开发
推荐使用一键脚本(会自动启动 PostgreSQL/Redis、检查 `.venv`、安装依赖并拉起 FastAPI + Celery
```bash
cd api
./dev-up.sh
```
可选环境变量:
- `SKIP_INSTALL=1`:跳过依赖安装
- `API_HOST` / `API_PORT`:覆盖 API 启动地址和端口
- `CELERY_POOL`:覆盖 Celery 池类型macOS 推荐 `solo`
也可以使用手动方式:
```bash
cd api
# 1. 启动 PostgreSQL + Redis
docker-compose -f docker-compose.dev.yml up -d
# 2. 安装依赖
pip install -r requirements.txt
# 3. 配置环境变量
export DATABASE_URL=postgresql://postgres:postgres@localhost:5432/life_echo
export REDIS_URL=redis://localhost:6379/0
# 4. 启动 API终端 1
uvicorn main:app --reload --host 0.0.0.0 --port 8000
# 5. 启动 Celery Worker终端 2
# macOS 使用 solo 池避免 fork 崩溃问题
celery -A tasks.celery_app worker --loglevel=info --pool=solo
# Linux/生产环境可以使用 prefork 池
# celery -A tasks.celery_app worker --loglevel=info --concurrency=4
```
### 验证服务
```bash
# 检查 PostgreSQL
docker exec life-echo-postgres-dev psql -U postgres -c "SELECT 1"
# 检查 Redis
docker exec life-echo-redis-dev redis-cli ping
```
### 生产部署(一键)
```bash
cd api
# 创建生产配置
cp .env .env.prod
# 编辑 .env.prod
# 启动所有服务
docker-compose up -d
# 查看日志
docker-compose logs -f
```
服务启动后,访问:
- API 文档: http://localhost:8000/docs
- 健康检查: http://localhost:8000/health
## 📚 详细文档
更多详细文档请参考 [docs/README.md](docs/README.md)
- **[本地开发环境配置](docs/本地开发环境配置.md)** - 开发环境搭建指南
- **[WebSocket 快速测试指南](docs/WebSocket快速测试指南.md)** - WebSocket 快速测试
- **[WebSocket 测试文档](docs/WebSocket测试文档.md)** - WebSocket 详细接口文档
- **[文字交流模式说明](docs/文字交流模式说明.md)** - 文字对话模式功能说明
- **[测试脚本使用说明](docs/测试脚本使用说明.md)** - 自动化测试脚本指南
## API 文档
### 认证系统
系统使用 JWTJSON Web Token进行认证采用访问令牌Access Token+ 刷新令牌Refresh Token机制
- **访问令牌**:有效期 2 小时,用于 API 请求认证
- **刷新令牌**:有效期 30 天,用于刷新访问令牌
#### 认证流程
1. **用户注册**`POST /api/auth/register`
2. **用户登录**`POST /api/auth/login` → 返回 `access_token``refresh_token`
3. **API 请求**:在 Header 中携带 `Authorization: Bearer {access_token}`
4. **刷新令牌**`POST /api/auth/refresh` → 使用 `refresh_token` 获取新的 `access_token`
5. **用户登出**`POST /api/auth/logout` → 撤销 `refresh_token`
#### 认证 API (`/api/auth`)
##### 用户注册
```http
POST /api/auth/register
Content-Type: application/json
{
"phone": "13800138000",
"password": "password123",
"nickname": "用户昵称",
"email": "user@example.com" // 可选
}
```
**响应**
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "random-refresh-token-string",
"token_type": "bearer"
}
```
##### 用户登录
```http
POST /api/auth/login
Content-Type: application/json
{
"phone": "13800138000",
"password": "password123"
}
```
**响应**:同注册接口
##### 刷新访问令牌
```http
POST /api/auth/refresh
Content-Type: application/json
{
"refresh_token": "your-refresh-token"
}
```
**响应**
```json
{
"access_token": "new-access-token",
"refresh_token": "same-refresh-token",
"token_type": "bearer"
}
```
##### 用户登出
```http
POST /api/auth/logout
Authorization: Bearer {access_token}
Content-Type: application/json
{
"refresh_token": "your-refresh-token"
}
```
##### 获取当前用户信息
```http
GET /api/auth/me
Authorization: Bearer {access_token}
```
**响应**
```json
{
"id": "user-id",
"phone": "13800138000",
"email": "user@example.com",
"nickname": "用户昵称",
"avatar_url": null,
"subscription_type": "free",
"created_at": "2024-01-15T10:00:00Z"
}
```
#### 使用认证令牌
所有需要认证的 API 请求都需要在 Header 中携带访问令牌:
```http
Authorization: Bearer {access_token}
```
### REST API
#### 对话管理 (`/api/conversations`)
**注意**:所有对话相关接口都需要认证。
- `POST /api/conversations` - 创建新对话(需要认证)
- `GET /api/conversations/{conversation_id}` - 获取对话详情(需要认证,只能访问自己的对话)
- `POST /api/conversations/{conversation_id}/end` - 结束对话(需要认证,只能结束自己的对话)
#### 章节管理 (`/api/chapters`)
**注意**:所有章节相关接口都需要认证。
- `GET /api/chapters` - 获取用户所有章节(需要认证)
- `GET /api/chapters/{chapter_id}` - 获取章节详情(需要认证,只能访问自己的章节)
- `POST /api/chapters/{chapter_id}/regenerate` - 重新整理章节(需要认证,只能操作自己的章节)
#### 回忆录管理 (`/api/books`)
**注意**:所有回忆录相关接口都需要认证。
- `GET /api/books/current` - 获取当前回忆录(需要认证)
- `POST /api/books/export-pdf` - 导出 PDF需要认证只能导出自己的回忆录
### WebSocket API
#### 对话 WebSocket (`/ws/conversation/{conversation_id}`)
**注意**WebSocket 连接需要认证,通过查询参数传递访问令牌。
**连接地址**
```
ws://localhost:8000/ws/conversation/{conversation_id}?token={access_token}
```
实时双向通信,支持:
- 接收客户端音频数据
- 发送 Agent 响应文本
- 实时语音识别ASR
- 实时语音合成TTS
**认证要求**
- 必须在查询参数中提供有效的 `access_token`
- 只能连接属于当前用户的对话
- 如果对话不存在,将自动创建并关联到当前用户
**消息格式**:
客户端 → 服务端:
```json
{
"type": "audio",
"data": "base64_encoded_audio_data"
}
```
服务端 → 客户端:
```json
{
"type": "transcript",
"text": "识别出的文本",
"agent_response": "Agent 的回复"
}
```
```json
{
"type": "audio",
"data": "base64_encoded_tts_audio"
}
```
## 数据库模型
### User用户
- `id`: 用户 ID
- `phone`: 手机号(唯一,必填)
- `password_hash`: 密码哈希
- `email`: 邮箱(可选)
- `openid`: 微信 OpenID可选
- `nickname`: 昵称
- `avatar_url`: 头像 URL
- `subscription_type`: 订阅类型free/premium
- `created_at`: 创建时间
### RefreshToken刷新令牌
- `id`: 令牌 ID
- `user_id`: 用户 ID外键
- `token`: 刷新令牌(唯一)
- `expires_at`: 过期时间30天后
- `created_at`: 创建时间
- `is_revoked`: 是否已撤销
### Conversation对话
- `id`: 对话 ID
- `user_id`: 用户 ID
- `started_at`: 开始时间
- `ended_at`: 结束时间
- `duration_seconds`: 持续时间(秒)
- `summary`: 对话摘要
- `status`: 状态active/ended/processing
- `current_topic`: 当前话题
- `conversation_stage`: 对话阶段childhood/education/career/family/beliefs/summary
### Segment对话段落
- `id`: 段落 ID
- `conversation_id`: 对话 ID
- `audio_url`: 音频 URL
- `transcript_text`: 转录文本
- `created_at`: 创建时间
- `processed`: 是否已处理
- `topic_category`: 话题分类
- `agent_response`: Agent 响应
### Chapter章节
- `id`: 章节 ID
- `user_id`: 用户 ID
- `title`: 标题
- `content`: 内容
- `order_index`: 排序索引
- `status`: 状态draft/completed
- `images`: 图片 URL 列表JSON
- `updated_at`: 更新时间
- `category`: 章节分类
### Book回忆录
- `id`: 回忆录 ID
- `user_id`: 用户 ID
- `title`: 标题
- `total_pages`: 总页数
- `total_words`: 总字数
- `cover_image_url`: 封面图片 URL
- `updated_at`: 更新时间
## 核心功能
### 1. 对话引导 Agent
使用 LangChain 构建的对话 Agent根据传记结构引导用户回忆
- 童年时光
- 教育经历
- 职业生涯
- 家庭生活
- 人生信念
- 总结回顾
### 2. 记忆整理 Agent
将口语对话内容整理为结构化的书面章节:
- 口语转书面语
- 内容结构化
- 章节分类
- 自动生成标题
### 3. 语音服务
- **ASR (语音识别)**: 使用 OpenAI Whisper API 将音频转为文本
- **TTS (语音合成)**: 使用 OpenAI TTS API 将文本转为语音
### 4. PDF 生成
使用 ReportLab 和 WeasyPrint 生成精美的回忆录 PDF 文档。
## 开发指南
### 添加新的 API 路由
1.`routers/` 目录创建新的路由文件
2. 定义路由函数
3.`main.py` 中注册路由:
```python
from routers import your_router
app.include_router(your_router.router)
```
### 添加新的数据库模型
1. 在对应 feature 的 `app/features/<feature_name>/models.py` 中定义模型类
2. 继承 `Base`(从 `app.core.db` 导入)
3.`app/main.py` 中 import 该 models 模块以注册到 Base.metadata
4. 运行 Alembic 迁移
### 添加新的服务
1.`app/features/<feature_name>/service.py` 中实现业务逻辑
2. 通过 `deps.py` 提供依赖注入
3. 在对应 feature 的 router 中通过 `Depends(get_xxx_service)` 使用
## 安全注意事项
1. **CORS 配置**: 当前允许所有来源,生产环境应限制为特定域名
2. **API Key 安全**: 确保 `.env` 文件不被提交到版本控制
3. **SECRET_KEY 安全**: 使用强随机字符串作为 JWT 签名密钥,生产环境必须更换
4. **密码安全**: 密码使用 bcrypt 哈希存储,不会以明文形式保存
5. **令牌安全**:
- 访问令牌短期有效2小时降低泄露风险
- 刷新令牌存储在数据库中,支持撤销
- 令牌过期后必须使用刷新令牌重新获取
6. **数据库备份**: 定期备份 PostgreSQL 数据库
7. **错误处理**: 所有 API 都包含适当的错误处理和权限验证
8. **日志记录**: 建议添加日志记录功能以便调试和监控
## 许可证
MIT License