每周五下午,把散落在日历、任务系统和 Git 里的工作事项拼成一份像样的周报,常常要吃掉半小时,还得担心漏项、写错结论。手动汇总真正的痛点不是打字慢,而是口径不统一、每条进展都对不上原始记录。
把原始记录一股脑丢给大模型同样不够用:模型会自行补脑细节、写出并未发生的进展,生成后没人复核就直接发出,一次错漏就得返工解释半天。仅靠提示词里一句「不要编造」,约束力远远不够。
本文分享一套可落地的周报确认链路:Spring AI 接 Qwen3.8 做结构化生成 + 事项溯源标记 + 人工确认卡闭环,可直接落地。
一、周报拼装痛点:手写汇总为何总在周五卡住
复盘几次真实的周五加班场景,问题基本集中在三处:
- 事项散落多处:会议在日历、需求在任务系统、代码在 Git,人工逐个翻记录,极易漏掉低可见度但耗时的工作。
- 描述口径不一:同一事项上周写「联调」、本周写「推进」,管理者读不出进展幅度,周报的横向可比性归零。
- 发布缺少闸门:写完直接发群,一旦出现数据错误或敏感表述,责任只能由作者自己扛。
核心结论: 周报难写的本质是「汇总无结构、生成无校验、发布无闸门」,三个缺口要分别补。]
二、整体链路:从事项采集到确认卡的五步闭环
整条链路拆成五个环节,每个环节都有明确产物与失败出口:
事项采集 → 结构化归并 → 模型生成 → 卡片渲染 → 人工确认
- 采集与归并 :从日历、任务系统、Git 拉取时间窗口内的原始记录,按标题去重后合并为统一的
WorkItem列表。 - 模型生成 :把 JSON 事项列表交给 Qwen3.8,产出固定四段结构的周报草稿,并为每条进展标注来源序号。
- 确认与发布 :草稿渲染成人工确认卡,只有「通过」才进入发布通道,「驳回」把修改意见拼回提示词重新生成。
核心结论: 生成只是链路中的一环,前后都要有可回退的结构化产物。

三、环境准备:Spring AI 接入 Qwen3.8 配置要点
先让工程跑通一次模型调用,关键配置集中在依赖与 application.yml:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
yaml
spring:
ai:
openai:
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
api-key: ${DASHSCOPE_API_KEY}
chat:
options:
model: qwen3.8-plus
temperature: 0.3
max-tokens: 2048
| 配置项 | 建议值 | 作用 |
|---|---|---|
base-url |
DashScope 兼容模式地址 | 用 OpenAI 协议直连 Qwen3.8 |
model |
qwen3.8-plus |
中文长文本与结构遵循度更稳 |
temperature |
0.2~0.4 | 周报以事实为主,偏低更可靠 |
max-tokens |
2048 | 覆盖 400 字正文加结构标记 |
走兼容协议即可零改造复用 Spring AI 的 ChatClient。
四、事项采集:零散记录归并成结构化输入
采集层只做一件事:把三个数据源压成一份去重后的事项清单:
java
public record WorkItem(String source, String title, LocalDate date, int hours, String result) {}
@Service
public class ItemCollector {
private final CalendarClient calendar;
private final TaskClient task;
private final GitClient git;
public List<WorkItem> collect(String user, LocalDate from, LocalDate to) {
List<WorkItem> all = new ArrayList<>();
all.addAll(calendar.listEvents(user, from, to));
all.addAll(task.doneStories(user, from, to));
all.addAll(git.mergedPRs(user, from, to));
return all.stream()
.collect(Collectors.toMap(WorkItem::title, i -> i, (a, b) -> a))
.values().stream()
.sorted(Comparator.comparing(WorkItem::date))
.toList();
}
}
- 统一时间窗口 :三个数据源必须用同一个
from/to,否则周报会出现跨周事项混入。 - 保留来源字段 :
source会在卡片上展示,用户点一下就能看到原始记录,这是防编造的关键抓手。
先有可信的结构化输入,模型才没有编造空间。

