- 更新根目录README.md,完善项目说明 - 更新api/README.md,添加API文档说明 - 新增api/docs/README.md文档 - 新增app-android/README.md文档 - 新增app-android/doc/文档目录
523 lines
14 KiB
Markdown
523 lines
14 KiB
Markdown
# Life Echo API
|
||
|
||
Life Echo 后端服务,基于 FastAPI 构建的实时语音对话回忆录生成系统。
|
||
|
||
## 项目简介
|
||
|
||
Life Echo API 是一个智能对话系统,通过 WebSocket 实时连接,使用 LangChain Agent 引导用户进行回忆录访谈对话,并将口语内容自动整理为结构化的书面章节,最终生成回忆录 PDF。
|
||
|
||
## 技术栈
|
||
|
||
- **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 # FastAPI 应用入口
|
||
├── requirements.txt # Python 依赖
|
||
├── Dockerfile # Docker 镜像构建文件
|
||
├── docker-compose.yml # 生产环境 Docker Compose
|
||
├── docker-compose.dev.yml # 开发环境 Docker Compose
|
||
├── agents/ # LangChain Agent
|
||
│ ├── conversation_agent.py # 对话引导 Agent
|
||
│ ├── memory_agent.py # 记忆整理 Agent
|
||
│ ├── memoir_processor.py # 回忆录处理器
|
||
│ ├── state_schema.py # 状态模式定义
|
||
│ └── prompts/ # Agent 提示词
|
||
│ ├── conversation_prompts.py
|
||
│ └── memory_prompts.py
|
||
├── database/ # 数据库模块
|
||
│ ├── database.py # 数据库连接和初始化
|
||
│ └── models.py # SQLAlchemy 数据模型
|
||
├── routers/ # API 路由
|
||
│ ├── auth.py # 认证 API(注册、登录、刷新令牌)
|
||
│ ├── conversations.py # 对话管理 API
|
||
│ ├── chapters.py # 章节管理 API
|
||
│ ├── books.py # 回忆录管理 API
|
||
│ ├── websocket.py # WebSocket 端点
|
||
│ ├── memoir_state.py # 回忆录状态 API
|
||
│ ├── user.py # 用户信息 API
|
||
│ ├── plans.py # 套餐管理 API
|
||
│ ├── orders.py # 订单管理 API
|
||
│ ├── quota.py # 配额管理 API
|
||
│ ├── tasks.py # 任务管理 API
|
||
│ ├── faqs.py # 常见问题 API
|
||
│ └── feedback.py # 反馈 API
|
||
├── middleware/ # 中间件
|
||
│ └── auth.py # 认证中间件
|
||
├── services/ # 业务服务
|
||
│ ├── auth_service.py # 认证服务(密码哈希、JWT)
|
||
│ ├── asr_service.py # 语音识别服务
|
||
│ ├── tts_service.py # 语音合成服务
|
||
│ ├── pdf_service.py # PDF 生成服务
|
||
│ ├── llm_service.py # LLM 服务(DeepSeek/兼容 OpenAI 的 LLM)
|
||
│ ├── memoir_state_service.py # 回忆录状态服务
|
||
│ ├── redis_service.py # Redis 服务
|
||
│ └── task_tracker.py # 任务追踪服务
|
||
├── tasks/ # Celery 后台任务
|
||
│ ├── celery_app.py # Celery 应用配置
|
||
│ └── memoir_tasks.py # 回忆录处理任务
|
||
└── docs/ # 详细文档
|
||
├── README.md # 文档索引
|
||
├── 本地开发环境配置.md
|
||
├── WebSocket快速测试指南.md
|
||
├── WebSocket测试文档.md
|
||
├── 文字交流模式说明.md
|
||
└── 测试脚本使用说明.md
|
||
```
|
||
|
||
## 环境配置
|
||
|
||
### 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. 初始化数据库
|
||
|
||
数据库会在首次启动时自动初始化,或手动初始化:
|
||
|
||
```python
|
||
from database import init_db
|
||
init_db()
|
||
```
|
||
|
||
## 快速启动
|
||
|
||
### 本地开发
|
||
|
||
```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 文档
|
||
|
||
### 认证系统
|
||
|
||
系统使用 JWT(JSON 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. 在 `database/models.py` 中定义模型类
|
||
2. 继承 `Base`
|
||
3. 运行数据库迁移(或重新初始化)
|
||
|
||
### 添加新的服务
|
||
|
||
1. 在 `services/` 目录创建服务文件
|
||
2. 实现服务类和方法
|
||
3. 在路由或其他服务中导入使用
|
||
|
||
## 安全注意事项
|
||
|
||
1. **CORS 配置**: 当前允许所有来源,生产环境应限制为特定域名
|
||
2. **API Key 安全**: 确保 `.env` 文件不被提交到版本控制
|
||
3. **SECRET_KEY 安全**: 使用强随机字符串作为 JWT 签名密钥,生产环境必须更换
|
||
4. **密码安全**: 密码使用 bcrypt 哈希存储,不会以明文形式保存
|
||
5. **令牌安全**:
|
||
- 访问令牌短期有效(2小时),降低泄露风险
|
||
- 刷新令牌存储在数据库中,支持撤销
|
||
- 令牌过期后必须使用刷新令牌重新获取
|
||
6. **数据库备份**: 定期备份 SQLite 数据库文件
|
||
7. **错误处理**: 所有 API 都包含适当的错误处理和权限验证
|
||
8. **日志记录**: 建议添加日志记录功能以便调试和监控
|
||
|
||
## 许可证
|
||
|
||
MIT License
|