用 AI 工作流写研发日志,三类 Excel 上传,日报周报月报批量生成

企业研发团队每个月最头疼的事情之一,就是填研发日志。每位研发人员要写每天的日报、每周的周报、每月的月报,还不能用”优化””提升””智能化”这类词——这些词会让研发费用加计扣除的税务合规审查直接出问题。如果 AI 能接管这件事,会是什么体验?本文分享我们基于 AI 工作流实现研发日志智能体的完整思路。


一套完整的研发日志,包含三种文档:
- 研发日报:每位员工,每个有工时的工作日,写一份
- 研发周报:每位员工,每个有工时的自然周,写一份
- 研发月报:每位员工,每月汇总一份
对一个 10 人团队来说,一个月下来光日报就有 10人 × 约20个工作日 = 200份,加上周报 40 份、月报 10 份——手工填写几乎不可能完成。
更麻烦的是内容要求极严:
- 内容必须在项目的研发框架内,与当前研发阶段的计划时间线对应
- 描述必须与员工岗位(人员类型、项目角色)匹配
- 禁用词列表长达 50+ 个:改造、优化、提升、升级、应用、建设、实施、集成、智能、高效……这些词在研发费用加计扣除的税务审查中被视为”工程应用”而非”技术研究开发”,一旦出现就可能导致该部分费用被剔除、无法享受加计扣除优惠
每个人每天花 15-30 分钟填日报,一个团队一年下来光在研发日志上耗掉的工时,可以支撑一个小项目了。
AI 能做什么?
我们用平台的 AI 工作流引擎,把这件事做成了一个工作流——HR 或项目负责人只需上传三类标准 Excel 文件,系统自动解析、批量生成所有员工的日报、周报、月报,打包成 zip 下载包,输出到任务中心。


核心思路:日报 → 周报 → 月报,有依赖就不能并行
研发日志的三种文档之间有严格的数据依赖:
- 周报必须基于本周的日报内容汇总生成(不能凭空生成周报,否则与日报内容对不上)
- 月报必须基于本月的周报内容汇总生成
因此,我们设计了三阶段顺序生成架构:
[员工A]
│
├─ 第1阶段:生成日报(每个有工时日期 × 1份)
│ 工时=0 跳过(请假不生成),工时>0 生成日报
│
├─ 第2阶段:生成周报(基于本周日报汇总 → 生成周报)
│ 每个有工时自然周 × 1份
│
└─ 第3阶段:生成月报(基于本月周报汇总 → 生成月报)
月度汇总,每人1份
三个阶段在同一个 LLM 会话(conversationId)内串行完成——日报产生的上下文直接传给周报的 LLM,周报的上下文再传给月报,保证内容一致性,不会出现”日报说在做算法优化,月报说在做工程部署”的矛盾。
工作流节点总览(11个节点,固定不随员工数变化)
[START]
│
▼
[DataValidationNode] ← 校验三类 Excel 格式 + 生成选项
│
├─ 校验失败 ──────────────────────────────────────────► [END]
│
└─ 校验通过
│
▼
[ExcelParserNode] ← 解析三类 Excel + 7项深度校验
│
├─ 解析失败 ──────────────────────────────────────────► [END]
│
└─ 解析成功
│
▼
[RdLogBatchGeneratorNode] ← 核心节点:批量生成所有员工日志
│
▼
[ZipPackageNode] ← 打包所有 docx 为 zip
│
▼
[ExportNode] ← 上传 OSS,生成下载链接
│
▼
[END]
节点总数:11个(含 condition 分支节点)。不管是 5 个员工还是 50 个员工,工作流拓扑结构完全不变——员工循环逻辑封装在
RdLogBatchGeneratorNode节点内部。


用户需要准备三类标准化 Excel 文件:
| 文件 | 核心字段 | 约束 |
|---|---|---|
| 项目信息 | 项目编号、项目名称、主要研发内容、技术难点、创新点 | .xlsx/.xls,≤50MB |
| 项目计划 | 研发阶段、计划开始/结束时间、计划研发内容(每个项目一个 Sheet) | .xlsx/.xls,≤50MB |
| 人员工时 | 工号、姓名、部门、人员类型、项目角色、1-31天每日工时 | .xlsx/.xls,最多1000条,不跨月 |
用户界面操作流程:
1. 分别下载三类 Excel 模板,按要求填写数据
2. 上传项目信息 Excel
3. 上传项目计划 Excel
4. 上传人员工时 Excel
5. 勾选生成类型(默认全选:日报 + 周报 + 月报)
6. 点击「生成研发日志」
7. 等待进度通知,去任务中心下载 zip


这是工作流的第一道实质性节点,也是最容易被忽视的关键节点。
研发日志 Excel 的数据校验比一般文件上传复杂得多,包含 7 项深度校验规则:
|


