Writing Copilot — 项目深挖防守稿
项目:面向政企客户的智能写作助手(自动化内容生成与写作辅助)
时间:2024年12月 – 2025年05月
角色:实现负责人
技术核心:LangGraph 多智能体 + DPO→GRPO 两阶段对齐 + Human-in-the-loop + 检索与成本优化
面试权重:★★★
来源:CV;未做一手考证
相关知识点:01-fundamentals/02-post-training/dpo.md、grpo.md、01-fundamentals/04-agent-architecture/multi-agent.md、human-in-the-loop.md
1. 三十秒叙事#
「面向政企客户的智能写作助手:从用户输入到最终研报生成的端到端流程。
系统是 LangGraph 上的多智能体写作架构 ——
web_agent负责检索、news_agent负责时效性内容、writing_agent负责成文。我在流程里插了一个 human-in-the-loop 的大纲确认环节:在触发下游检索和写作之前,先跟用户确认并优化大纲。这一步看似简单,但它把「自动化程度」和「可控性」的平衡点前移了 —— 政企场景里,写错方向的成本远高于多问一句的成本。最难的部分是对齐:这个场景需要模型对特定约束合规作答而不是一律拒绝。我做的是 DPO + GRPO 两阶段 —— 先用 DPO 抑制模型原有的过强安全对齐分布、缓解过度拒答,再用 GRPO 配合定制奖励信号引导它在合规前提下作答。」
为什么这么开场:把「HITL 设计」和「对齐策略」两个钩子都抛出去。DPO→GRPO 这个顺序很少见,面试官大概率会咬住这个问 —— 而这正是你准备最充分的地方。
2. 架构与关键决策#
2.1 为什么是多智能体而不是单体#
三个角色的工具集和上下文需求完全不同:
| Agent | 职责 | 需要什么 |
|---|---|---|
web_agent |
网页检索 | 搜索工具、爬取与清洗 |
news_agent |
时效性内容 | 新闻源、时间过滤 |
writing_agent |
成文 | 长上下文、写作指令、格式约束 |
塞进一个 agent 会导致工具描述冗长、选择错误率上升、且上下文被检索结果挤满而挤压写作质量。拆开之后每个 agent 的上下文是隔离的 —— 这是多智能体的核心收益(见 04-agent-architecture/multi-agent.md 里「什么时候多智能体反而有害」的讨论:上下文隔离是收益,错误复合是代价)。
2.2 为什么在「写作前」而不是「写作后」做人工确认#
这是成本结构决定的,讲清楚这一点很加分:
- 写作是最昂贵的一步(长上下文、检索 + 生成)
- 大纲是最便宜的检查点(几十个 token)
- 大纲错了 → 下游全部重做;大纲对了 → 下游基本可控
所以把确认点放在大纲阶段,是用最小成本拦截最大浪费。这是个纯粹的工程权衡,面试官喜欢听。
顺带要能说清代价:HITL 会打断自动化,用户不在时流程会卡住。所以要设计超时策略(超时后走默认大纲还是中止)—— 能主动提这个说明你想过生产环境。
2.3 DPO → GRPO 这个顺序(本项目的核心考点)#
先理解问题:模型有很强的安全对齐,导致对敏感话题一律拒答(over-refusal)。但业务需要的是合规作答而不是拒答 —— 这是两个不同的目标。
为什么不能只用 GRPO 直接训:
模型的拒答行为在输出分布里是一组很强的价值 token 模式。如果直接上 GRPO 想把它掰过来,会面对两个问题:
- 奖励信号要和已有的强先验对抗,学习效率低、不稳定
- 容易把安全能力一起训坏 —— 变成什么都说,这是不可接受的风险
所以先 DPO:DPO 在偏好对上做优化,可以有针对性地压低「拒答」这个模式的概率,同时保留安全边界。DPO 是离线、稳定的 —— 它是把分布往目标方向「挪」,而不是靠奖励信号「撞」。
然后再 GRPO:分布被 DPO 挪到合理位置后,再用 GRPO 配合定制奖励信号做细粒度优化 —— 引导模型在符合安全规范的前提下对敏感话题合规作答。因为起点已经合理,GRPO 的奖励信号此时才有效率。
一句话总结(可以直接说出口):DPO 负责把分布挪到正确的「区域」,GRPO 负责在这个区域里做精细优化。顺序反了,要么训不动,要么把安全能力一起训坏。
这个回答的价值在于它展示了你理解 DPO 和 GRPO 的机制差异(离线偏好优化 vs 在线奖励优化),而不只是「两个都试过」。这远超一般候选人。
2.4 检索与成本优化#
政企写作场景的输入上下文非常大(多来源网页),直接塞进 LLM 成本高、延迟差、且噪声会稀释有效信息。
做的是一条筛选链:
爬取页面 → 分块(chunking) → 相关性打分 → 重排序(re-ranking) → 细粒度内容筛选与压缩 → 注入 LLM关键在于先粗筛再精排再压缩,逐级降低候选量,最后只把高质量片段喂给模型。收益是双向的:推理成本下降(token 数减少)+ 响应延迟下降,而且因为噪声被过滤,质量通常不降反升。
要能画出一条权衡曲线:压缩越狠,成本越低,但漏掉关键信息的风险越高。所以压缩必须可评测 —— 需要一套能验证「压缩后答案质量没退化」的评测。
2.5 实体校对(容易被低估的模块)#
政企内容的特殊要求:人名和职务不能错。
做法不是靠模型「注意一点」,而是一套工程化的后处理:维护 香港特区政府高级官员的结构化知识库 → 命名实体后处理模块 → 语义检索候选 → 规则引擎做实体链接与消歧。
这个模块的面试价值:它证明你理解「有些正确性要求不能靠模型本身保证,必须用外部约束兜住」。这是生产级 AI 系统和 demo 的分界线。主动讲这个很加分。
3. 面试官会怎么往下挖#
第一层:动机#
Q:这个项目最大的技术难点是什么?
别说「都挺难的」。选一个讲透 —— 建议选对齐(DPO→GRPO),因为你的理解深度在这里最突出。
Q:为什么政企客户需要 HITL?不能全自动吗?
答:准确性责任的归属问题。政企内容出错有实际后果,用户需要保留最终控制权。技术上这是「自动化程度 vs 可控性」的权衡,HITL 的放置点(大纲阶段)是按成本结构选的。
第二层:技术细节#
Q:DPO 和 GRPO 的区别是什么?为什么不能只用 GRPO?
⚠️ 必问。 要点:DPO 是离线的偏好优化,直接在
(prompt, chosen, rejected)上优化,不需要奖励模型、不需要在线采样,优化稳定但只能往偏好数据覆盖的方向走。GRPO 是在线 RL,采样一组回答、用组内相对优势更新,能探索偏好数据没覆盖的区域,但需要可设计的奖励信号且训练更不稳定。只用 GRPO 的问题:要跟模型已有的强拒答先验正面对抗,效率低,且容易把安全能力一起训坏。
Q:DPO 训练需要什么样的数据?你怎么构造的?
要点:三元组
(prompt, chosen, rejected)。要能说清「rejected 选什么」是关键设计 —— 不能用随机负例,必须选有信息量的负例(这里就是「合规但拒答」vs「合规且作答」这类对比)。偏好数据的质量决定了 DPO 的方向。
Q:GRPO 的奖励信号怎么设计?怎么防止 reward hacking?
要点:合规性 + 作答质量 + 格式要求的多项加权。防 hack 的核心是每一项都要有对抗检验 —— 例如模型可能学会用「形式上合规但实质空泛」的回答骗过合规奖励,所以必须配质量项约束。
Q:多智能体之间怎么传递状态?出错怎么处理?
要点:LangGraph 的共享 state。错误处理:单个 agent 失败时的重试与降级、以及最终写作前的兜底检查(信息是否足够、来源是否可信)。
Q:上下文压缩怎么保证不丢关键信息?
要点:压缩策略要配评测。分级压缩(先粗排砍掉大量低分块,再对保留块做细粒度抽取),且对「答案所需信息是否仍在上下文里」做专门验证。
第三层:工程与生产#
Q:怎么评测这个系统的质量?
要点:写作质量是主观的,所以需要组合方案 —— 人工评分 + LLM-as-judge(并说明其偏置,见
05-agent-evaluation/llm-as-judge.md)+ 针对可验证维度的自动检查(事实一致性、实体准确性、格式合规)。要点是「不同维度用不同方法」,不要声称有一个万能指标。
Q:成本和延迟怎么控制?
用 2.4 的筛选链回答,并给出方向性数据(token 减少比例、延迟改善),不要编精确数字。
第四层:反思#
Q:这个项目最大的遗憾是什么?
建议方向:① 压缩环节的评测做得不够系统,导致调压缩率时缺依据;② HITL 的超时/异步处理是后补的,早期设计没考虑;③ 对齐的评测偏离线,缺少长期线上回归。
Q:如果让你把这个系统开源,你会怎么改?
考察抽象能力:把「约束对齐 + 合规作答」抽成可复用模块、把实体校对从硬编码知识库改成可配置的外部约束、以及把 HITL 抽象成通用中断/恢复原语。
4. 线上故障复盘#
米哈游面经:「所有技术点必须绑定业务场景 + 线上问题 + 量化结果」。这一节按
README.md《故障题的四段结构》准备。⚠️ 下面三类是这套架构必然会长出来的故障(由设计推导),不是替你编的经历。你要做的是把每一类对应到自己真实遇到的那一次;确实没遇到的,就如实说没遇到,再讲你为它加了什么预防。
| # | 故障类型 | 现象(先给可观测的表象) | 该往哪查 | 修法与复盘要点 |
|---|---|---|---|---|
| 1 | HITL 卡死流程 | 无人值守时段任务全部挂起、队列堆积、用户以为系统坏了 —— 但日志里「没有任何错误」 | 大纲确认环节的等待时长分布、超时比例、挂起任务的堆积曲线 | 超时策略(超时走默认大纲继续,或中止并通知)+ 把中断点做成可恢复状态。复盘:HITL 的代价就是打断自动化,所以超时与恢复必须在设计时就有 —— 我们是后补的 |
| 2 | 压缩把答案要用的信息滤掉了 | 答案变「泛」、引用不到来源,且是上调压缩率之后才出现的;单看每个模块都正常 | 对同一批问题跑压缩前 / 压缩后对比,验证「答案所需信息是否还在注入的上下文里」 | 分级压缩(粗排砍量 → 保留块细粒度抽取),并给压缩单独建评测。复盘:压缩必须可评测,否则调压缩率全靠感觉 |
| 3 | 多智能体错误复合 | 最终成文里出现来源不可信或缺失的内容,但每个 agent 单独看都是成功的 | 按环节看中间产物:检索命中、时效过滤、大纲 → 成文的一致性 | 成文前的兜底检查(信息是否足够、来源是否可信)+ 单 agent 超时降级 + 重试。复盘:多智能体的收益是上下文隔离,代价就是错误复合 —— 收益和代价是同一件事的两面 |
面试官还会接着问#
Q:多个 agent 各说各的,或者意见冲突,你怎么处理?
要能说清谁有最终决定权。两条路:① 主管 agent 裁决(简单,但主管的判断质量就是上限);② 冲突时降级到人工确认(政企场景更常见,因为写错方向的代价高)。关键是不能含糊 —— 冲突没有处理策略的多智能体系统在生产里会静默地产生垃圾输出。
Q:实体校对模块漏了一个没在知识库里的人名,会怎样?
要能说出降级行为:是保留原文、还是标记为待确认、还是拦截?政企场景的正确做法通常是标记 + 提示而不是静默放行 —— 因为「不确定」本身是需要传达给用户的信息。这也暴露了这个模块的真实局限:闭集知识库只能覆盖它收录过的人,所以必须有「不在库里」的处理路径。
5. 数字口径速查#
⚠️ 这个项目在 CV 上没有写具体数字 —— 这是好事,不要临时编。
要讲效果时,用结构性描述:
| 说法 | 可用性 |
|---|---|
| 「显著降低了输入 token 数,推理成本和延迟都下降」 | ✅ 安全 |
| 「准确率提升 X%」 | ❌ 没有依据,别编 |
| 「我们对敏感话题的过度拒答明显减少、同时保留了安全边界」 | ✅ 安全(这是定性的,且是设计目标) |
| 「HITL 把返工率降下来了」 | ⚠️ 只有当你有实测数据时才说 |
原则:没有口径的数字比没有数字更危险。
6. 红线#
不要 claim:
- ❌ 不要编造任何准确率/延迟/成本数字。
- ❌ 不要把「多智能体」说成你自己一个人从零设计的框架 —— 讲清楚你负责的部分(CV 写的是「实现负责人」)。
- ❌ 不要过多描述约束内容的具体业务细节。
- ❌ 不要说「我们完全解决了过度拒答」—— 这是不可能完全解决的,说「显著缓解」才可信。
要主动说:
- ✅ 主动讲 DPO→GRPO 的顺序理由 —— 这是你最强的差异化回答。
- ✅ 主动讲 HITL 的代价(打断自动化),而不只是好处。
- ✅ 主动讲实体校对模块 —— 它体现生产思维。
- ✅ 主动提一个具体的线上故障(见 §4)—— 这是「真做过」最有效的证据,也是米哈游面经里被单列出来的考察项。
7. 自测#
1. 用三句话说清为什么是 DPO 先、GRPO 后。顺序反过来会怎样?
答案要点
① DPO 是离线偏好优化,稳定地把输出分布从「一律拒答」挪到「合规作答」的区域,同时保住安全边界;② GRPO 是在线 RL,在已经合理的分布区域里用奖励信号做细粒度优化,效率高。顺序反过来:直接 GRPO 要对抗模型的强拒答先验,学习效率低且不稳定,且容易把安全能力一起训坏(变成什么都答)。
2. DPO 的偏好数据里,rejected 应该选什么?为什么不能随机选?
答案要点
必须选有信息量的负例 —— 在这个项目里是「合规但拒答」这类与正例仅在目标维度上有差异的样本。随机负例(例如质量明显很差的回答)会让模型学到的偏好方向与真正想要的对齐目标错位,训练看似收敛但解决不了 over-refusal。
3. HITL 放在大纲阶段而不是成文之后,理由是什么?这个设计有什么代价?
答案要点
理由:按成本结构选检查点 —— 写作是最贵的一步,大纲是最便宜的检查点,在大纲阶段拦截方向性错误能以最小成本避免最大浪费。代价:打断全自动化,用户不在时流程会阻塞,需要设计超时策略(默认大纲或中止)。
4. 上下文压缩到极致会发生什么?你如何证明压缩是可接受的?
答案要点
压缩过狠会丢掉答案所需的关键信息,表现为答案质量下降或引用不到来源。证明方式:建立专门评测 —— 对「答案所需信息是否仍保留在注入的上下文中」做验证,并对比不同压缩率下的端到端质量,找到成本与质量的平衡点,而不是凭感觉调参。
5. 为什么政企场景需要独立的实体校对模块,而不是指望模型自己写对?
答案要点
因为人名/职务这类正确性是硬要求且不可统计性保证:模型本质是概率生成,无法保证特定字符串 100% 正确。用结构化知识库 + NER 后处理 + 规则引擎做外部约束,把「正确性」从模型能力问题转成工程可保证的问题。这体现了生产系统与 demo 的分界:不能靠模型自身兜住的正确性,必须用外部机制兜。