做了一整晚,周报还停在外围:我们为什么把一个大 Spec 拆成三期?
一次 Agent 周报开发复盘:完整思考方案,不等于一次性实现全部方案。
一、我们原本只是想让 Agent 写一份周报
2026 年 10 月,我们准备给 ETF Agent 增加一项很自然的能力:根据用户已有的基金持仓,每周生成一份投资组合复盘。
我们的目标不是让 Agent 罗列一周涨跌,而是让用户看完后知道:组合发生了什么变化、风险有没有偏离、哪些事情值得关注,以及是否需要调整后续研究。
报告最好是 HTML,手机上能读,有必要的图表和数据来源,聊天窗口再给一段简短结论。
但当我们真正开始设计,就发现这件事远比“每周总结一次”复杂。
如果是周报,似乎应该有历史记录;既然有历史,最好支持跨期比较;既然能够比较,就应该保存过去的投资观点,记录观点有没有变化;既然是每周的事,最好支持定时订阅;既然会订阅,就还需要通知、取消、重试;报告要交给用户,还得考虑 HTML、移动端、打印、文件保存和下载。
这些需求单独看,都合理。
于是我们认真讨论了完整产品方案,形成了覆盖多类场景、多个模块和不同验收路径的 Spec。
问题也从这里开始。
二、一个晚上过去了,我们还在完善外围能力
开始实施之后,我们并不是没有进展。
我们逐步处理了研究方法、固定 HTML 渲染、文件保存、历史资格、来源交接、页面可用性和一些失败路径。局部测试不断增加,一些组件也能够独立运行。
可开发了一整晚,我们回头看用户最初的要求,发现一个尴尬的事实:
我们花了大量时间让周报系统变得完整,却还没有让 Agent 从正常入口自主交付第一份周报。
这并不是说历史、订阅、安全或移动端不重要。
问题在于,我们没有足够严格地区分两类工作:
一类是没有它,第一份报告就无法交付。
另一类是有了第一份报告之后,产品才能长期变得更好。
它们都值得做,却不应该天然拥有相同的实施优先级。
当时的大 Spec 已经把这些工作组织在同一套任务和验收中。结果就是,某个外围机制尚未完善,整项工作看起来就还不能结束。
更糟糕的是,这种结构会不断产生新的依赖:历史比较要求更完整的来源;来源处理牵出版本管理;版本管理又牵出恢复;HTML 的视觉问题又让我们继续研究渲染器。
一个 Spec 可以在逻辑上自洽,却在交付顺序上不合理。
而 Coding Agent 的强执行能力,反而会放大这个问题。
过去开发一个外围功能可能需要几天,我们自然会重新考虑优先级。现在 Agent 可以连续创建模块、补测试、完善协议,只要计划里还有任务,它就能持续推进。
它并不知道:继续完成计划,与尽快交付用户价值,可能已经不是一回事。
三、真正改变方向的,是重新定义第一份结果
10 月 20 日,我们决定收缩第一期范围。
不再要求一次交付完整的周报产品,而是把第一阶段重新定义为:
用户通过一条正常 CLI 命令启动研究,Agent 自己取得获准的数据,形成报告,保存 HTML,并在最终回答中返回真正可下载的文件链接。
这条要求听起来比之前简单得多。
但它反而更严格。
因为它不接受几个常见的替代品:
- 模型说“报告已生成”,却没有实际文件;
- Python 完成了渲染,但没有经过文件保存;
- 测试代码预先拼好结果,替 Agent 完成关键步骤;
- 开发者手工修改参数或补文件之后,宣布“自动交付成功”;
- 服务端已经保存,却无法从正常下载入口取得文件。
我们先要求离线生成、保存和下载一份真实文件,证明不依赖模型的基础交付链成立。之后再让真实模型通过正常入口使用同一项能力。
此时,第一期不再把长期历史、复杂比较、订阅通知、投资论点管理和精细版式当成关闭条件。
这不是取消它们,而是撤销它们对首份结果的阻塞权。
同样,首期 HTML 可以朴素,研究数据可以明确标记不足。但必须保留真实权限、来源身份、文件安全和执行事实。
缩小交付范围,不能靠删除必要的正确性保护实现。
四、HTML 又让我们发现:有些能力根本不该属于周报
范围收缩之后,还有一次更深的架构调整。
我们原来为周报准备了一条相对专用的生成路线:固定研究方法、Python Renderer、专门的 HTML 生成和文件交付接线。
固定模板有其优点,输出比较统一,也方便做确定性检查。
但真实研究逐渐暴露出另一面。
模型可能已经拿到数据,却把结果哈希误当成工具调用身份;可能尝试导出一个实际不存在的工作区路径;也可能在一段漫长的 Python 流程中完成计算和渲染,最后仍然没有交付文件。
另一批报告交付检查甚至出现过:文件已经保存,最终回答也给出了链接,但五次认证下载全部返回 404。
这些不是单纯的“HTML 排版问题”,而是在提醒我们:
周报的独特性主要是研究方法,不是文件基础设施。
为什么周报应该拥有一套自己的文件保存协议?为什么直接写 HTML 和 Python 生成 HTML 必须走两套不同的交付逻辑?
后来我们把通用 HTML 生成、保存和下载能力从周报专用路径中抽出来。
可以把新的交付路径简化成:
- Agent 研究并组织内容;
- 根据任务选择直接生成 HTML,或者用 Python 完成必要计算和批量生成;
- 两条路线共同使用既有内容准备、来源处理、文件保存和授权下载能力。
模型负责选择适合任务的表达方式,已有领域能力负责可信数值,Publication 处理内容准备,Artifact 负责实际文件字节和访问边界。
我们不再要求每一种报告都经过一条专用 Renderer,也没有顺手增加新的 HTML Router 或通用展示 DSL。
这一步非常关键。
分期交付不只是把任务往后推。有时还会迫使我们发现:某项能力原本就放错了产品边界。
最终,周报 Skill 可以专注于研究方法,而 HTML 成为其他研究任务也能够复用的通用交付能力。
五、一期、二期、三期,最后到底怎样划分?
经过重新整理,我们不再按照原 Spec 的章节顺序推进,而是按照可以独立交付的结果组织工作。
| 阶段 | 独立结果 | 不再作为本阶段阻塞的事情 |
|---|---|---|
| 一期:首份周报 | 一条正常命令完成研究、HTML 保存和实际文件下载 | 历史比较、订阅、复杂论点管理、综合质量优化 |
| 二期:连续周报 | 合格的历史记录、跨期比较、保留与删除、历史读取及基础可用性 | 订阅通知、进一步的论点版本管理、深度优化 |
| 三期:长期伴随 | 有限周期执行、任务历史、通知偏好、投资论点与用户修正、进一步的研究深度选择 | 新交易系统、第二套调度器,以及不属于 Runtime 的语义质量保证 |
HTML 通用能力不是“第四期周报”,而是从具体场景中识别出来的横向基础能力。
这次拆分还有一个不太显眼、但很重要的操作:
真正修改当前期的需求范围、任务清单和验收条件,同时把已有工作、失败和后续需求移交给相应阶段。
如果只在 Proposal 里写一句“MVP 优先”,原来的任务清单、依赖关系和关闭条件完全不变,那不叫分期,只叫给超大的 Spec 换了一个标题。
对于已经接近完成的二期工作,我们也没有为了拆分而机械搬走。是否拆出三期,取决于它是否拥有相对独立的交付结果、责任边界和验收周期,而不是根据任务数量平均分成三份。
六、拆分之后,交付终于有了可证明的结果
10 月 20 日,一期共享 HTML 路线取得了更明确的工程结果。
在固定候选的五次普通真实 CLI 运行中,五次都按当期交付条件正常结束,返回了实际保存文件的链接;13 个 HTML 文件版本通过认证下载,返回的字节大小与 SHA-256 与保存记录一致。
这次我们终于能够明确说明:
第一份报告所依赖的主要文件交付链,已经有正常入口的实际证据。
但我们没有因此宣布投资研究质量也已经通过。
一份文件可以真实存在、正确下载,而其中的分析仍可能不够深刻;一次报告可以完成,Agent 也未必能够稳定处理所有复杂变体。
后来的二期和三期分别完成了声明范围内的 Runtime 工程验收;它们并不自动证明周期研究具有长期产品价值,也不证明模型总能做出正确的投资判断。
这种结果分层,反而让开发进度更可信。
以前,一个外围问题没做好,可能让整项任务永远显示“未完成”。
现在,我们能分别回答:首份文件能否交付?历史能否正确保存和读取?定时任务是否遵守确认与取消?模型的研究质量又证明到了什么程度?
不同问题拥有不同的证据,不再互相借用成功。
七、怎样防止下一个大 Spec 再次陷入这种困境?
这次最值得保留的收获,不是临时把周报拆成了三份,而是我们随后调整了 Coding Agent 的 Spec 研发工作流。
否则下一个复杂需求到来时,Agent 仍然会兴致勃勃地规划十个模块,再花一个晚上建设外围。
我们把防止重演的做法收敛到了已有流程中,没有另外发明一套“分期审批系统”。
第一,设计阶段必须先说清第一份交付物
以前,我们更习惯从功能列表开始:要支持什么、有哪些模块、每个模块如何验收。
现在面对复杂需求,我们会更早提出:
用户最早可以得到什么真正可用的东西?
它可能是一份报告、一个文件、一次真实计算、一段可以完成的业务操作。
只有先确定这个结果,才能反过来判断哪些能力是必需依赖。
例如周报:
历史比较不是第一份报告的必要依赖;周期订阅不是;投资论点的完整版本管理也不是。
但合法取得数据、实际生成文件、保存并返回可下载链接,是必要依赖。
因此 Spec 中要明确第一份产物,以及如何观察它确实完成,而不只是罗列一串功能。
第二,允许完整设计,但不允许提前实施所有阶段
我们没有转向另一种极端:只准讨论第一期,未来一概不考虑。
复杂系统有些边界必须提前想清楚,例如权限、数据身份、持久化兼容,以及后续阶段是否会迫使当前结构推倒重来。
所以可以完整讨论远期方案。
但讨论过,不等于这一期承诺实现。
当前阶段只把必要依赖放入执行任务。远期功能可以保留方向和关键接口约束,但不因为它们已经出现在设计稿里,就提前创建表、服务、协议和测试框架。
哪怕有多个 Coding Agent 可以并行工作,也不代表应该让它们同时铺开所有外围模块。
并行能力解决的是执行效率,不会替我们自动判断任务的价值顺序。
第三,真正按阶段维护任务和验收,不只是给清单加标签
这是我们从周报拆分中得到的直接教训。
现在,若一个需求确实需要分期,我们要求每一期都能回答:
本期交付什么?依赖什么?哪些事情明确不属于本期?怎样证明本期完成?
实施顺序也按这个结果安排,而不是按照原来文档章节的先后顺序。
如果任务已经缩小范围,就要同步修改当前任务、计划和验收承诺。延期能力从当前完成条件中移除,并保留其后续归属和已经完成的证据。
不能一边说“先交付”,一边继续执行原来那份庞大的任务清单。
同样,某一期通过,不等于整个大需求已经完成。
这既防止首期交付被无关工作拖延,也防止我们把阶段成功包装为完整产品成功。
第四,把“是否值得新增机制”放回原有设计评审
即使当前阶段已经收窄,Coding Agent 仍可能在实现途中不断增加新模块。
因此我们继续使用原有的四个设计问题:
事实归谁,决定权归谁,失败如何处理,新机制究竟带来什么价值?
例如报告生成失败,应该先检查已有生成和保存能力哪里断了,而不是马上创建一个专用 Report Manager、Repair Agent 或新的流程控制器。
这项检查不要求开发者再填写一份新表格,也不为每种复杂度创建自动评分器。
我们希望改变的是开发者和 Coding Agent 的判断,而不是增加一道流程。
第五,验收沿真实交付路径,证据足够就停止扩大范围
对周报来说,文件存在不等于下载成功,局部测试通过不等于 Agent 自己完成。
因此第一期要求从正常入口走到实际文件交付。
与此同时,我们也明确区分:工程交付链的验证和模型研究质量的验证,是两个问题。
局部接口变更先做针对性回归;真正需要观察模型行为时,才进行相应真实测评。
同一范围已经得到有效证据,也不因进入下一个文档阶段就反复重跑整套检查。
验证是为了回答明确的问题,而不是为下一轮验证创造理由。
这一套方法什么时候启动?
不是所有需求都强制拆分。
如果任务很小、范围清楚、可以一次完成,就正常开发。
只有当一个 Spec 涉及多个可独立交付的结果、外围工作开始延迟核心交付,或者单次承诺已经难以清晰验收时,才需要认真考虑分期。
我们也不设固定的两期、三期或任务数量阈值。
防止重演的关键,不是让所有项目都变得流程化,而是在复杂需求第一次进入设计时,就建立清晰的交付顺序。
八、最后,我们改变了对完整设计的理解
问题不在于我们思考得太完整。
讨论历史、订阅、长期论点和恢复,是有价值的。提前识别会造成返工的关键约束,也有必要。
真正的问题是:
我们把“设计时应该考虑的问题”,变成了“第一期必须完成的事情”。
完整设计与分期实施并不冲突。
设计可以提前看见终局,实施却应该围绕最早能够交给用户的真实结果展开。对后续阶段,只保留必要的职责边界、不可违反的约束和已确认的方向。
如果第一份结果可以在更小的闭环内产生,就不应该让未来的完整产品形态持续决定今天是否可以交付。
这次周报实践最后让我记住了一句话:
完整思考方案,是为了避免未来走错方向;围绕第一份结果实施,是为了避免今天一直走不到终点。
而把它写入现有研发工作流,是为了让下一次 Coding Agent 面对复杂需求时,不必再靠做了一整晚之后的醒悟,才想起用户最初要的是什么。
取材边界:本文基于 2026 年 10 月周报一期、二期、三期的 Spec、实施记录、HTML 交付复盘和后续 Spec 工作流调整。完成与下载数据属于各自测试窗口;不代表生产部署、模型研究质量或实际投资收益已获证明。
延伸阅读与交流
这次经历与从 Bug 循环走向真实任务收敛、HTML 交付架构反转、Spec 与 Evidence 工作流相互补充。另一篇代码删了,旧文档为什么仍在指挥 Agent?继续讨论长期工程知识怎样跟着架构演进。
更多实践见 ETF Agent 工程文章与阅读目录。如果这些真实开发经验对你有帮助,欢迎到 GitHub 点个 Star。