五、提示词设计:用分段约束锁死生成质量
提示词分三块写:角色、输入、硬性输出要求,缺一段就容易跑偏:
text
# 角色
你是资深研发工程师的周报助手,只做归纳,不做发挥。
# 输入事项(按序号引用)
${items}
# 输出要求
1. 仅依据输入事项撰写,禁止补充未出现的工作
2. 结构固定四段:本周概览 / 关键进展 / 风险与阻塞 / 下周计划
3. 每条进展末尾标注 [事项序号],下周计划须能在输入中找到依据
4. 总长 400 字以内,语气客观,不使用「圆满」等评价词
- 结构强约束 :固定四段并要求序号回指,生成后可程序化校验段落与
[n]是否齐全。 - 缺段自动重写:校验失败就把缺失项作为错误信息附回对话重试,最多两轮。
强约束提示词 → 结构校验 → 缺段自动重写
六、卡片构建:把周报渲染成可编辑确认卡
确认卡不是普通页面,它是发布前的最后一道人工闸门,字段要服务交互:
| 字段 | 类型 | 交互行为 |
|---|---|---|
sections |
数组 | 四段分块展示,逐段折叠 |
sources |
数组 | 悬停进展条目显示原始事项 |
edits |
文本 | 行内编辑,确认时随请求提交 |
score |
数字 | 低于阈值时发布按钮置灰 |
status |
枚举 | draft / confirmed / rejected |
- 得分门槛:让模型自评事实一致性并返回 0~100 分,低于 80 分的草稿强制人工逐条核对。
- 状态机流转 :只有
draft → confirmed允许发布,rejected必须重新生成后才能再次进入确认。
核心结论: 卡片把「AI 输出」降级成「待办草稿」,责任主体始终是人。

七、人工确认:通过、驳回与局部改写的闭环
确认接口只负责两件事:放行或把意见送回生成环节,代码如下:
java
@RestController
@RequestMapping("/weekly")
public class WeeklyCardController {
private final WeeklyService service;
@PostMapping("/{id}/confirm")
public Result confirm(@PathVariable String id, @RequestBody ConfirmReq req) {
if (req.approved()) {
return Result.ok(service.publish(id, req.edits()));
}
return Result.ok(service.rewrite(id, req.edits(), req.note(), 1));
}
}
- 通过 :合并人工
edits,状态置为confirmed,推送到群机器人或邮件模板。 - 驳回 :把
note与被标记的段落拼回提示词重新生成,超过两轮仍未通过则转人工手写并记录原因。
核心结论: 驳回不是终点,而是带回上下文的重试信号。
八、异常降级:超时、低分与编造的兜底策略
线上一定会遇到模型抽风,先列清楚现象、原因与处置:
| 现象 | 可能原因 | 处置动作 |
|---|---|---|
| 401 / InvalidApiKey | 密钥未注入或过期 | 检查环境变量与轮换策略 |
| 正文被截断 | max-tokens 偏小 |
调大到 2048 并限制事项条数 |
| 进展与事项不符 | 输入 JSON 超长被压缩 | 按主题分组分批生成再合并 |
卡片长期 pending |
确认回调超时 | 前端轮询兜底 + 30 分钟提醒 |
- 超时降级:模型 10 秒未返回就用上周模板加事项列表生成简版草稿,宁可朴素也不留空。
- 低分拦截:得分低于阈值直接锁定发布按钮,把风险挡在卡片里。
兜底策略的价值在于:模型可以失败,流程不能失败。

九、链路验证:用接口调用与日志核对全链路
联调阶段用两条 curl 就能覆盖主流程,先把生成接口跑通:
bash
curl -s -X POST localhost:8080/weekly/generate \
-H 'Content-Type: application/json' \
-d '{"user":"zhouzy","from":"2025-06-02","to":"2025-06-06"}' \
| jq '.data | {id, score, status}'
# 用上一步返回的 id 替换占位符,模拟通过确认
curl -s -X POST localhost:8080/weekly/<id>/confirm \
-H 'Content-Type: application/json' \
-d '{"approved":true,"edits":"补充压测结论","note":"ok"}'
- 日志三要素 :每次调用记录
traceId、事项条数、模型耗时,便于定位是采集慢还是生成慢。 - 抽样回放:随机抽取 10 份历史草稿,人工比对来源事项,统计编造率是否低于 5%。
核心结论: 链路可验证,才能放心把发布权交给确认卡。**
十、上线清单:参数调优与三个高频坑位
正式接入团队前,按这张清单逐项过一遍:
- 温度与长度 :
temperature稳定在 0.3 附近,改一处就要回归抽样,别凭感觉调。 - 事项上限:单次输入控制在 40 条以内,超出按主题分组分批生成,避免上下文挤压。
- 敏感表述:保留「不使用评价词」约束,并在卡片上对人名、金额做二次确认提示。
- 权限边界:采集接口按用户鉴权,只允许拉取本人事项,防止串号看到他人日程。
上线前把参数、上限、权限三件事钉死,周报助手才经得起整组人每周使用。

结语
这套链路的价值不在于让模型写出更漂亮的周报,而在于把「汇总、生成、校验、确认」四件事拆开:采集层给出可信输入,提示词与结构校验压住编造,确认卡把最终决定权交回给人,异常降级保证流程不因模型失败而中断。整套方案基于 Spring AI 的标准抽象,换模型只需改一行配置。
对团队而言,落地后最直观的变化是周五下午从半小时压缩到几分钟的核对,以及每条进展都能点开看来源------让 AI 负责起草,让人负责拍板,周报才能既快又敢发。