|—|——–|——|
| 1 | 三表项目编号一致性 | 项目信息/项目计划/人员工时中的项目编号必须匹配 |
| 2 | 必填字段非空 | 工号、姓名、项目编号、年、月不能为空 |
| 3 | 不跨月 | 工时数据只能在同一个自然月内 |
| 4 | 不超1000条 | 工时记录数上限 |
| 5 | 无重复记录 | 工号 + 项目编号 + 年月 唯一 |
| 6 | 工时全零校验 | 至少要有一名员工有有效工时 |
| 7 | 项目计划时间完整 | 每个研发阶段的开始/结束时间不能为空 |
校验失败时,系统直接在任务中心展示具体错误,指向到行级别:
Excel解析失败:工时数据存在重复记录
(工号[10001579] 姓名[张三] 项目编号[RD2025001] 2025年03月)
设计意图:把校验逻辑从 Service 代码中抽取为独立节点,校验失败直接路由到 END,不再通过抛异常来中断流程。前端只需监听 state 中的
parseError字段即可,错误展示不需要改代码。


这是整个工作流最核心的节点,封装了”多员工 × 三阶段”的完整生成逻辑。
5.1 三阶段 LLM 生成流程
对每位员工(可配置并发度,默认串行):
│
├─ [日报生成]
│ 对每个有工时日期(dailyHours[d] > 0):
│ ├─ 构建 Prompt(项目信息 + 当日日期 + 当日工时 + 项目计划时间线 + 员工岗位)
│ ├─ 调用 LLM → 输出 JSON(progressWork / problemSolution / nextDailyWork)
│ └─ 渲染为 docx(daily_report_template.docx)
│
├─ [周报生成]
│ 对每个有工时自然周:
│ ├─ 汇总该周所有日报内容 → 构建周报 Prompt
│ ├─ 调用 LLM(同一 conversationId,延续上下文)→ 输出 JSON
│ └─ 渲染为 docx(weekly_report_template.docx)
│
└─ [月报生成]
├─ 汇总本月所有周报内容 → 构建月报 Prompt
├─ 调用 LLM(同一 conversationId)→ 输出 JSON
└─ 渲染为 docx(monthly_report_template.docx)
5.2 同一员工复用 LLM 会话
每位员工的日报、周报、月报在同一个 conversationId(LLM 会话)内生成:
员工A的 conversationId = "rdlog_A_2025_03"
↓
日报1(3月1日)→ 日报2(3月3日)→ … → 日报N
↓ (周报 Prompt 包含本周所有日报全文)
周报1(第9周)→ 周报2(第10周)→ …
↓ (月报 Prompt 包含本月所有周报全文)
月报(2025年3月)
这样做有两个好处:
- 后续文档能看到前序文档的上下文,周报不会与日报内容矛盾
- LLM 对这名员工的岗位、项目情况有连续记忆,输出更连贯
5.3 文件命名规则
| 文档类型 | 命名格式 | 示例 |
|---|---|---|
| 研发日报 | {姓名}_{YYYY-MM-DD}_研发日报.docx |
张三_2025-03-01_研发日报.docx |
| 研发周报 | {姓名}_{YYYY年第N周}_研发周报.docx |
张三_2025年第9周_研发周报.docx |
| 研发月报 | {姓名}_{YYYY年MM月}_研发月报.docx |
张三_2025年03月_研发月报.docx |
5.4 并发配置
节点提供 maxConcurrency 参数:
| 配置值 | 效果 | 适用场景 |
|---|---|---|
1(默认) |
员工串行处理 | LLM 资源有限,稳定优先 |
3 |
同时处理3名员工 | 推荐生产配置,耗时约减少60% |
5 |
同时处理5名员工 | 员工数多时,缩短等待时间 |
10名员工全选(日报+周报+月报):
maxConcurrency=1:约 30-50 分钟maxConcurrency=3:约 12-18 分钟maxConcurrency=5:约 8-12 分钟


禁用词是研发日志最容易踩的坑,传统方案是生成后再做关键词过滤,但这样会破坏文档结构,被替换的句子往往语义不通。
我们的方案是在 systemPrompt 里直接声明禁用词列表,让 LLM 在生成时就规避:
{
"systemPrompt": "你是一位专业的研发工程师,正在为「张三」撰写研发日报。
...
【禁止使用的词汇(包含即视为不合格)】
改造、改进、改善、增强、改良、技改、变更、优化、提高、提升、升级、
应用、利用、建设、实施、操作、制备、搭建、安装、加工、集成、工程、
产业化、示范、规模化、咨询、规范化、工业化、管理、教学、运营、推广、
节能、减排、环保、自动、智能、高效……(共50+个)
..."
}
如果 LLM 输出中仍检测到禁用词,节点会自动触发一次重试,在 Prompt 末尾追加强调:
本次重试,严禁出现以下词汇,每出现一个扣10分:改造/优化/提升/…
重试仍有禁用词则记录告警日志,但不中断其他员工的生成——一名员工的异常不会影响整批任务。


