325 lines
12 KiB
Plaintext
325 lines
12 KiB
Plaintext
# 智慧监督AI文书写作服务 - AI开发手册
|
||
|
||
## 项目背景
|
||
|
||
本项目是一个基于大模型的智能文书生成服务,主要功能包括:
|
||
- 从非结构化文本中提取结构化字段数据(使用AI大模型)
|
||
- 根据字段数据填充Word模板生成正式文书
|
||
- 支持多种业务类型的文书模板管理
|
||
- 文档存储和下载管理(MinIO对象存储)
|
||
|
||
核心业务流程:
|
||
1. 接收输入的非结构化文本数据
|
||
2. 使用AI大模型提取结构化字段
|
||
3. 根据字段数据填充Word模板
|
||
4. 生成文档并上传到MinIO
|
||
5. 返回文档下载链接
|
||
|
||
## 技术栈与编码标准
|
||
|
||
### 核心技术栈
|
||
- **Python版本**: Python 3.8+
|
||
- **Web框架**: Flask 3.0.0
|
||
- **数据库**: MySQL (使用PyMySQL 1.1.2)
|
||
- **文档处理**: python-docx 1.1.0
|
||
- **对象存储**: MinIO 7.2.3
|
||
- **AI服务**:
|
||
- 华为大模型 (DeepSeek-R1-Distill-Llama-70B)
|
||
- 硅基流动 (DeepSeek-V3.2-Exp)
|
||
- **其他依赖**: flask-cors, flasgger, python-dotenv, requests, openpyxl, json-repair
|
||
|
||
### 编码规范
|
||
- **代码风格**: 遵循PEP 8规范
|
||
- **命名规范**:
|
||
- 类名使用大驼峰命名(PascalCase):`AIService`, `DocumentService`
|
||
- 函数和变量使用小写下划线命名(snake_case):`get_connection`, `field_data`
|
||
- 常量使用全大写下划线命名:`AI_PROVIDER`, `DB_HOST`
|
||
- **注释要求**:
|
||
- 所有类和方法必须有docstring(使用三引号)
|
||
- 复杂逻辑必须添加行内注释
|
||
- 使用中文注释(项目统一使用中文)
|
||
- **类型提示**: 建议使用类型提示(typing模块),提高代码可读性
|
||
- **异常处理**: 必须使用try-except捕获异常,并提供有意义的错误信息
|
||
|
||
### 文件编码
|
||
- 所有Python文件使用UTF-8编码
|
||
- 文件开头不需要BOM标记
|
||
|
||
## 项目文件结构
|
||
|
||
```
|
||
.
|
||
├── app.py # Flask主应用,定义所有API路由
|
||
├── requirements.txt # Python依赖列表
|
||
├── .env.example # 环境变量配置示例
|
||
├── .cursorrules # AI开发手册(本文件)
|
||
├── services/ # 服务层(业务逻辑)
|
||
│ ├── __init__.py
|
||
│ ├── ai_service.py # AI服务:封装大模型调用逻辑
|
||
│ ├── document_service.py # 文档服务:Word模板填充、MinIO上传
|
||
│ ├── field_service.py # 字段服务:数据库字段配置查询
|
||
│ └── ai_logger.py # AI日志记录器
|
||
├── utils/ # 工具类
|
||
│ ├── __init__.py
|
||
│ └── response.py # 统一API响应格式工具
|
||
├── config/ # 配置文件
|
||
│ ├── prompt_config.json # AI提示词配置
|
||
│ └── field_defaults.json # 字段默认值配置
|
||
├── static/ # 静态文件
|
||
│ ├── index.html # 测试页面
|
||
│ └── template_field_manager.html # 模板字段管理页面
|
||
├── template/ # Word模板文件目录
|
||
├── template_finish/ # 已完成的模板文件
|
||
├── test_scripts/ # 测试脚本
|
||
└── 技术文档/ # 技术文档目录
|
||
```
|
||
|
||
## 架构约束与最佳实践
|
||
|
||
### 1. 分层架构
|
||
项目采用分层架构,严格遵循以下层次:
|
||
|
||
- **路由层** (`app.py`): 只负责接收HTTP请求、参数验证、调用服务层、返回响应
|
||
- **服务层** (`services/`): 包含所有业务逻辑,服务类之间可以相互调用
|
||
- **工具层** (`utils/`): 提供通用工具函数,不包含业务逻辑
|
||
- **数据层**: 数据库操作封装在服务层中,不单独抽象
|
||
|
||
**重要原则**:
|
||
- 路由层不包含业务逻辑,只做参数验证和响应格式化
|
||
- 服务层方法应该是可测试的,不依赖Flask的request对象
|
||
- 数据库连接在使用后必须关闭(使用try-finally确保)
|
||
|
||
### 2. 服务层设计规范
|
||
|
||
#### AI服务 (`services/ai_service.py`)
|
||
- 负责所有AI大模型调用
|
||
- 支持多种AI服务提供商(华为、硅基流动),通过环境变量切换
|
||
- 必须处理JSON解析失败的情况,提供多种修复机制
|
||
- 字段名规范化:将AI返回的各种字段名格式映射到正确的字段编码
|
||
- 日期格式规范化:统一转换为中文格式(YYYY年MM月 或 YYYY年MM月DD日)
|
||
- 后处理:从已有信息推断缺失字段(如从出生年月计算年龄)
|
||
|
||
#### 文档服务 (`services/document_service.py`)
|
||
- 负责Word模板下载、填充、上传
|
||
- 占位符格式:`{{field_code}}`(双大括号)
|
||
- 必须处理表格中的占位符(使用索引访问,避免迭代器bug)
|
||
- 提供XML备用方案处理特殊表格结构
|
||
- 文档名称生成:从原始文件名提取基础名称,添加被核查人姓名后缀
|
||
- MinIO路径格式:`/{tenant_id}/{timestamp}/{file_name}`
|
||
|
||
#### 字段服务 (`services/field_service.py`)
|
||
- 负责从数据库查询字段配置
|
||
- 构建AI提示词:根据输入数据和输出字段配置生成提示词
|
||
- 支持从配置文件加载提示词模板和字段默认值
|
||
|
||
### 3. 数据库设计规范
|
||
|
||
#### 主要数据表
|
||
- `f_polic_field`: 字段配置表
|
||
- `id`: 主键
|
||
- `name`: 字段名称
|
||
- `filed_code`: 字段编码(注意:数据库字段名是filed_code,不是field_code)
|
||
- `field_type`: 字段类型(1=输入字段,2=输出字段)
|
||
- `state`: 状态(1=启用,0=禁用)
|
||
|
||
- `f_polic_file_config`: 文件配置表(模板配置)
|
||
- `id`: 主键(作为fileId使用)
|
||
- `name`: 文件名称
|
||
- `file_path`: MinIO中的文件路径
|
||
- `input_data`: JSON格式的输入数据配置
|
||
- `state`: 状态(1=启用,0=禁用)
|
||
|
||
- `f_polic_file_field`: 文件字段关联表
|
||
- `file_id`: 文件配置ID
|
||
- `filed_id`: 字段ID
|
||
- `state`: 状态(1=启用,0=禁用)
|
||
|
||
#### 数据库操作规范
|
||
- 所有数据库操作必须使用参数化查询,防止SQL注入
|
||
- 使用`pymysql.cursors.DictCursor`获取字典格式结果
|
||
- 数据库连接必须在使用后关闭(try-finally模式)
|
||
- 事务操作必须正确处理回滚
|
||
|
||
### 4. API设计规范
|
||
|
||
#### 统一响应格式
|
||
所有API必须使用`utils/response.py`中的工具函数:
|
||
|
||
**成功响应**:
|
||
```python
|
||
return success_response(data={'key': 'value'}, msg="ok")
|
||
```
|
||
|
||
**错误响应**:
|
||
```python
|
||
return error_response(code=400, error_msg="错误信息")
|
||
```
|
||
|
||
**响应结构**:
|
||
```json
|
||
{
|
||
"code": 0, // 0表示成功,其他值表示错误码
|
||
"data": {}, // 响应数据
|
||
"msg": "ok", // 响应消息
|
||
"timestamp": "1234567890", // 时间戳(毫秒)
|
||
"errorMsg": "", // 错误信息(成功时为空)
|
||
"isSuccess": true // 是否成功
|
||
}
|
||
```
|
||
|
||
#### API路由规范
|
||
- 使用`@app.route`装饰器定义路由
|
||
- 支持Swagger文档(使用flasgger)
|
||
- 路由路径使用小写字母和连字符:`/api/ai/extract`
|
||
- 保留旧路径以兼容:`/ai/extract` 和 `/api/ai/extract` 同时支持
|
||
|
||
#### 错误码规范
|
||
- `0`: 成功
|
||
- `400`: 请求参数错误
|
||
- `500`: 服务器内部错误
|
||
- `1001`: 模板不存在
|
||
- `2001`: AI解析超时
|
||
- `2002`: AI解析失败
|
||
- `3001`: 文件生成失败
|
||
- `3002`: 文件保存失败
|
||
|
||
### 5. 环境变量配置
|
||
|
||
所有配置通过环境变量管理,使用`.env`文件(不要提交到版本控制):
|
||
|
||
**必需配置**:
|
||
- `DB_HOST`: 数据库主机
|
||
- `DB_PORT`: 数据库端口
|
||
- `DB_USER`: 数据库用户名
|
||
- `DB_PASSWORD`: 数据库密码
|
||
- `DB_NAME`: 数据库名称
|
||
- `MINIO_ENDPOINT`: MinIO服务地址
|
||
- `MINIO_ACCESS_KEY`: MinIO访问密钥
|
||
- `MINIO_SECRET_KEY`: MinIO密钥
|
||
- `MINIO_BUCKET`: MinIO存储桶名称
|
||
- `MINIO_SECURE`: 是否使用HTTPS(true/false)
|
||
|
||
**AI服务配置**:
|
||
- `AI_PROVIDER`: AI服务提供商('huawei' 或 'siliconflow')
|
||
- `HUAWEI_API_ENDPOINT`: 华为API地址
|
||
- `HUAWEI_API_KEY`: 华为API密钥
|
||
- `HUAWEI_MODEL`: 华为模型名称
|
||
- `HUAWEI_API_TIMEOUT`: 超时时间(秒)
|
||
- `HUAWEI_API_MAX_TOKENS`: 最大token数
|
||
- `SILICONFLOW_URL`: 硅基流动API地址
|
||
- `SILICONFLOW_API_KEY`: 硅基流动API密钥
|
||
- `SILICONFLOW_MODEL`: 硅基流动模型名称
|
||
- `SILICONFLOW_API_TIMEOUT`: 超时时间(秒)
|
||
- `SILICONFLOW_API_MAX_TOKENS`: 最大token数
|
||
|
||
**可选配置**:
|
||
- `PORT`: 服务端口(默认7500)
|
||
- `DEBUG`: 调试模式(true/false,默认false)
|
||
- `TENANT_ID`: 租户ID(用于MinIO路径)
|
||
|
||
### 6. 错误处理规范
|
||
|
||
- 所有可能失败的操作必须使用try-except捕获异常
|
||
- 异常信息要详细,包含上下文信息
|
||
- 数据库操作异常必须回滚事务
|
||
- 文件操作异常必须清理临时文件
|
||
- 对外暴露的错误信息要友好,不泄露内部实现细节
|
||
|
||
**示例**:
|
||
```python
|
||
try:
|
||
# 业务逻辑
|
||
result = some_operation()
|
||
return success_response(data=result)
|
||
except ValueError as e:
|
||
return error_response(400, f"参数错误: {str(e)}")
|
||
except Exception as e:
|
||
# 记录详细错误日志
|
||
print(f"[ERROR] 操作失败: {str(e)}")
|
||
import traceback
|
||
print(traceback.format_exc())
|
||
return error_response(500, "服务器内部错误")
|
||
```
|
||
|
||
### 7. 日志规范
|
||
|
||
- 使用`print`输出日志(项目当前使用print,不是logging模块)
|
||
- 日志格式:`[级别] 消息内容`
|
||
- 日志级别:
|
||
- `[DEBUG]`: 调试信息(详细的执行过程)
|
||
- `[INFO]`: 一般信息(正常流程)
|
||
- `[WARN]`: 警告信息(不影响功能但需要注意)
|
||
- `[ERROR]`: 错误信息(功能失败)
|
||
- 关键操作必须记录日志:AI调用、文件生成、数据库操作
|
||
|
||
### 8. 代码质量要求
|
||
|
||
- **可读性**: 代码要清晰易懂,变量名要有意义
|
||
- **可维护性**: 避免重复代码,提取公共方法
|
||
- **可测试性**: 服务层方法应该是纯函数,便于单元测试
|
||
- **健壮性**: 处理边界情况,避免崩溃
|
||
- **性能**: 数据库查询要优化,避免N+1查询
|
||
|
||
### 9. 特殊注意事项
|
||
|
||
#### Word模板处理
|
||
- 使用`python-docx`库处理Word文档
|
||
- 占位符格式:`{{field_code}}`(双大括号)
|
||
- 表格访问必须使用索引方式,避免迭代器导致的IndexError
|
||
- 处理跨run的占位符时,需要合并runs并保持格式
|
||
- 某些复杂表格结构可能导致访问失败,提供XML备用方案
|
||
|
||
#### AI字段提取
|
||
- AI返回的JSON可能格式不正确,需要多种修复机制
|
||
- 字段名可能不规范(如`_source`、`target_organisation`),需要规范化映射
|
||
- 日期格式需要统一转换为中文格式
|
||
- 缺失字段需要从已有信息推断(如从出生年月计算年龄)
|
||
|
||
#### MinIO文件管理
|
||
- 文件路径使用相对路径(以`/`开头)
|
||
- 上传文件时自动生成时间戳路径
|
||
- 支持生成预签名下载URL(7天有效期)
|
||
- 临时文件使用后必须清理
|
||
|
||
## 开发工作流
|
||
|
||
1. **添加新功能**:
|
||
- 在服务层添加业务逻辑方法
|
||
- 在路由层添加API端点
|
||
- 更新Swagger文档注释
|
||
- 测试功能是否正常
|
||
|
||
2. **修改现有功能**:
|
||
- 理解现有代码逻辑
|
||
- 保持API接口兼容性(如需要修改,考虑版本控制)
|
||
- 更新相关文档
|
||
|
||
3. **调试问题**:
|
||
- 查看日志输出(使用[DEBUG]级别)
|
||
- 检查数据库数据是否正确
|
||
- 验证环境变量配置
|
||
- 测试AI服务是否可用
|
||
|
||
## 常见问题处理
|
||
|
||
1. **AI解析失败**: 检查输入文本质量,查看AI日志,尝试修复JSON格式
|
||
2. **模板填充失败**: 检查占位符格式是否正确,查看表格结构是否异常
|
||
3. **MinIO上传失败**: 检查网络连接,验证MinIO配置和权限
|
||
4. **数据库连接失败**: 检查数据库配置和网络连接
|
||
|
||
## 代码生成指导
|
||
|
||
当AI需要生成代码时,请遵循以下原则:
|
||
|
||
1. **保持一致性**: 遵循项目现有的代码风格和架构模式
|
||
2. **错误处理**: 所有可能失败的操作都要有异常处理
|
||
3. **日志记录**: 关键操作要记录日志
|
||
4. **参数验证**: API接口要验证输入参数
|
||
5. **资源清理**: 文件、数据库连接等资源要正确清理
|
||
6. **中文注释**: 使用中文编写注释和文档字符串
|
||
7. **类型提示**: 建议使用类型提示提高代码可读性
|
||
|
||
## 更新日志
|
||
|
||
- 2025-12-13: 创建初始版本
|