- 新增WechatService(企业微信推送服务,支持文本/卡片/Markdown消息) - 新增WechatCallbackController(异步回复模式,5秒内响应) - 完善iit_quality_check Worker(调用WechatService推送通知) - 新增企业微信回调路由(GET验证+POST接收消息) - 实现LLM意图识别(query_weekly_summary/query_patient_info等) - 安装依赖:@wecom/crypto, xml2js - 更新开发记录文档和MVP开发计划 技术要点: - 使用异步回复模式规避企业微信5秒超时限制 - 使用@wecom/crypto官方库处理XML加解密 - 使用setImmediate实现后台异步处理 - 支持主动推送消息返回LLM处理结果 - 完善审计日志记录(WECHAT_NOTIFICATION_SENT/WECHAT_INTERACTION) 相关文档: - docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成开发完成记录.md - docs/03-业务模块/IIT Manager Agent/04-开发计划/最小MVP闭环开发计划.md - docs/03-业务模块/IIT Manager Agent/00-模块当前状态与开发指南.md
564 lines
12 KiB
Markdown
564 lines
12 KiB
Markdown
# 工具C - AI Copilot Few-shot示例库
|
||
|
||
> **文档版本**: V1.0
|
||
> **创建日期**: 2025-12-06
|
||
> **用途**: System Prompt中的Few-shot示例
|
||
> **覆盖场景**: 从基础清洗到高级插补,10个核心场景
|
||
|
||
---
|
||
|
||
## 📋 示例总览
|
||
|
||
| 编号 | 场景名称 | 级别 | 技术要点 | 医疗价值 |
|
||
|------|---------|------|---------|---------|
|
||
| 1 | 统一缺失值标记 | Level 1 | replace | 数据标准化 ⭐⭐⭐ |
|
||
| 2 | 数值列清洗 | Level 1 | 正则+类型转换 | 检验值处理 ⭐⭐⭐⭐ |
|
||
| 3 | 分类变量编码 | Level 2 | map | 统计建模 ⭐⭐⭐⭐⭐ |
|
||
| 4 | 连续变量分箱 | Level 2 | cut | 分层分析 ⭐⭐⭐⭐ |
|
||
| 5 | BMI计算与分类 | Level 3 | 公式+条件 | 临床指标 ⭐⭐⭐⭐⭐ |
|
||
| 6 | 日期计算 | Level 3 | datetime | 时间间隔 ⭐⭐⭐⭐⭐ |
|
||
| 7 | 条件筛选 | Level 3 | 多条件过滤 | 入组标准 ⭐⭐⭐⭐⭐ |
|
||
| 8 | 简单缺失值填补 | Level 4 | fillna | 缺失处理 ⭐⭐⭐⭐ |
|
||
| 9 | 多重插补(MICE) | Level 4 | IterativeImputer | 高级填补 ⭐⭐⭐⭐⭐ |
|
||
| 10 | 智能去重 | Level 4 | sort+drop_duplicates | 数据质量 ⭐⭐⭐⭐ |
|
||
|
||
---
|
||
|
||
## 🎯 Level 1: 基础数据清洗(2个)
|
||
|
||
### 示例1: 统一缺失值标记
|
||
|
||
**用户指令**:
|
||
```
|
||
把所有代表缺失的符号(-、不详、NA、N/A)统一替换为标准空值
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 统一缺失值标记
|
||
df = df.replace(['-', '不详', 'NA', 'N/A', '\\', '未查'], np.nan)
|
||
```
|
||
|
||
**代码说明**:
|
||
- 医疗数据常见多种缺失值表示方式
|
||
- 统一为标准NaN便于后续统计分析
|
||
- 适用场景: 数据清洗第一步
|
||
|
||
**预期结果**:
|
||
- 所有非标准缺失值标记被统一为NaN
|
||
- 后续可使用isnull()等方法统一处理
|
||
|
||
---
|
||
|
||
### 示例2: 数值列清洗
|
||
|
||
**用户指令**:
|
||
```
|
||
把肌酐列里的非数字符号去掉,<0.1按0.05处理,转为数值类型
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 处理数值列的符号
|
||
df['creatinine'] = df['creatinine'].astype(str).str.replace('>', '').str.replace('<', '')
|
||
df.loc[df['creatinine'] == '0.1', 'creatinine'] = '0.05'
|
||
df['creatinine'] = pd.to_numeric(df['creatinine'], errors='coerce')
|
||
```
|
||
|
||
**代码说明**:
|
||
- 检验科导出数据常含符号(>、<、+等)
|
||
- 需清理后才能进行数值计算和统计分析
|
||
- errors='coerce'将无法转换的值设为NaN
|
||
|
||
**预期结果**:
|
||
- 肌酐列变为纯数值类型
|
||
- 符号被正确处理
|
||
- 异常值转为NaN
|
||
|
||
**医疗场景**:
|
||
- 检验报告:肌酐、白细胞、血红蛋白等
|
||
- 常见符号:>100、<0.1、12.5+
|
||
|
||
---
|
||
|
||
## 🔧 Level 2: 变量编码与计算(2个)
|
||
|
||
### 示例3: 分类变量编码
|
||
|
||
**用户指令**:
|
||
```
|
||
把性别列转为数字,男=1,女=0
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 性别编码
|
||
df['gender_code'] = df['gender'].map({'男': 1, '女': 0})
|
||
```
|
||
|
||
**代码说明**:
|
||
- 将文本分类变量转为数值
|
||
- 便于Logistic回归、神经网络等建模
|
||
- map方法简洁高效
|
||
|
||
**预期结果**:
|
||
- 新增gender_code列
|
||
- 男→1, 女→0
|
||
- 原gender列保持不变
|
||
|
||
**扩展场景**:
|
||
- 婚姻状态: 已婚=1, 未婚=0
|
||
- 吸烟史: 是=1, 否=0
|
||
- 教育程度: 小学=1, 初中=2, 高中=3, 大学=4
|
||
|
||
---
|
||
|
||
### 示例4: 连续变量分箱
|
||
|
||
**用户指令**:
|
||
```
|
||
把年龄按18岁、60岁分为未成年、成年、老年三组
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 年龄分组
|
||
df['age_group'] = pd.cut(df['age'],
|
||
bins=[0, 18, 60, 120],
|
||
labels=['未成年', '成年', '老年'],
|
||
right=False)
|
||
```
|
||
|
||
**代码说明**:
|
||
- 将连续变量离散化为有序分类变量
|
||
- bins定义区间边界,labels定义标签
|
||
- right=False表示左闭右开区间[0,18)
|
||
|
||
**预期结果**:
|
||
- 新增age_group列
|
||
- 0-17岁→未成年
|
||
- 18-59岁→成年
|
||
- 60+岁→老年
|
||
|
||
**医疗应用**:
|
||
- 分层分析(各年龄段发病率)
|
||
- 卡方检验(年龄组vs疾病)
|
||
- 描述性统计(基线特征表)
|
||
|
||
---
|
||
|
||
## 🏥 Level 3: 医学计算与筛选(3个)
|
||
|
||
### 示例5: BMI计算与分类
|
||
|
||
**用户指令**:
|
||
```
|
||
根据身高(cm)和体重(kg)计算BMI,并标记BMI≥28为肥胖
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 计算BMI
|
||
df['BMI'] = df['weight'] / (df['height'] / 100) ** 2
|
||
|
||
# 肥胖标记
|
||
df['obesity'] = df['BMI'].apply(lambda x: '肥胖' if x >= 28 else '正常')
|
||
```
|
||
|
||
**代码说明**:
|
||
- BMI公式: 体重(kg) / 身高(m)²
|
||
- 中国标准: BMI≥28为肥胀
|
||
- 向量化计算,无需循环
|
||
|
||
**预期结果**:
|
||
- 新增BMI列(数值)
|
||
- 新增obesity列(分类)
|
||
|
||
**临床标准**:
|
||
- 偏瘦: BMI < 18.5
|
||
- 正常: 18.5 ≤ BMI < 24
|
||
- 超重: 24 ≤ BMI < 28
|
||
- 肥胖: BMI ≥ 28
|
||
|
||
**扩展场景**:
|
||
- 体表面积(BSA): 化疗剂量计算
|
||
- eGFR: 肾功能评估
|
||
- APACHE评分: 危重症评估
|
||
|
||
---
|
||
|
||
### 示例6: 日期计算
|
||
|
||
**用户指令**:
|
||
```
|
||
根据入院日期和出院日期计算住院天数
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 计算住院天数
|
||
df['admission_date'] = pd.to_datetime(df['admission_date'])
|
||
df['discharge_date'] = pd.to_datetime(df['discharge_date'])
|
||
df['length_of_stay'] = (df['discharge_date'] - df['admission_date']).dt.days
|
||
```
|
||
|
||
**代码说明**:
|
||
- 先将日期列转为datetime类型
|
||
- 日期相减得到Timedelta对象
|
||
- .dt.days提取天数
|
||
|
||
**预期结果**:
|
||
- 新增length_of_stay列
|
||
- 数值类型,单位为天
|
||
|
||
**医疗应用**:
|
||
- 住院天数分析
|
||
- 平均住院日(ALOS)统计
|
||
- 住院费用相关性分析
|
||
|
||
**扩展场景**:
|
||
- 计算年龄: (今天 - 出生日期) / 365.25
|
||
- 随访时间: (随访日期 - 基线日期)
|
||
- 生存时间: (死亡/末次随访 - 确诊日期)
|
||
|
||
---
|
||
|
||
### 示例7: 条件筛选(入组标准)
|
||
|
||
**用户指令**:
|
||
```
|
||
筛选出年龄≥18岁、诊断为糖尿病、且血糖≥7.0的患者
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 多条件筛选
|
||
df_selected = df[
|
||
(df['age'] >= 18) &
|
||
(df['diagnosis'] == '糖尿病') &
|
||
(df['glucose'] >= 7.0)
|
||
]
|
||
```
|
||
|
||
**代码说明**:
|
||
- 布尔索引,多条件用&连接
|
||
- 每个条件需加括号
|
||
- 返回满足所有条件的行
|
||
|
||
**预期结果**:
|
||
- 新DataFrame,包含符合条件的病例
|
||
- 原df不变
|
||
|
||
**临床研究应用**:
|
||
- 纳入标准筛选
|
||
- 排除标准剔除
|
||
- 亚组分析(如老年糖尿病患者)
|
||
|
||
**扩展场景**:
|
||
```python
|
||
# 纳入标准
|
||
included = df[
|
||
(df['age'] >= 18) &
|
||
(df['age'] <= 75) &
|
||
(df['diagnosis'].isin(['肺腺癌', '肺鳞癌'])) &
|
||
(df['stage'].isin(['III', 'IV']))
|
||
]
|
||
|
||
# 排除标准
|
||
excluded = df[
|
||
(df['pregnancy'] == 1) | # 妊娠
|
||
(df['severe_liver'] == 1) | # 严重肝病
|
||
(df['other_cancer'] == 1) # 其他肿瘤
|
||
]
|
||
```
|
||
|
||
---
|
||
|
||
## 🔬 Level 4: 高级数据治理(3个)
|
||
|
||
### 示例8: 简单缺失值填补
|
||
|
||
**用户指令**:
|
||
```
|
||
用中位数填补BMI列的缺失值
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 用中位数填补缺失值
|
||
bmi_median = df['BMI'].median()
|
||
df['BMI'] = df['BMI'].fillna(bmi_median)
|
||
```
|
||
|
||
**代码说明**:
|
||
- median()计算中位数(排除NaN)
|
||
- fillna()填补缺失值
|
||
- 中位数受离群值影响小
|
||
|
||
**预期结果**:
|
||
- BMI列无缺失值
|
||
- 缺失位置被中位数替代
|
||
|
||
**填补方法选择**:
|
||
| 方法 | 适用场景 | 优点 | 缺点 |
|
||
|------|---------|------|------|
|
||
| 均值 | 正态分布 | 简单 | 受离群值影响 |
|
||
| 中位数 | 偏态分布 | 稳健 | 信息损失 |
|
||
| 众数 | 分类变量 | 保留分布 | 可能不合理 |
|
||
| 前向填充 | 时间序列 | 保留趋势 | 仅适用时序 |
|
||
|
||
**注意事项**:
|
||
- ⚠️ 仅适用于缺失率<5%
|
||
- ⚠️ 假设缺失为MCAR(完全随机缺失)
|
||
- ⚠️ 可能低估标准差
|
||
|
||
---
|
||
|
||
### 示例9: 多重插补(MICE)⭐ 核心场景
|
||
|
||
**用户指令**:
|
||
```
|
||
使用多重插补法对BMI、年龄、肌酐列的缺失值进行填补
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
from sklearn.experimental import enable_iterative_imputer
|
||
from sklearn.impute import IterativeImputer
|
||
|
||
# 选择需要插补的数值列
|
||
cols = ['BMI', 'age', 'creatinine']
|
||
|
||
# 多重插补
|
||
imputer = IterativeImputer(max_iter=10, random_state=0)
|
||
df[cols] = imputer.fit_transform(df[cols])
|
||
```
|
||
|
||
**代码说明**:
|
||
- MICE (Multivariate Imputation by Chained Equations)
|
||
- 利用变量间相关性预测缺失值
|
||
- max_iter=10: 最多迭代10次
|
||
- random_state=0: 可复现结果
|
||
|
||
**算法原理**:
|
||
1. 初始填补(如均值)
|
||
2. 循环迭代:
|
||
- 对每个有缺失的变量,用其他变量预测
|
||
- 更新填补值
|
||
3. 收敛后停止
|
||
|
||
**适用场景**:
|
||
- ✅ 缺失率5%-30%
|
||
- ✅ 缺失机制为MAR(随机缺失)
|
||
- ✅ 变量间存在相关性
|
||
- ✅ 需要保持数据分布特征
|
||
|
||
**优势**:
|
||
- 利用变量间关系
|
||
- 保持数据分布
|
||
- 减少偏差
|
||
- 统计学上更合理
|
||
|
||
**vs 简单填补**:
|
||
| 指标 | 简单填补 | 多重插补 |
|
||
|------|---------|---------|
|
||
| 复杂度 | 低 | 中等 |
|
||
| 计算时间 | 快 | 较慢 |
|
||
| 偏差 | 可能较大 | 较小 |
|
||
| 标准误 | 低估 | 准确 |
|
||
| 分布保持 | 差 | 好 |
|
||
|
||
**注意事项**:
|
||
- 仅适用于数值变量
|
||
- 分类变量需先编码
|
||
- 如有时间变量需先转换
|
||
|
||
---
|
||
|
||
### 示例10: 智能去重
|
||
|
||
**用户指令**:
|
||
```
|
||
按患者ID去重,保留检查日期最新的记录
|
||
```
|
||
|
||
**AI生成代码**:
|
||
```python
|
||
# 智能去重:先按日期排序,再按ID去重保留最后一条
|
||
df['check_date'] = pd.to_datetime(df['check_date'])
|
||
df = df.sort_values('check_date').drop_duplicates(subset=['patient_id'], keep='last')
|
||
```
|
||
|
||
**代码说明**:
|
||
- sort_values()先按日期升序排列
|
||
- drop_duplicates()按patient_id去重
|
||
- keep='last'保留最后一条(即最新日期)
|
||
|
||
**预期结果**:
|
||
- 每个患者只保留一条记录
|
||
- 保留的是检查日期最新的那条
|
||
|
||
**扩展场景**:
|
||
|
||
**场景1: 保留数据最完整的记录**
|
||
```python
|
||
# 计算每行的完整度
|
||
df['completeness'] = df.notna().sum(axis=1)
|
||
df = df.sort_values('completeness', ascending=False).drop_duplicates(subset=['patient_id'], keep='first')
|
||
```
|
||
|
||
**场景2: 多字段组合去重**
|
||
```python
|
||
# 按患者ID+就诊日期去重
|
||
df = df.drop_duplicates(subset=['patient_id', 'visit_date'], keep='first')
|
||
```
|
||
|
||
**场景3: 复杂逻辑去重**
|
||
```python
|
||
# 优先级:日期最新 > 完整度最高
|
||
df = df.sort_values(['check_date', 'completeness'], ascending=[False, False]).drop_duplicates(subset=['patient_id'], keep='first')
|
||
```
|
||
|
||
**医疗场景**:
|
||
- 删除重复录入的病例
|
||
- 多次就诊取首次/末次
|
||
- 检验结果去重(取最新)
|
||
|
||
---
|
||
|
||
## 📚 使用说明
|
||
|
||
### System Prompt集成方式
|
||
|
||
```python
|
||
system_prompt = f"""
|
||
你是医疗科研数据清洗专家,负责生成Pandas代码来清洗整理数据。
|
||
|
||
## 当前数据集信息
|
||
- 文件名: {session.fileName}
|
||
- 行数: {session.totalRows}
|
||
- 列数: {session.totalCols}
|
||
- 列名: {', '.join(session.columns)}
|
||
|
||
## 安全规则(强制)
|
||
1. 只能操作df变量
|
||
2. 禁止导入os、sys等危险模块
|
||
3. 禁止使用eval、exec等危险函数
|
||
4. 必须进行异常处理
|
||
5. 返回格式: {{"code": "...", "explanation": "..."}}
|
||
|
||
## Few-shot示例
|
||
|
||
### 示例1: 统一缺失值标记
|
||
用户: 把所有代表缺失的符号统一替换为标准空值
|
||
代码:
|
||
```python
|
||
df = df.replace(['-', '不详', 'NA', 'N/A'], np.nan)
|
||
```
|
||
|
||
### 示例2: 数值列清洗
|
||
用户: 把肌酐列里的非数字符号去掉,转为数值类型
|
||
代码:
|
||
```python
|
||
df['creatinine'] = df['creatinine'].astype(str).str.replace('>', '').str.replace('<', '')
|
||
df['creatinine'] = pd.to_numeric(df['creatinine'], errors='coerce')
|
||
```
|
||
|
||
[... 其他8个示例 ...]
|
||
|
||
## 用户当前请求
|
||
{user_message}
|
||
|
||
请生成代码并解释。
|
||
"""
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 质量标准
|
||
|
||
每个示例必须满足:
|
||
- ✅ 代码可直接运行
|
||
- ✅ 有详细注释
|
||
- ✅ 有明确的输入输出
|
||
- ✅ 符合Python最佳实践
|
||
- ✅ 考虑异常情况
|
||
- ✅ 有医疗场景说明
|
||
|
||
---
|
||
|
||
## 📊 测试用例设计
|
||
|
||
基于这10个示例,Day 3测试应包含:
|
||
|
||
**基础测试(4个)**:
|
||
1. 示例1测试(缺失值统一)
|
||
2. 示例2测试(数值清洗)
|
||
3. 示例3测试(性别编码)
|
||
4. 示例4测试(年龄分组)
|
||
|
||
**中级测试(3个)**:
|
||
5. 示例5测试(BMI计算)
|
||
6. 示例6测试(住院天数)
|
||
7. 示例7测试(条件筛选)
|
||
|
||
**高级测试(3个)**:
|
||
8. 示例8测试(中位数填补)
|
||
9. 示例9测试(多重插补)⭐
|
||
10. 示例10测试(智能去重)
|
||
|
||
**扩展测试(5个)**:
|
||
11. 混合场景测试(先清洗再计算)
|
||
12. 错误场景测试(列不存在)
|
||
13. 边界场景测试(全部缺失)
|
||
14. 自我修正测试(代码报错后重试)
|
||
15. 端到端测试(上传→AI处理→结果验证)
|
||
|
||
---
|
||
|
||
## 🔄 维护记录
|
||
|
||
| 日期 | 版本 | 修改内容 | 修改人 |
|
||
|------|------|---------|--------|
|
||
| 2025-12-06 | V1.0 | 初始创建,10个核心示例 | AI Assistant |
|
||
|
||
---
|
||
|
||
**文档状态**: ✅ 已确认
|
||
**下一步**: 开始Day 3开发(AICodeService实现)
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|