上周我干了一件特别蠢的事——把一个代码库重构任务丢给 Harness让它慢慢跑然后合上笔记本就走了。两天后回来一看任务在 7 小时 58 分的时候崩了上下文全丢连个 checkpoint 都没留下。我当时的表情大概就是那种想骂人但不知道骂谁的崩溃感。你别说这事儿还真不怪 Harness。怪我。怪我太天真地以为把任务丢给 Agent 就行了就像把一锅汤放在灶上然后出门旅游——回来发现锅烧干了你还怪锅不行锅是冤枉的。今天这篇不打算讲什么高大上的架构设计就聊聊我踩过的坑。长任务场景Long-running Task——指那些需要跑几小时甚至几天的 Agent 任务——有三大死法上下文溢出、断点丢失、状态爆炸。一个一个说。先说上下文溢出Context Overflow。Agent 的上下文窗口就像你的办公桌——一开始整整齐齐文件、咖啡、笔记本各就各位。但跑着跑着中间结果、日志、报错信息、模型回复……全堆上来了。桌子不够用Agent 就开始失忆——它不记得十分钟前自己改过哪个文件不记得当前任务进行到哪一步了甚至开始重复做已经做完的事。我第一次跑的时候没意识到这个问题。Harness 的 Standard 模式默认是单轮对话上下文管理相对简单。但切换到 PTC 或 Creative 模式后Agent 会反复调用工具、检查结果、调代码——每一步都在往上下文里塞东西。上下文一满表现就像你同时开了 50 个浏览器标签页的电脑——卡死、崩溃、或者干脆不响应了。有意思的是我后来试了 DeepSeek 和 Claude 来做同一个长任务表现完全不一样。DeepSeek 在上下文逼近上限时会偷偷忘掉早期的中间结果但不会告诉你Claude 就会直接报Context length exceeded然后优雅地停在那里等你处理。Harness 的做法是分段管理——它会自动把早期对话归档到所谓的历史段History Segment只保留最近的交互在活跃上下文里。这个设计很聪明但不是万能的。笑死我发现有个坑是如果你在插件里往上下文里塞了太多结构化数据比如一整棵 AST 语法树Harness 的上下文分段机制会误判这个很大但很重要的内容为可以归档的废话直接把它挪到历史段里然后 Agent 就失去了对当前代码结构的理解。解法其实也不复杂。在插件层面做上下文预算Context Budget——每次往上下文里写东西之前先估算一下这玩意占多少 token如果超过预算就换个方式存比如写到本地文件或者用外部存储只在上下文里留一个指针。Harness 的插件 API 里有个context.set_budget()接口但说实话文档写得不够清楚我翻了好几次源码才搞明白怎么用。再说断点续传Checkpoint Resume。这个坑比上下文溢出更隐蔽——因为你不跑到那个时间点根本不知道它会炸。我做过一个实验让 Harness 跑一个需要处理 500 个文件的代码迁移任务。前 300 个文件顺顺利利第 301 个文件是个 2 万行的巨型类——Agent 读完它之后上下文直接爆了任务卡死。问题是 Harness 没有自动 checkpoint 机制之前的 300 个文件全白做了。你可能会想那手动加 checkpoint 不就行了 对可以但得你自己写。Harness 的StateManager插件接口提供了save_state()和load_state()支持把中间状态持久化到磁盘或者 Redis。但问题是它只存状态不存产物——也就是说你可以让 Agent 记住我处理到第 300 个文件了但前 300 个文件的修改结果如果 Agent 没有主动提交还是丢了。我现在的做法是在每个长任务里加一个心跳插件Heartbeat Plugin每处理完 N 个文件就自动 commit 一次修改同时把进度写到一个本地 JSON 文件里。这样就算任务崩了我至少知道上次做到哪了重跑的时候从断点接上就行。代码大概长这样class HeartbeatPlugin: def on_task_iteration(self, ctx): counter ctx.state.get(file_counter, 0) if counter 0 and counter % 50 0: ctx.git_commit(fauto checkpoint: processed {counter} files) ctx.state.save({file_counter: counter, last_file: ctx.current_file})这玩意儿不复杂但没它真不行。最后说状态爆炸State Explosion。这个坑跟前面两个不太一样——它是渐进式死亡。长任务跑着跑着Agent 的中间状态文件会越来越大。一开始可能只有几百 KB但十几个小时后能膨胀到几百 MB。我见过一个跑了两天的任务光是状态文件就占了 1.2 GB。然后磁盘满了Harness 写不了状态任务崩了——而且因为没有 checkpoint连崩在哪都不知道。Harness 的状态存储默认是全量快照模式——每次 save_state() 都把所有状态序列化一次。这在小任务里没问题但长任务里就是灾难。解决方案是增量快照Incremental Snapshot——只存变化的部分不存全量。可惜 Harness 核心层没有内置这个能力得自己在外层包装。说实话这些问题并不是 Harness 独有的。任何 Agent 框架到了长任务场景都得面对它们。Claude Code 的做法是主动限制单次会话长度超过就建议你开新会话Codex 则依赖 OpenAI 的后端自动管理。Harness 的哲学是给你工具你自己管——这种自由度的代价就是你得自己踩坑。你觉得长任务场景的这些问题应该由框架层来解决还是开发者自己兜底欢迎在评论区聊聊你的看法和经验。