ARTICLE · 1319043
从 40 分到 85 分:Office Secretary 公文写作 Agent 的架构演进与极简重构
ORIGIN/起因
有这个想法是因为在工作中有一份材料被领导打回来了。一份发言稿,原稿可能是按公文的材料逻辑准备的。领导觉得重点不够突出,没有逻辑——实际上是不符合发言人的记忆习惯。因为材料的组织是按照重要程度为序以方便以后工作安排确定权重。而发言材料需要按照现实生活中的语言逻辑要符合听者信息拾取习惯——这是一个不小的挑战,思维路径是具有稳定性的,这种稳定性带来的潜在问题就是很难跳出既定路径进行自我审计。
后来我用Claude给出的思路很快解决了这个问题。
基于这个案例,能够发现两个事实,材料写作方面,大模型由于海量的语料训练形成了天然的多维度优势,尤其是能力比较强的前沿模型在理解和语言塑造上的能力往往能打破人类的思维路径依赖。
再则部分职场人在材料编写上确实花去大量的时间,以前也想做这个动作,减少工作量。但是由于当时模型的发展局限,写出来的东西达不到企业内部要求。而现在刚好在这个当口,包括claude的opus等前沿能力已经完全胜任书面材料的编撰工作了。
所以,我把这个事情做成一个待办。开始尝试一些解决方案。
FIRST THINGS FIRST/最重要的事
在一切开始之前,最重要的是先要搞清楚最核心的目标是什么?我要解决什么样的问题。
原因非常简单。
因为在实际操作过程中会不断出现新的问题,随着需要解决问题越来越多,解决新问题很容易造成执行飘移。因为在不断解决新问题的过程中又会发现其他问题,到最后会造成失焦,并且逐渐偏离原来的目标。这个问题无论是对于大模型或者对于人而言,都客观存在。
这样的事情在我自己的生活中比比皆是。例如,我想打印一份试卷出来给小朋友测试,打印出来以后就想装订起来,发现订书机里没有订书钉了,然后我去找订书钉,打开书房的灯,发现开关坏了,然后我又开始修书房的灯开关。
自己写起来的时候都觉得好笑,但是这样的事情确实在生活中屡见不鲜。
所以知道自己要解决的问题是什么,然后在执行中不断从事务中再聚焦非常重要。这个问题对于agent相对反而很好解决,我们做好一个decision,制定好principle,冻结以后,每次决策都能够清晰的知道决策树和路径,最大程度减少飘移。
但是对于人类而言,这样的机制反而有点逆人性,需要不断的训练。
你看,此刻由于我太想把一个事情层层剥开的说清楚,目测可见的发生了飘移。
让我再次回到我们topic:回顾一下Office Secretary的开发历程,忠实的记录。
WHAT IS THE PROBLEM?/遇到了什么问题?
我能观测到最大的问题是:报批的材料达不到领导的要求。反复修改造成了极大的时间和精力浪费。
工作做了,但是在呈报的书面表达上,从内容的表述,结构的组织,以及用途的适应上,撰稿人无法进行多个维度精确的对齐。并且由于写作习惯形成了风格依赖,在对齐不熟悉或者不擅长的风格或者要求时,会出现卡死。
WHAT IS THE KEY ISSUE?/解决问题的关键在哪里?
这看起来是一个非常简单的问题,但在项目的具体操作中,却是整个系统发生过的最重大的转向的十字路口。
基于这样的考虑,我们设计了两个大的模块。模块一:面向不同的领导,建立不同的profile,profile中记录了领导的偏好,我们将领导的偏好作为prompt的一部分给到前沿模型,进行稿件撰写。同时根据领导的批示建立学习飞轮,甚至建立了领导提出的优质语块的语块池。我们用一个前沿模型对领导的批示进行学习,可以泛化的偏好我们用来更新profile,一些得到正向点评的优秀语句或者词块,沉淀进语块池。
这样一来,我们根据领导的偏好进行稿件的撰写,并且不断沉淀学习领导的偏好,优化写作风格和内容组织形式。用稿件退回次数作为事实终裁。对于学习后形成的profile和lexical chunk进行后评价继而再优化。通过不断优化,最终实现稿件的零退回。
看起来,我们建立了一个逻辑上非常缜密的系统。
WHAT ELSE?/还需要什么?
首先对于公文写作,准确是前置要求,所有监管文件,治理措施,业务数据,前序决议的引用必须是有据可依。
虽然说目前的前沿模型对于低级幻觉已经控制的非常优秀了,但是备不住你没有给到足够的信息和约束,它出于善意补足开始自由发挥。所以我们需要一个成熟的资料库。这个资料库不但是之前呈批文稿通过以后的存档,同时也是我们前面提到的治理措施,业务数据,前序决议等参考文件的存放和引用池。笔者可以调出相应的文件选择当次撰写需要用的数据以及以前的决议等等,加入到撰写提示词中。
另外,我们也需要给学习飞轮以及profile加入手动调制的功能,避免将某一次特例判断成一个长期适用的泛化意见。
其他还有一些具体的业务逻辑流程,数据处理,备份等等常规性的需求。
INTERACTION/交互
这也是非常重要的一个环节,用什么样的方式进行交互。
由于我们采用的模型是境外服务商的闭源模型,所以服务只能部署在云端。考虑到用户使用的便利性,初步的设计是使用Difyweb,后来转移到云端部署的Hermes Agent,hook到本地的飞书bot。最终我们使用的是优化后的Web网页。
这样的迁移一来是因为整个系统架构的转换,同时也是出于合规的考虑。用户在使用的时候只用通过前端聊天对话框键入需求和命令。那么云端的Agent就可以响应,在同一个实例中,通过cli工具利用当地部署的CC或者codex进行LLM的调用,进而实现稿件的撰写。
Developing/开发
手里的开发工具常用的Claude Code,Codex。备用的:Zcode。可用但不堪用的:Antigravity Cli。
我用的chatgpt的chat作为整个项目的PM。原因非常简单:没有token的限制——写在2026.11.5,几天前chatgpt已经公告了“喜讯”:chat将和work以及codex共用额度——这对于开发提供了极大便利,就是不用换PM,在上下文一致的情况下,我可以在CC,codex,zcode之间来回转换,用不同的编码agent进行具体的代码编写。
整体来说,对于代码基础薄弱的我而言:CC会在执行ChatGPT的指令时候给出他自己的意见,使用体验更好一些,而且看到他们俩的讨论,自己也会多少学到一些东西。而codex是一个非常好的执行者,但是执行完以后不会主动的提出潜在问题。主打一个指哪打哪,打完不管。Zcode就像是CC的远方侄子,很像但是有差距。
如果在不考虑token的前提下,我是希望由Claude来做PM的。ChatGPT很多时候让人感觉表达欲很强,虽然输出很结构化都是用要点分层次的表达,但是确实有时候把关键信息淹没在了事实的复述中,以至于很多次,我都会在不同的session中强调:回复遵循第一性原理,给出的命令要求精炼重点突出。这样会大幅缩减给开发agent的prompt——这主要是减少我看这些prompt耗费的精力,因为太多了我肯定不会看,如果精炼一点,在反复处理一个问题的时候,我能检视一下整体处理逻辑。
开发过程中的第一性原理
事实上,我极度厌恶这些X上KOL用来引流词,在Elon Musk提出第一性原理以后,我相当长一段时间在X中文圈里被这个词刷屏,以至于都产生了应激。
但是在具体的开发中,我发现如果我的开发进程是A-B-C-D-E,在E出现了问题,正常情况下应该回溯整个工作链审视从A-Goal之间有没有正确的路径始终找寻最合理最短路径,但是agent默认不是这样的,他们在出问题的地方做补丁,然后进行测试,如果没有通过就继续打补丁,最终卡死。即便是补丁搭好了,测试通过了,如果在进行修复的过程中进行了功能上的让步或者妥协,很快就会发现,这种细微的堆积会带来最终实现的极大飘移。
另外,以codex为例,执行中很容易陷入无休止的测试,在一个测试中发生了非阻塞故障,他会不断的进行修复,企图让系统完美通过测试。这耗费巨量的时间和资源。
所以,我一般在一个环节三次报错以后都会让agent“退回原点思考,我们有没有更好的解决方案”,不知道是不是因为“退回原点”这个语料没有充分训练,事实上效果不太好,直到我把我的想法告诉了gpt,他帮我梳理出了适用于这个principle的提示词:
vibe coding 第一性原理
1.面向最终目标,不要陷入工程,不为架构而架构,不为验证而验证。始终回到目标,用第一性原理判断什么真正重要。
2.遇到一个新问题,先思考:
它是否真正阻碍核心目标?不解决它,会不会造成实质性风险或错误?有没有更简单、直接、成本更低的方法继续前进?
如果答案只是“理论上还能更严谨”“工程上还能更漂亮”,但不影响产品核心价值,就记录backlog,继续推进。
并且在不断的实际中总结以后形成了目前最终的版本。
DEVELOPMENT PROCESS/开发过程
process 1
基于以上的种种设计,我们做了第一版的系统架构:
“Dify 本身现在就定位为 AI 工作流平台,可以编排模型、数据源和流程,同时提供知识库/RAG、Agent 和 Workflow,因此很适合做这里的“AI运行核心”。
n8n 的强项则是把 API、系统、文件和事件连接起来,并且可以自托管;因此更适合作为后台的自动化胶水层,而不是承担核心写作推理。”
在这个时候雄心勃勃的使用了Dify作为工作实施,n8n作为了编排器。
此时的前端还没有设定为飞书bot,Hermes也没有进入视线,前端准备自建或者使用dify web。并且还准备把领导的profile做成矢量数据库,通过RAG检索调用。
但是由于我不想再购买credit所以希望利用claude code或者codex的订阅auth。
这一版被推翻。
很快根据我提出的新的要求,收敛到了真正开始实施的架构。
我们基于移动办公,会议记录等多场景考量,采用了飞书bot-云端Hermes Agent 调用云端Claude和Chat GPT的架构。
顺着这个架构和思路一路完善和修正,最终实现了系统的上线。上线以后跑了第一个真实场景的模拟任务。
效果完全拉垮!
整体效果毫无可取之处,从系统日志看,无论是profile还是skill以及核心规则都给了编撰agent过多的约束和限制,以至于最终出来的文本无法达到40/100,这是一次显而易见的失败。原因也非常明显:我们之所以认为LLM能给出满意的文本,是基于原本没有任何约束限制的环境下,我想当然的以为有了更多的内容:喜欢什么样的,可以怎么写,会类似于通过提示词来校准输出,在原有的生成效果上会更符合期待,我甚至还和模型微调进行了对标。
但事实上,我认为的校准在操作中对于模型而言是极大的限制和约束,以至于LLM无法充分的发挥能力,只能在限定的一小块区域内进行有限的创作。
在发现这个重大的设计缺陷时,我当时第一个想法就是:为什么在一开始不用极小的成本先进行功能验证,例如模拟画像和约束给出提示词进行A/B对照,验证我的假设是否成立。这只会花很少的时间,可能不到一个小时,却能让我少走上百个小时的弯路,节省巨量的token。
但都已经走到这里了,硬着头皮也要救回来。
process 2
真正难的不是下定要重来的决心,而是不知道该从哪里开始。
我让GPT根据实现流程仔细分析了过度约束的来源,发现学习飞轮本身就是最大的污染源。因为我们在不断的根据某个人的喜好设置越来越多的约束条件。
然后因为设置中hermes的功能是一个router所以在胶水提示词的控制上,环节越多,越容易引入更多的不确定性。
因此,我们做了一个重大的转向:
1.不再使用Hermes作为服务入口,即刻冻结退出。转而使用web服务,UI满足于电脑显示的同时针对于手机显示进行优化。
2.鉴于目前的LLM已经拥有了超强的写稿能力。所以放弃学习飞轮,不再针对个人进行偏好画像。只使用每一轮的反馈作为提示词,尽量保证LLM能最大限度的自由发挥自身的能力,并且从网络获取相关的知识和内容。资料库作为唯一的外部提示词接口只提供关键事实和数据,不对写作进行风格上的限制。
接下来,我们做了几轮A/B对照测试,事实证明,使用这种办法,在保证写作质量的同时,也补充了针对性的事实,提高了整体的文件撰写质量。
接下来就是选择要继承的legacy了。
刚刚开始的时候我们使用了新建的核心功能,然后基于此进行UI的移植。事后看来由于核心功能在新的设计中非常轻——毕竟我们保留的东西已经很少了。但是在UI和交互移植的时候发现了很多问题,几乎没有办法完整复现最初已经经过多轮测试的成熟交互体验。
所以最终,我们又冻结退出了这个分支,转而克隆了整个老项目,剔除了核心功能以后,用新的核心功能去适配老的交互和UI,并按需进行调整。
THE END/终局
最终,我认为我们获得一个期待的结果,当然,后来我们还在word导出,通过文档自动进入资料库等等细节上进行不断的优化。
迄今,我们这个系统仍然处于运行测试阶段。目前来说总体符合预期。重构后相同场景的文本通过率从不可用的 40 分回升到了可以作为高质量初稿的 85 分以上,退回修改次数显著降低。
我进行这个记录的初衷也在于,不论接下来出现什么状况,能通过文字的忠实记录让这个开发历程能够在日后的其他项目中起到参照的作用,少走弯路,沉淀经验也汲取教训。















































































