Files
life-echo/api
Kevin aac484463d feat(api): 拆分章节物化与 Story 后处理,并加固 Redis 锁与腾讯 ASR
回忆录 Story 流水线(同步)
- 同步路径仅写入 Story 与章节关联,改为 mark_chapter_dirty_sync,不再内联 compose
- 物化由 Celery recompose_chapter 异步完成;compose 不变量与异常时保留 dirty 的语义在 repo 中补充说明
- Evidence:大批次时降低 top_k;路由候选 story 携带 char_count/version_count;append 超长/版本过多时强制新开 story
- 叙事 prompt:relevant_chunks 去重,减少重复证据噪声
- 叙事回退与忠实度 gate:返回 fallback 类型并记录结构化日志(含耗时、JSON 有效性等)

Post-commit 与任务编排
- 新增 post_commit.enqueue_story_post_commit_effects:统一派发 generate_story_image(Redis 去重)、延迟 recompose_chapter、可选 memory compaction
- memoir_tasks / story_service / story_image_tasks 改为调用 post-commit 入口;主图回填后按关联章节重算并调度物化与 compacs(锁委托、Redis 单例、ASR to_thread)
- 更新 test_narrative_pipeline 以适配 _apply_narrative_fallbacks 返回值
2026-03-30 11:53:04 +08:00
..
2026-03-23 13:21:07 +08:00
2026-01-18 15:58:05 +08:00
2026-03-25 17:40:04 +08:00
2026-03-23 13:54:41 +08:00
2026-03-23 13:21:07 +08:00
2026-03-19 14:36:40 +08:00
2026-03-23 13:54:41 +08:00

Life Echo API

Life Echo 后端服务,基于 FastAPI 构建的实时语音对话回忆录生成系统。

项目简介

Life Echo API 是一个智能对话系统,通过 WebSocket 实时连接,使用 LangChain Agent 引导用户进行回忆录访谈对话,并将口语内容自动整理为结构化的书面章节,最终生成回忆录 PDF。

架构要点(多 Agent 收敛)

  • 会话真源conversation_messagesDB+ Redis 缓存;实时编排入口ChatOrchestrator
  • 图像管线:正文主图 generate_story_image;章节封面 try_enqueue_generate_chapter_covergenerate_chapter_cover
  • 回忆录批次MemoirOrchestrator.prepare_batches 显式分桶后,process_memoir_segments 按类别加锁并调用 run_story_pipeline_for_category_batch(含 StoryRouteAgent.plan_batch 多 unit 写入)。

LLM 与记忆(约定文档)

技术栈

  • 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. 安装依赖

cd api
pip install -r requirements.txt

2. 环境变量配置

创建 .env 文件(在 api/ 目录下):

# 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 配置示例

DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxx
DEEPSEEK_MODEL=deepseek-chat

3. 数据库迁移

数据库 schema 由 Alembic 管理。app/main.py 启动时会在线程中执行 alembic upgrade head(见 app/core/alembic_startup.py):对连接类错误自动重试;生产环境建议设置 ALEMBIC_STARTUP_FAIL_FAST=true,迁移失败则进程退出。仍可手动执行:

cd api
uv run alembic upgrade head

快速启动

本地开发

推荐使用一键脚本(会自动启动 PostgreSQL/Redis、检查 .venv、安装依赖并拉起 FastAPI + Celery

cd api
./dev-up.sh

可选环境变量:

  • SKIP_INSTALL=1:跳过依赖安装
  • API_HOST / API_PORT:覆盖 API 启动地址和端口
  • CELERY_POOL:覆盖 Celery 池类型macOS 推荐 solo

也可以使用手动方式:

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

验证服务

# 检查 PostgreSQL
docker exec life-echo-postgres-dev psql -U postgres -c "SELECT 1"

# 检查 Redis  
docker exec life-echo-redis-dev redis-cli ping

生产部署(一键)

cd api

# 创建生产配置
cp .env .env.prod
# 编辑 .env.prod

# 启动所有服务
docker compose up -d

# 查看日志
docker compose logs -f

服务启动后,访问:

📚 详细文档

更多详细文档请参考 docs/README.md

API 文档

认证系统

系统使用 JWTJSON Web Token进行认证采用访问令牌Access Token+ 刷新令牌Refresh Token机制

  • 访问令牌:有效期 2 小时,用于 API 请求认证
  • 刷新令牌:有效期 30 天,用于刷新访问令牌

认证流程

  1. 用户注册POST /api/auth/register
  2. 用户登录POST /api/auth/login → 返回 access_tokenrefresh_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)

用户注册
POST /api/auth/register
Content-Type: application/json

{
  "phone": "13800138000",
  "password": "password123",
  "nickname": "用户昵称",
  "email": "user@example.com"  // 可选
}

响应

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "random-refresh-token-string",
  "token_type": "bearer"
}
用户登录
POST /api/auth/login
Content-Type: application/json

{
  "phone": "13800138000",
  "password": "password123"
}

响应:同注册接口

刷新访问令牌
POST /api/auth/refresh
Content-Type: application/json

{
  "refresh_token": "your-refresh-token"
}

响应

{
  "access_token": "new-access-token",
  "refresh_token": "same-refresh-token",
  "token_type": "bearer"
}
用户登出
POST /api/auth/logout
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "refresh_token": "your-refresh-token"
}
获取当前用户信息
GET /api/auth/me
Authorization: Bearer {access_token}

响应

{
  "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 中携带访问令牌:

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
  • 只能连接属于当前用户的对话
  • 如果对话不存在,将自动创建并关联到当前用户

消息格式:

客户端 → 服务端:

{
  "type": "audio",
  "data": "base64_encoded_audio_data"
}

服务端 → 客户端:

{
  "type": "transcript",
  "text": "识别出的文本",
  "agent_response": "Agent 的回复"
}
{
  "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
  • user_input_text: 用户输入正文(语音 ASR 或文字输入;历史列名 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 中注册路由:
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