Replace CreateRecTask polling with recording-file flash API, add TENCENT_APP_ID, remove server-side pydub slicing, and log ASR recognition text at INFO in development. Co-authored-by: Cursor <cursoragent@cursor.com>
587 lines
20 KiB
Markdown
587 lines
20 KiB
Markdown
# Life Echo API
|
||
|
||
Life Echo 后端服务,基于 FastAPI 构建的实时语音对话回忆录生成系统。
|
||
|
||
## 项目简介
|
||
|
||
Life Echo API 是一个智能对话系统,通过 WebSocket 实时连接,使用 LangChain Agent 引导用户进行回忆录访谈对话,并将口语内容自动整理为结构化的书面章节,最终生成回忆录 PDF。
|
||
|
||
### 架构要点(多 Agent 收敛)
|
||
|
||
- **会话真源**:`conversation_messages`(DB)+ Redis 缓存;**实时编排入口**:`ChatOrchestrator`。
|
||
- **图像管线**:正文主图 `generate_story_image`;章节封面 `try_enqueue_generate_chapter_cover` → `generate_chapter_cover`。
|
||
- **回忆录批次**:`MemoirOrchestrator.prepare_batches` 显式分桶后,`process_memoir_phase1` 派发 Phase 2 按类别调用 `run_story_pipeline_for_category_batch`(含 `StoryRouteAgent.plan_batch` 多 unit 写入)。
|
||
|
||
### LLM 与记忆(约定文档)
|
||
|
||
- **JSON 模式**:结构化抽取/路由/叙事 JSON 使用 `app/core/langchain_llm.py` 的 `bind_json_object_mode`(与 [DeepSeek JSON Output](https://api-docs.deepseek.com/guides/json_mode) 一致);详见 [`docs/llm-json-mode.md`](docs/llm-json-mode.md)。适配器说明见 [`app/adapters/llm/deepseek.py`](app/adapters/llm/deepseek.py)。
|
||
- **记忆检索**:异步与 Celery 均使用 **向量(pgvector)** chunks,见 [`docs/memory-retrieval.md`](docs/memory-retrieval.md)(含 async/sync **行为矩阵**)。
|
||
- **AI 相关代码扫描**:`uv run python scripts/ai_touchpoints_scan.py --markdown docs/ai-touchpoints.md`(在 `api/` 目录下执行)生成带标签的触点列表,见 [`docs/ai-touchpoints.md`](docs/ai-touchpoints.md)。
|
||
- **与 AI 强相关的配置项**:产品调参 SSOT 为 [`config/*.toml`](config/default.toml)(经 `app/features/*/constants.py` 与 `app/core/runtime_constants.py` re-export);密钥见 [`.env.example`](.env.example)。详见 [`docs/configuration.md`](docs/configuration.md)。
|
||
- **Memory compaction**:默认在 `config/default.toml` → `[memory]` 中开启。须运行 **Celery worker** 与 **celery-beat**([`docker-compose.yml`](docker-compose.yml) 已包含 `celery-beat`,用于定期 `memory_compaction_sweep`)。
|
||
- **Memory LLM enrichment(单次 LLM:会话摘要 + 事实)**:任务路由到 **`memory_idle`** 队列(`config/default.toml` → `[celery] memory_enrichment_queue`)。本地与 compose 内 worker 已使用 `-Q celery,memory_idle`;生产可单独起低并发 worker 只消费 `memory_idle`,与主队列隔离。
|
||
|
||
## 技术栈
|
||
|
||
- **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**: 腾讯云 ASR(`16k_zh_large`)/ TTS
|
||
- **认证**: JWT (python-jose) + bcrypt
|
||
- **其他**: Pydantic, python-dotenv
|
||
- **可观测性**: OpenTelemetry → Grafana LGTM(Tempo / Prometheus / Loki),见 [`docs/observability.md`](docs/observability.md)
|
||
|
||
## 可观测性(本地)
|
||
|
||
```bash
|
||
docker compose -f docker-compose.dev.yml -f docker-compose.observability.yml up -d
|
||
# Grafana: http://127.0.0.1:48300
|
||
```
|
||
|
||
在 `config/*.toml` 的 `[deploy]` 中配置 `otel_enabled` 与 `otel_exporter_otlp_endpoint`;采样策略等细项见 `[otel]` section 与 [`docs/observability.md`](docs/observability.md)。
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
api/
|
||
├── main.py # 应用入口(uvicorn 启动)
|
||
├── app/ # 应用主包
|
||
│ ├── main.py # FastAPI 应用定义
|
||
│ ├── core/ # 核心基础设施
|
||
│ │ ├── config.py # secrets / bootstrap(Settings + facade)
|
||
│ │ ├── app_config*.py # TOML 加载与 AppConfig
|
||
│ │ ├── runtime_constants.py # re-export config/*.toml runtime sections
|
||
│ │ ├── 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. 配置(TOML + .env)
|
||
|
||
配置分两层 SSOT,详见 **[docs/configuration.md](docs/configuration.md)**。
|
||
|
||
| 层 | 来源 | 内容 |
|
||
|----|------|------|
|
||
| **Secrets / bootstrap** | [`.env.example`](.env.example) | `DATABASE_URL`、`SECRET_KEY`、API/支付/Liblib 密钥 |
|
||
| **非密钥** | [`config/default.toml`](config/default.toml) + `config/{APP_ENV}.toml` | 功能开关、SMS 模板、Chat/Memoir/Memory/Eval 调参、OTel 等 |
|
||
|
||
本地开发:`.env.development`(密钥)+ `config/development.toml`(行为);`development.sh` 将前者同步为 `.env`。预发/生产:`.env.staging` / `.env.production` + 对应 `config/*.toml`。
|
||
|
||
最小 `.env` 示例:
|
||
|
||
```env
|
||
APP_ENV=development
|
||
DATABASE_URL=postgresql://postgres:postgres@localhost:48291/life_echo
|
||
REDIS_URL=redis://localhost:48307/0
|
||
SECRET_KEY=your-secret-key-here
|
||
DEEPSEEK_API_KEY=sk-...
|
||
ZHIPU_API_KEY=...
|
||
TENCENT_SECRET_ID=...
|
||
TENCENT_SECRET_KEY=...
|
||
```
|
||
|
||
**腾讯云**:凭证仍在 env(`TENCENT_SECRET_ID/KEY`);短信模板 ID、COS 桶名等在 `config/*.toml` 的 `[deploy]` section。
|
||
|
||
业务代码读取 TOML 值仍可用原有 import(re-export):
|
||
|
||
| 模块 | 路径 |
|
||
|------|------|
|
||
| 访谈 / 聊天 | `app/features/conversation/constants.py` → `chat` |
|
||
| 回忆录流水线 | `app/features/memoir/constants.py` → `memoir` |
|
||
| Story / 章节 | `app/features/story/constants.py` → `story` |
|
||
| 记忆富化 / compaction | `app/features/memory/constants.py` → `memory` |
|
||
| 内网评测 | `app/features/evaluation/constants.py` → `eval_cfg` |
|
||
| ASR/TTS/LLM/Celery 等 | `app/core/runtime_constants.py` |
|
||
|
||
### 3. 数据库迁移
|
||
|
||
数据库 schema 由 Alembic 管理。**`app/main.py` 启动时会在线程中执行 `alembic upgrade head`**(见 `app/core/alembic_startup.py`):对连接类错误自动重试;生产环境建议设置 `ALEMBIC_STARTUP_FAIL_FAST=true`,迁移失败则进程退出。
|
||
|
||
规范与跨环境排障见 **[docs/alembic-migrations.md](docs/alembic-migrations.md)**(禁止改已部署 revision id、老库用显式 `0019` 补列等)。
|
||
|
||
```bash
|
||
cd api
|
||
uv run alembic upgrade head
|
||
uv run pytest tests/test_alembic_migration_policy.py -q
|
||
```
|
||
|
||
若库中仍为已撤回的 `0020_*` revision,部署前先执行 `uv run python scripts/repair_alembic_version_after_withdrawn_0020.py`(见上文文档)。
|
||
|
||
## 快速启动
|
||
|
||
### 本地开发
|
||
|
||
推荐使用一键脚本(会自动启动 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. 配置环境变量(与 docker-compose.dev.yml 固定宿主端口一致:Postgres 48291、Redis 48307)
|
||
export DATABASE_URL=postgresql://postgres:postgres@localhost:48291/life_echo
|
||
export REDIS_URL=redis://localhost:48307/0
|
||
|
||
# 4. 启动 API(终端 1)
|
||
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||
|
||
# 5. 启动 Celery Worker(终端 2)
|
||
# macOS 使用 solo 池避免 fork 崩溃问题;须同时消费 memory_idle(Memory 富化)
|
||
celery -A app.tasks.celery_app worker --loglevel=info --pool=solo -Q celery,memory_idle
|
||
|
||
# Linux/生产环境可以使用 prefork 池
|
||
# celery -A app.tasks.celery_app worker --loglevel=info --concurrency=4 -Q celery,memory_idle
|
||
```
|
||
|
||
### 验证服务
|
||
|
||
```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": "new-refresh-token-string",
|
||
"token_type": "bearer"
|
||
}
|
||
```
|
||
|
||
每次刷新会轮换 refresh token(返回新的 refresh token,旧 token 立即失效)。在 `REFRESH_TOKEN_REUSE_GRACE_SECONDS`(默认 30 秒)窗口内重复使用已轮换的旧 token 视为幂等重试,返回新 access token 与当前 replacement refresh token;grace 窗口外再次使用则吊销该用户全部会话并返回 `REFRESH_TOKEN_REUSE`。
|
||
|
||
##### 用户登出
|
||
```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}
|
||
```
|
||
|
||
### HTTP 错误契约
|
||
|
||
所有 HTTP 错误响应均为 `application/json`,统一格式:
|
||
|
||
```json
|
||
{
|
||
"error_code": "NOT_FOUND",
|
||
"message": "资源不存在",
|
||
"request_id": "550e8400-e29b-41d4-a716-446655440000"
|
||
}
|
||
```
|
||
|
||
- `error_code`:机器可读错误码(见 OpenAPI `ErrorResponse` / `ErrorCode` 组件)
|
||
- `message`:面向用户的说明
|
||
- `request_id`:与响应头 `X-Request-Id` 一致,便于排查
|
||
|
||
**429 状态码语义**:HTTP 429 被两种错误码共用,客户端必须根据 `error_code` 分支,不能只看 status:
|
||
|
||
| error_code | 含义 |
|
||
|------------|------|
|
||
| `QUOTA_EXCEEDED` | 配额已用尽(如对话次数) |
|
||
| `RATE_LIMITED` | 请求频率超限(如 SMS 发送冷却) |
|
||
|
||
遗留 `HTTPException(status_code=429)` 默认映射为 `RATE_LIMITED`。
|
||
|
||
**CORS 与 credentials**:`api_cors_origins` 留空时,服务端使用 `allow_origins=["*"]` 且 `allow_credentials=False`;生产/staging 必须在 `config/staging.toml` / `config/production.toml` 的 `[deploy]` 中配置逗号分隔的前端域名。
|
||
|
||
### 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"
|
||
}
|
||
```
|
||
|
||
**WebSocket 错误消息**(与 HTTP 错误契约不同,勿混用 `parseApiError`):
|
||
|
||
服务端 → 客户端(配额不足等):
|
||
```json
|
||
{
|
||
"type": "error",
|
||
"data": {
|
||
"message": "本月对话次数已用尽",
|
||
"code": "QUOTA_EXCEEDED"
|
||
},
|
||
"timestamp": "2024-01-15T10:00:00Z"
|
||
}
|
||
```
|
||
|
||
- WS 帧使用 `data.code`(如 `QUOTA_EXCEEDED`),**不是** HTTP 的 `error_code` 字段
|
||
- HTTP 客户端错误解析器(`parseApiError`)不适用于 WebSocket 消息
|
||
|
||
## 数据库模型
|
||
|
||
### 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 (语音识别)**: 腾讯云录音文件识别极速版(Flash 同步接口,引擎 `16k_zh_large`);需配置 `TENCENT_APP_ID`;客户端按 15s 分段上传
|
||
- **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 配置**: 本地开发默认可用 `allow_origins=["*"]`(`deploy.api_cors_origins` 留空);生产/staging 必须在 `config/staging.toml` / `config/production.toml` 的 `[deploy]` 中设置逗号分隔前端域名
|
||
2. **API Key 安全**: 确保 `.env` 文件不被提交到版本控制
|
||
3. **SECRET_KEY 安全**: 使用强随机字符串作为 JWT 签名密钥,生产环境必须更换
|
||
4. **密码安全**: 密码使用 bcrypt 哈希存储,不会以明文形式保存
|
||
5. **令牌安全**:
|
||
- 访问令牌短期有效(2小时),降低泄露风险
|
||
- 刷新令牌存储在数据库中,支持撤销;每次 `/api/auth/refresh` 会轮换 refresh token
|
||
- 已轮换的 refresh token 被再次使用时,服务端吊销全部会话并返回 `REFRESH_TOKEN_REUSE`
|
||
- 令牌过期后必须使用刷新令牌重新获取
|
||
6. **数据库备份**: 定期备份 PostgreSQL 数据库
|
||
7. **错误处理**: 所有 API 都包含适当的错误处理和权限验证
|
||
8. **日志记录**: 建议添加日志记录功能以便调试和监控
|
||
|
||
## 许可证
|
||
|
||
MIT License
|