我是安徽最忧郁程序员无隅

一个文档导入功能做到一半,旧会话结束了。新会话打开项目,看到代码已经改过,却不知道哪些改动有效、哪些检查没跑,更不知道为什么上次选择了这个方案。
Day 6 和 Day 7 围绕的就是这个问题:怎样把任务留在一个可以被接手的位置? 这里的 Harness,可以先理解为围绕 Agent 的工作约定、状态记录、执行工具和验证反馈。
两天的核心很好记:init 恢复环境,handoff 恢复任务上下文;新会话的实际接手行为,用来检验这两部分是否有效。
本文整理自阅读、项目只读观察和学习讨论。两天的实际恢复实验均已跳过,因此下面的功能状态示例用于解释机制,不代表已经取得跨会话成功证据。
一、任务连续性需要留下哪些信息
先限定一个场景:接手者可以读取项目文件,但没有获得旧聊天内容。它的目标是在一个桌面知识库应用中,继续完成"文档列表显示导入时间"。这不涉及某个工具是否自动继承聊天的产品设定。
新会话需要恢复两类信息。第一类是执行条件:从哪里启动、依赖是否可用、怎样检查。第二类是任务状态:做到哪里、为什么这样做、还缺什么证据。
| 要回答的问题 | 应留下的信息 | 主要职责 |
|---|---|---|
| 怎样开始工作? | 项目入口、环境准备和检查方式 | 初始化 |
| 已经发生了什么? | 改动、代码状态、执行结果 | 进度与验证记录 |
| 为什么采用当前方案? | 关键决定及其理由 | 决策记录 |
| 接下来做什么? | 一个可执行、可观察结果的动作 | 会话交接 |
这些信息不一定要拆成四个文件。小任务可以放进一份简短交接,复杂项目再通过入口链接到详细记录。关键是接手者能找到它们,并且能分清事实、判断和待办。
例如,代码里存在导入时间字段,只能帮助接手者识别当前实现。它未必能说明字段为什么在导入时生成,也不能告诉接手者重启后是否还能读取这个值。
Anthropic 的长任务工程文章采用了相近的分工:首次会话准备环境,后续会话逐步推进,并通过进度文件与 Git 历史帮助新会话了解工作状态。这里借鉴的是交接机制,不据此推断本次学习的效率收益。来源:Effective harnesses for long-running agents
二、Day 6:初始化要有可以判断的结束点
在导入时间这个任务里,确认项目目录、准备依赖、运行基础检查,属于初始化;增加时间字段、补充保存逻辑、调整列表展示,属于功能实现。
先初始化的价值,是留下一个可核对的起点。如果第一次检查已经失败,后续就不能直接把同样的失败归因于本轮修改。反过来,初始化发现失败,也不意味着应该顺手修完整个项目:先记录失败,再判断它是否阻塞当前任务。
初始化的产出应当是明确的环境状态和基线结果。 它可能告诉我们"可以继续",也可能告诉我们"这里存在阻塞"。仅有脚本文件,或者仅有安装成功的输出,都不足以证明功能可用。
为什么准备完成后,不一定立刻启动应用
这次读到的资源版 init.sh 模板,会切换工作目录、安装依赖、执行基础验证,再输出启动命令。默认情况下,它随后返回;只有显式设置 RUN_START_COMMAND=1,才进入启动应用的分支。这是本次本地模板的行为,具体命令仍需按项目调整。
这样安排有一个很实际的原因:开发服务器或桌面应用可能持续运行。如果初始化在前台进入这个进程,等待初始化结束的后续步骤就要继续等待,直到进程退出。
把准备阶段和持续运行阶段分开,调用者才能知道何时可以开始下一项工作。实际工程也可以采用后台服务等方式管理生命周期,但需要另外处理就绪检查与清理;本次没有验证这些方案。
同时要区分"第一次建立初始化流程"和"后续会话使用它"。前者可能需要配置基础设施,后者只应按项目约定恢复必要条件,不必每次重新搭建整个环境。
本次只是阅读 Bash 模板,没有执行初始化,也没有验证它在学习所用 Windows 环境下的兼容性。
三、交接要让下一步能执行,而不是让摘要看起来完整
学习交接时,我最容易混淆的是"本轮改动"和"当前已验证"。修改了元数据类型与列表组件,是改动事实;运行类型检查并取得成功结果,才是一项验证事实。
如果把这些都写成"功能已完成",接手者就可能直接跳过剩余检查。反过来,只写"还有一些东西没验证",又没有告诉它该从哪里开始。
下面用一个假设场景演示交接内容:字段和展示代码已经修改,类型检查通过,但测试和真实界面还没有验证。表中所有执行状态都是教学假设,不是本次项目结果。
| 交接字段 | 教学示例 |
|---|---|
| 目标 | 文档列表显示导入时间,重新打开应用后仍能读取已保存的时间 |
| 本轮改动 | 增加导入时间字段,调整列表展示 |
| 决定及原因 | 在导入时生成并保存时间,界面只负责格式化,避免每次渲染重新生成 |
| 当前已验证 | 类型检查退出码为 0;该结果仅对应本次检查时的代码状态 |
| 已知缺口 | 保存行为尚未验证;自动测试、真实导入和重启流程尚未验证 |
| 唯一下一步 | 在项目目录运行 npm run test,记录退出码与失败项;若没有测试,记录验证缺口 |
这里使用的 npm run test 是本次课程 starter 在 package.json 中定义的项目脚本,指向 vitest run。其他项目应使用自己的验证入口,不能直接假定命令相同。
实际交接还要附上工作位置、当前提交、未提交修改文件以及验证输出的位置。只写一个提交号无法描述尚未提交的改动;只留下"通过"两个字,也无法判断结果对应哪一版代码。
决定需要理由,下一步需要结果信号
"在导入时生成时间"记录了方案;"避免每次渲染重新生成"记录了它要保护的行为。新会话因此能理解约束,在提出替代方案时也知道应该保留什么。
"继续完善"则缺少动作边界。把它改成"运行测试并记录结果",接手者就能开始执行,也能判断这一步是否结束。如果失败,应留下失败项与下一步诊断方向;如果没有测试,应保留缺口,不能写成通过。
验证层级决定交接中可以说多大的结论
本次课程约定的验证顺序是:类型检查 → 自动测试 → 真实 UI 流程。低层通过不能证明高层也通过。