研发日志智能体有 6 个提示词编码,分三种场景:
| 提示词编码 | 用途 |
|---|---|
rdlog.daily |
研发日报生成(原始数据驱动) |
rdlog.weekly_from_daily |
周报生成(基于日报汇总,主路径) |
rdlog.monthly_from_weekly |
月报生成(基于周报汇总,主路径) |
rdlog.weekly_from_files |
周报降级(日报生成失败时,直接基于文件生成) |
rdlog.monthly_from_daily |
月报降级(周报生成失败时,基于日报汇总生成) |
rdlog.monthly_from_files |
月报降级(日报/周报均失败时的兜底方案) |
提示词存储在数据库,支持热更新——调整禁用词、修改字数要求、优化表达格式,都不需要重新发布代码。
注意:这 6 个 promptCode 与原 AI 模块(
RdProjectInfoServiceImpl)中的常量完全对齐,不需要修改已有数据库记录。


| 对比项 | 原 AI 模块实现 | 工作流实现(本方案) |
|---|---|---|
| 文件校验 | 7项校验散落在 Controller 私有方法,报错只能抛异常 | ExcelParserNode 封装,校验失败写入 state,路由到 END 并展示具体错误 |
| 进度追踪 | @AsyncMonitor + Redis TaskMeta,自行实现轮询 |
工作流引擎原生任务中心,流式进度,无需额外开发 |
| 并发控制 | 全局 Semaphore(20) 信号量,员工串行 |
maxConcurrency 参数化,可按员工粒度并发 |
| 提示词管理 | 代码内 PROMPT_CODE_* 常量 + 数据库兜底 |
全部走 promptCode 热更新,无代码常量 |
| 扩展性 | 修改 Service 代码重新部署 | 工作流 JSON 配置驱动,提示词热更新,节点独立可复用 |
| 错误恢复 | 一名员工报错终止整批 | 单员工失败告警,不阻断其他员工,继续生成 |
迁移策略:工作流版本与原接口并行运行,不下线 /ai/aiRdLogGen/processAndGenerate;存量 RDERP 系统对接保持不变;新用户走工作流入口。


坑1:LLM 输出 JSON 偶发格式错误
LLM 有时会输出 Markdown 包裹的 JSON(json ... ),或者在长文本中截断。
解法:在解析前做清洗(去掉 ```json ``` 包裹),解析失败触发一次重试,再失败则对该员工该日期输出占位内容(不阻断整批)。
坑2:Word 模板占位符与 JSON 字段名不匹配
poi-tl 渲染时,如果 LLM 输出的 JSON 字段名(比如 progressWork)和 Word 模板里的占位符(比如 {{progress_work}})对不上,会抛 NullPointerException。
解法:在提示词的 JSON Schema 里明确规定字段名,与 Word 模板占位符严格一一对应;渲染前做字段补全,缺失字段填充空字符串。
坑3:三表项目编号不一致
用户填写 Excel 时,项目信息表写的是 RD-2025-001,人员工时表写的是 RD2025001(少了横线)。两个表对不上,找不到对应的项目信息,LLM 就会”凭空”生成内容。
解法:ExcelParserNode 在解析时做三表项目编号一致性校验,不一致直接报错并指出是哪个表、哪个编号对不上,让用户修正数据后重新上传。
坑4:大批量任务超时
10人团队全选三种日志,总 LLM 调用次数约 (20日报+5周报+1月报) × 10人 = 260次,串行执行约 30-50 分钟,可能触发网关超时。
解法:工作流引擎任务中心异步模式——用户提交后立即返回,后台继续执行,完成后在任务中心展示下载链接。用户不需要等在页面前,去做别的事情就好。


研发日志的 AI 化,和专利撰写、技术方案、月报生成本质上是同一类问题:结构化程度高、规则约束强、内容有数据依赖——这类问题最适合用工作流引擎来做,而不是一次性 LLM 调用。
工作流化的核心价值不仅是”自动化”,还包括:
- 可观测:每一步的输入输出都记录在 state 里,出问题可以逐节点排查
- 可配置:提示词热更新,禁用词列表随政策调整,不发版
- 可复用:
ZipPackageNode、ExportNode、DataValidationNode在多个智能体间复用,不重复造轮子 - 可扩展:今天是10名员工,明天是100名员工,只需调整
maxConcurrency参数
下一步,我们计划在工作流中加入禁用词实时高亮预览功能——在任务中心下载前,先展示检测报告,让用户确认没有问题再打包。
如果你们团队也在做类似的文档自动化需求,欢迎留言交流。
夜雨聆风