TravelContentCreator/docs/REFACTORING_IMPLEMENTATION.md

350 lines
7.8 KiB
Markdown
Raw Normal View History

2025-12-08 14:58:35 +08:00
# 技术债务重构实施文档
> 本文档记录技术债务改进的具体实施过程
---
## 实施计划
| # | 改进项 | 状态 | 完成时间 |
|---|-------|------|---------|
| 1 | 数据库访问改接口 | ✅ 完成 | 2024-12-08 |
| 2 | 图片传输改 URL | ✅ 完成 | 2024-12-08 |
| 3 | 放弃 ppid | ✅ 完成 | 2024-12-08 |
| 4 | Prompt Registry | ✅ 完成 | 2024-12-08 |
| 5 | 依赖注入统一 | ✅ 完成 | 2024-12-08 |
---
## 1. 数据库访问改接口
### 目标
Python 端不再直接连接数据库,所有数据由 Java 端通过 HTTP 接口传递。
### 改动前架构
```
┌─────────────┐ ┌─────────────┐
│ Java 端 │ │ Python 端 │
└──────┬──────┘ └──────┬──────┘
│ │
│ 各自连接 │ 各自连接
▼ ▼
┌─────────────────────────┐
│ MySQL │
└─────────────────────────┘
```
### 改动后架构
```
┌─────────────┐ ┌─────────────┐
│ Java 端 │ ──── HTTP ────────>│ Python 端 │
└──────┬──────┘ (完整数据) └─────────────┘
│ │
│ 唯一数据源 │ 无数据库访问
▼ │
┌─────────────────────────┐ │
│ MySQL │ X
└─────────────────────────┘
```
### 新的接口协议
Java 端调用 Python 端时,传递完整数据:
```json
{
"engine": "topic_generate",
"params": {
"num_topics": 5,
"month": "2024-12",
// 直接传完整对象,而不是 ID
"scenic_spot": {
"id": 1,
"name": "天津冒险湾",
"description": "主题乐园...",
"location": "天津市"
},
"product": {
"id": 10,
"name": "门票套餐",
"price": 299,
"description": "..."
},
"style": {
"id": 5,
"name": "攻略风",
"description": "实用性强..."
},
"audience": {
"id": 3,
"name": "亲子家庭",
"description": "..."
}
}
}
```
### 实施步骤
1. [x] 定义新的参数 Schema
2. [x] 创建 V2 引擎接收完整对象
3. [x] V2 引擎不访问数据库
4. [ ] 更新 Java 端调用方式 (待 Java 端配合)
### 已创建文件
- `domain/aigc/engines/topic_generate_v2.py` - 选题生成 V2
- `domain/aigc/engines/content_generate_v2.py` - 内容生成 V2
- `domain/aigc/engines/poster_generate_v2.py` - 海报生成 V2
---
## 2. 图片传输改 URL
### 目标
不再传递 Base64改为传递图片 URL 或路径。
### 新的接口协议
```json
{
"engine": "poster_generate",
"params": {
"template_id": "vibrant",
// 方式1: S3 URL
"image_urls": [
"https://s3.xxx.com/bucket/image1.jpg",
"https://s3.xxx.com/bucket/image2.jpg"
],
// 方式2: 本地路径 (如果共享存储)
"image_paths": [
"/data/images/123.jpg"
],
// 方式3: 素材 ID (Python 自行获取)
"material_ids": [123, 456]
}
}
```
### 实施步骤
1. [x] 修改引擎支持 URL 下载
2. [x] 添加图片下载工具 (aiohttp)
3. [ ] 更新 Java 端传参方式 (待 Java 端配合)
### 已实现
`PosterGenerateEngineV2` 支持三种图片来源:
- `image_urls` - 从 URL 下载 (推荐)
- `image_paths` - 从本地路径读取
- `images_base64` - Base64 (兼容旧接口)
---
## 3. 放弃 ppid
### 目标
不再使用 ppidJava 端直接传递解析后的完整数据。
### 改动
- 移除 Python 端的 `resolve_ppid()` 逻辑
- 移除 `ProductPackageRepository`
- 引擎参数 Schema 中移除 `ppid`
### 实施步骤
1. [x] V2 引擎不包含 ppid 参数
2. [x] V2 引擎不访问 ProductPackageRepository
3. [x] 参数 Schema 只接收完整对象
### 说明
V2 引擎的参数 Schema 中没有 `ppid`,只接收:
- `scenic_spot` - 完整景区对象
- `product` - 完整产品对象
- `style` - 完整风格对象
- `audience` - 完整受众对象
Java 端需要在调用前解析 ppid 并传递完整数据。
---
## 4. Prompt Registry
### 目标
集中管理 Prompt支持版本化。
### 目录结构
```
prompts/
├── topic_generate/
│ └── v1.0.0.yaml
├── content_generate/
│ └── v1.0.0.yaml
└── content_judge/
└── v1.0.0.yaml
```
### 实施步骤
1. [x] 创建 `domain/prompt/` 模块
2. [x] 实现 `PromptRegistry`
3. [x] 迁移现有 prompt 到 YAML
4. [x] V2 引擎使用新 Registry
### 已创建文件
**模块:**
- `domain/prompt/__init__.py`
- `domain/prompt/registry.py` - PromptRegistry 实现
**Prompt 配置:**
- `prompts/topic_generate/v1.0.0.yaml`
- `prompts/content_generate/v1.0.0.yaml`
- `prompts/content_judge/v1.0.0.yaml`
### 使用示例
```python
from domain.prompt import PromptRegistry
registry = PromptRegistry('prompts')
# 渲染 prompt
system, user = registry.render(
'content_generate',
context={'style_content': '...', 'demand_content': '...', ...},
version='latest'
)
# 获取模型参数
config = registry.get('content_generate')
params = config.get_model_params() # {'temperature': 0.3, ...}
```
---
## 5. 依赖注入统一
### 目标
统一使用容器模式管理依赖。
### 实施步骤
1. [x] 创建 `Container`
2. [x] 实现服务注册和获取
3. [ ] 逐步迁移现有依赖获取方式 (渐进式)
### 已创建文件
- `domain/container.py` - Container 实现
### 使用示例
```python
from domain.container import Container, get_service, inject
# 方式1: 直接获取
from core.config import ConfigManager
config = Container.get(ConfigManager)
# 方式2: 便捷函数
from domain import get_service
config = get_service(ConfigManager)
# 方式3: 装饰器注入
@inject(ConfigManager, AIAgent)
def my_function(config, agent, other_param):
...
```
### 说明
Container 采用渐进式迁移策略:
- 新代码使用 Container
- 旧代码保持不变,逐步迁移
- V2 引擎内部使用延迟加载,兼容两种方式
---
## 变更日志
| 日期 | 改动 | 文件 |
|-----|------|------|
| 2024-12-08 | 创建实施文档 | docs/REFACTORING_IMPLEMENTATION.md |
| 2024-12-08 | 创建 PromptRegistry | domain/prompt/registry.py |
| 2024-12-08 | 创建 Container | domain/container.py |
| 2024-12-08 | 创建 V2 引擎 | domain/aigc/engines/*_v2.py |
| 2024-12-08 | 迁移 Prompt 到 YAML | prompts/*.yaml |
---
## 新旧引擎对比
| 特性 | V1 引擎 | V2 引擎 |
|-----|--------|--------|
| 数据库访问 | ✅ 直接访问 | ❌ 不访问 |
| ppid 支持 | ✅ 自动解析 | ❌ 不支持 |
| 图片传输 | Base64 | URL/路径/Base64 |
| Prompt 管理 | 文件模板 | PromptRegistry |
| 依赖注入 | 延迟加载 | Container |
## Java 端调用示例
### V1 引擎 (旧)
```json
{
"engine": "topic_generate",
"params": {
"ppid": 12345,
"num_topics": 5
}
}
```
### V2 引擎 (新)
```json
{
"engine": "topic_generate_v2",
"params": {
"num_topics": 5,
"month": "2024-12",
"scenic_spot": {
"id": 1,
"name": "天津冒险湾",
"description": "..."
},
"product": {
"id": 10,
"name": "门票套餐",
"price": 299
}
}
}
```
---
## 待办事项
- [ ] Java 端更新调用方式,使用 V2 引擎
- [ ] 验证 V2 引擎功能正确性
- [ ] 清理 V1 引擎中的数据库访问代码 (可选)
- [ ] 删除 Python 端的 database_service.py (待确认无其他依赖)