类型检查能发现其检查范围内的类型问题,却不能证明用户点击导入后一定看到正确时间。自动测试能证明被断言覆盖的行为,但如果它绕过了真实界面,界面链路仍然缺少证据。
即使实际导入后显示正确,也还不能据此断言重启持久化通过。这个需求需要另外观察重新打开应用后的结果。交接记录应把验证命令、样例、结果和代码状态连在一起,而不是只保留一句"测试正常"。
四、Day 7:用接手者的行为检验交接质量
Day 6 解决怎样留下记录,Day 7 追问记录是否真的足够。独立恢复实验能够提供一种单靠阅读得不到的证据:没有旧聊天的接手者,能否利用这些材料找到正确动作,并继续完成验证。
一份交接可能结构齐全,却遗漏了测试运行目录或关键错误输出。原作者看得懂,是因为还记得上下文;新会话实际执行时,这些隐含信息才会暴露出来。

恢复不能停在"读完交接"。接手者还需要核对代码与环境:如果交接写着字段已保存,实际差异却只有列表展示,就应先查清差异。旧记录提供线索,当前代码和检查结果用于确认现场。
原定观察有三项,各自回答不同问题。
| 观察项 | 具体判断 | 需要保留的边界 |
|---|---|---|
| 恢复耗时 | 多久找到正确、可执行的下一步 | 依赖安装、审批等待与实现耗时应分开记录 |
| 重复探索 | 是否重新寻找已经查清但未留下的信息 | 为确认记录仍有效而核对代码是必要工作 |
| 决策漂移 | 是否因遗漏目标或理由而无依据地改变方案 | 根据新证据修正旧方案不应一律算作漂移 |
课程 Day 7 的原定门槛是:15 分钟内找到正确下一步,并且无需口头补充即可完成和验证。这里的 15 分钟是课程验收口径,限定的是找到下一步;它不是本文测量结果,也不是所有项目都适用的标准。
如果要做对照,还需提前登记模型、推理设置、权限、工作流程与人工干预。如果这些条件跟交接材料一起变化,就不能把效果全部归因于文档。本文没有进行这样的比较,也没有恢复效率提升数据。
五、这两天已经学到什么,还缺什么证据</fonte
Day 6 的实际观察停留在 starter 的只读核对。学习记录确认了项目有启动、构建、类型检查和测试脚本入口;相关状态文件中,四个新增功能仍为 not-started,已有功能的 pass 声明未在本次独立复验。
当时根目录已有项目入口说明与功能清单,缺少初始化、交接、进度和决策等相关材料,也没有发现测试文件。测试命令存在与测试用例存在,是两件需要分别确认的事。 这些观察能描述准备状态,不能证明任务已经可以恢复。
Day 7 完成了交接结构讨论、既有记录核对讲解和恢复观察项介绍,没有启动独立新会话接手产品任务。因此,两天的最终学习状态都保留为 skipped:概念讨论有记录,实际初始化、中断交接、恢复耗时与产品验证证据仍然缺失。
对我来说,最有用的收获是形成了一种更准确的记录方式:把已经改过的代码、真正验证过的行为、尚未解决的问题,以及下一步动作分别写清楚。它让后续工作有依据,也让"没有验证"能够被看见。
把这两天连起来,任务连续性的机制就是:先准备能执行和检查的环境,暂停时留下状态与理由,接手时核对现场,再推进一个明确动作。交接是否有效,最终要由接手者能否继续工作来证明。
本文依据为 Day 6--7 的学习记录、课程计划、第五讲与第六讲,以及本次读取的交接和初始化模板。外部机制参考见前文链接;文中的交接样例均为教学假设,没有将讲义中的效率数字写成本次实测结论。