AI编程下半场:长时序任务如何成为关键拐点
发布时间:2026/9/6 5:36:14 锦皓数字建站

自从 AI 编程助手大规模普及以来开发者之间一直存在两种截然不同的声音一边是“AI 写代码真香”一边是“AI 只能写玩具项目一上复杂工程就废”。这两种声音其实都对只是各自描述的是 AI 编程能力的不同阶段。最近在技术社区里流传的一句话点破了这个关键变化“The big improvement is on coding and especially long-horizon tasks. Explicitly trained on it actually works.”翻译过来就是这次最大的改进集中在代码生成上尤其是长时序long-horizon任务。而且这个能力不是顺带优化的是模型被显式训练出来的。如果你一直在关注 AI 编程工具大概能感受到 2024 下半年到 2025 年这段时间各家模型和 Agent 产品都在往同一个方向卷不是谁能生成单段代码更漂亮而是谁能把一个横跨多文件、多步骤、多轮修改的工程任务完整跑下来。这篇文章想聊的正是这件事long-horizon 到底是什么为什么它才是 AI 编程的关键拐点以及作为普通开发者我们应该如何调整使用 AI 编程工具的方式。先给出我的核心判断AI 编程的下半场拼的不是单点代码生成质量而是长时序任务的完成率和稳定性。谁能在多文件、多步骤、多轮迭代的真实工程场景中跑通谁才是真正可用的生产力工具。下面我会从概念、技术演进、工具链变化和实操验证四个维度展开。1. 为什么 long-horizon 是 AI 编程的关键拐点先说一个很多开发者都经历过的场景。你用 AI 助手生成一个 Python 函数它写得又快又好类型注解齐全注释规范。你满意地点点头接着让它“把这个函数接入现有的 Web 服务”它开始给出修改建议。等你再让它“顺便把相关测试补上再更新一下接口文档”它开始表现得像失去了上下文一样——要么重复修改已经改过的文件要么忽略你之前关于某些模块不能动的叮嘱要么做到第三步就忘了最初的需求。这不是你的问题也不是提示词写得不够好而是模型的上下文处理和任务规划能力确实存在上限。单步代码生成只需要模型理解当前这段代码的语义但长时序任务要求模型在一连串操作中保持目标一致性、状态追踪能力和自我纠错能力。这两者难度完全不是一个量级。long-horizon 任务在 AI 编程语境下指的是跨越多个文件、多个步骤、多轮交互才能完成的工程任务。举个直观的例子短任务写一个计算斐波那契数列的函数。长任务为一个已有 3 万行代码的电商后端新增一个优惠券核销接口要求遵循项目现有的分层架构、异常处理规范、日志规范补充单元测试和集成测试并更新 OpenAPI 文档最后跑通全部回归测试。后者的难点在于模型需要先理解现有项目的结构记住你制定的约束在多轮修改中不偏离目标还要能在出现错误时准确定位是哪个环节引入的。这已经不是“会不会写代码”的问题而是“能不能像一个中级工程师那样推进任务”的问题。所以当官方强调“explicitly trained on it”时真正值得关注的信息是模型厂商开始把长任务能力当作一个独立的训练目标来处理而不是指望模型在通用训练中“顺便学会”。这说明长时序任务已经被认定为核心能力指标而不是附属品。2. Coding Plan、Spec-driven 与 Vibe Coding热词背后的技术脉络如果你最近常逛技术社区肯定被几个热词刷过屏vibe coding、coding plan、spec-driven、AI coding 笔试。这些概念看起来眼花缭乱其实是 AI 编程工具在发展过程中不同阶段的产物而且它们都指向同一个深水区——长时序任务的落地方式。2.1 Vibe Coding长时序任务的第一个阶段Vibe coding 指的是开发者用极其口语化的自然语言描述需求让 AI 直接生成代码开发者则处于一种“跟着感觉走”的状态。这种方式的极致体验是你甚至不太需要看懂代码只要不断给 AI 反馈它就能帮你把应用搭出来。Vibe coding 在短任务场景下体验非常好。做一个原型、写一个脚本、生成一个组件效率提升是肉眼可见的。但一旦任务变长问题就出现了AI 会渐渐“忘记”前面做过什么决定同一段逻辑可能被重复实现两遍项目结构越改越混乱某个依赖版本升级后连带修改的代码没有被完整更新。这是因为 vibe coding 本质上缺少一个结构化的任务约束机制——它把长任务的稳定性寄托在模型的临场发挥上。2.2 Coding Plan让 AI 先想清楚再做Coding Plan 的概念由此而来。它的核心思路是在执行编码任务之前先让 AI 生成一份清晰的实施计划——包括文件变更清单、依赖关系、实现顺序、风险点——然后再按计划逐步执行。这个思路的本质是把 long-horizon 任务的不可控性通过“先规划后执行”的方式降下来。你可以把 Coding Plan 理解为给 AI 加了一层“结构化思考”的流程它不再是想到哪写到哪而是先理解全局再拆解步骤最后逐步落实。从开发者体验来看Coding Plan 的最大变化是你可以在 AI 动代码之前先审查它的计划及时纠偏。这比让 AI 直接改完代码再去 review 要省事得多也安全得多。2.3 Spec-driven把需求固化下来Spec-driven 则是更进一步的做法。它在编码开始之前先明确写出规格说明specification包括功能行为、输入输出、边界条件、业务流程。AI 和开发者的所有后续工作都以这份 spec 为准绳。Spec-driven 和 vibe coding 正好是两种相反的哲学vibe coding 追求“边做边想”spec-driven 追求“先想清楚再做”。在 long-horizon 任务中spec-driven 明显更可靠因为它为长任务提供了“不变锚点”——无论中间经过多少轮修改最终的验收标准始终是那份 spec而不是模型对需求的模糊记忆。从技术脉络来看这三种方式其实对应着 AI 编程工具逐步解决 long-horizon 任务的三层递进vibe coding 验证了 AI 的代码生成能力coding plan 解决了任务的组织问题spec-driven 解决了目标的稳定性问题。理解了这条脉络再看各家的 Coding Plan 功能就不容易迷路了。3. 为什么“显式训练”如此重要回到项目标题中那句“Explicitly trained on it actually works”。这句话透露的信息密度其实很高。它意味着 long-horizon 能力的提升不是靠堆参数、扩上下文窗口这种“硬件式”改进而是来自训练策略的调整。为什么这个区分很重要因为过去我们看到的很多长任务失败不是模型“不知道怎么做”而是它在执行过程中“忘了该怎么做”。也就是说模型的能力是够的但在长链条任务中无法稳定保持方向。这类似于一个能力很强的工程师如果没有人给他任务清单他在忙乱中也会漏掉步骤。显式训练的思路就是在训练阶段就构造大量长链条任务样本让模型学会在长上下文中维持目标一致性、在多步操作中追踪状态、以及在偏离方向时自我修正。这种能力一旦被“训练进去”就不再依赖运气或巧合而是成为一种稳定的模型行为。对普通开发者来说这意味着两件事你不需要再小心翼翼地拆解任务了。过去为了不让 AI 跑偏我们习惯把一个大任务拆成十几个小提示词逐条发送。现在模型本身对长任务的承接能力变强了你可以更自然地把完整需求描述给它让它自己规划执行。Agent 类工具的可信度提高了。以前 Agent 跑长任务经常“烂尾”一个重要原因就是模型不具备长时序稳定性。现在如果模型在训练层面就被强化了这项能力Agent 在真实项目中的完成率也会同步提升。当然这不是说模型已经完美解决长任务了。它只是意味着我们正在从“模型只会写代码片段”走向“模型能推进工程任务”的阶段。4. 如何设计一个 Long-horizon 任务来验证 AI 编程能力如果你想知道当前使用的 AI 编程工具到底行不行最好的办法不是看宣传而是亲手设计一个长时序任务来测试。下面我给出一个可以在本地完成的最小验证方案。4.1 任务设计原则一个好的 long-horizon 测试任务至少要包含以下特征涉及多个文件的创建或修改。包含顺序依赖任务 B 的正确性依赖任务 A 的输出。要求遵循某种既有约束比如命名规范、目录结构、认证方式。包含验证环节跑测试、检查输出、修正错误。最好有一个中途变更需求测试工具的应对能力。满足这五个条件才算是一个有区分度的 long-horizon 任务。4.2 示例任务描述下面这个任务可以在任何支持多文件编辑的 AI 编程工具中测试。我以一个简单的 Python 项目为例。任务描述 在项目 /tmp/demo_service 中完成以下需求 1. 项目目前是一个 FastAPI 应用端口为 8000入口文件是 main.py。 2. 请新增一个用户积分模块包含以下接口 - POST /api/users/{user_id}/points 增加积分 - GET /api/users/{user_id}/points 查询积分 3. 积分数据存储在 SQLite 数据库中使用 SQLAlchemy 统一管理数据库文件在 data/app.db。 4. 所有接口必须通过 verify_token 中间件进行身份校验该中间件已在 main.py 中实现。 5. 积分变更记录需要写入积分流水表流水表包含用户ID、变更值、原因、创建时间。 6. 请为积分模块编写 pytest 单元测试使用内存数据库不依赖真实文件。 7. 修改完成后运行全部测试确保原有测试也被正常执行。 额外约束 - 新代码遵循项目现有的模块划分方式不把所有代码堆在一个文件里。 - 日志使用项目已有的 logger 配置不要另起炉灶。 - 如果现有项目结构有无法兼容的情况先说明不要强行修改。注意这个任务描述里包含了路径、约束、验证条件和可能冲突点。一个能承载 long-horizon 任务的模型应该能做到先扫描项目现有结构理解 main.py 和依赖配置。生成合理的模块文件拆分方案。在实现接口时复用现有的 token 校验中间件。测试使用内存数据库而非真实文件。最后执行 pytest 并反馈结果。如果你的 AI 工具在这个任务中表现出“只写代码不跑测试”“忽略既有约束”“只改一个文件就宣称完成”那说明它离真正的 long-horizon 支持还有距离。5. 一个简化版 Long-horizon 任务代码示例为了让文章不只是概念讨论下面给出一个简化版的完整示例演示 long-horizon 任务中的三个关键能力多文件协作、状态追踪和顺序依赖。5.1 项目结构demo_service/ ├── main.py ├── models.py ├── database.py └── tests/ └── test_points.py这是一个最小的 FastAPI 积分服务我们围绕它演示任务拆分和代码实现。5.2 数据库连接配置# 文件路径demo_service/database.py from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, declarative_base # 使用 SQLite 作为演示数据库 SQLALCHEMY_DATABASE_URL sqlite:///./data/app.db engine create_engine( SQLALCHEMY_DATABASE_URL, connect_args{check_same_thread: False} ) SessionLocal sessionmaker(autocommitFalse, autoflushFalse, bindengine) Base declarative_base()5.3 模型定义# 文件路径demo_service/models.py from sqlalchemy import Column, Integer, String, DateTime from datetime import datetime from .database import Base class UserPoints(Base): 用户当前积分 __tablename__ user_points user_id Column(String(64), primary_keyTrue, indexTrue) points Column(Integer, default0) updated_at Column(DateTime, defaultdatetime.utcnow) class PointsLog(Base): 积分流水 __tablename__ points_log id Column(Integer, primary_keyTrue, autoincrementTrue) user_id Column(String(64), indexTrue) change_value Column(Integer) reason Column(String(255)) created_at Column(DateTime, defaultdatetime.utcnow)5.4 接口实现# 文件路径demo_service/main.py from fastapi import FastAPI, Depends, HTTPException from sqlalchemy.orm import Session from .database import Base, engine, SessionLocal from .models import UserPoints, PointsLog Base.metadata.create_all(bindengine) app FastAPI() def get_db(): db SessionLocal() try: yield db finally: db.close() def verify_token(username: str default_user): # 演示用中间件实际项目请接入真实的认证体系 return username app.get(/api/users/{user_id}/points) def get_points(user_id: str, db: Session Depends(get_db)): record db.query(UserPoints).filter(UserPoints.user_id user_id).first() if not record: return {user_id: user_id, points: 0} return {user_id: user_id, points: record.points} app.post(/api/users/{user_id}/points) def add_points( user_id: str, change_value: int, reason: str, db: Session Depends(get_db) ): record db.query(UserPoints).filter(UserPoints.user_id user_id).first() if not record: record UserPoints(user_iduser_id, points0) db.add(record) record.points change_value log PointsLog( user_iduser_id, change_valuechange_value, reasonreason ) db.add(log) db.commit() db.refresh(record) return {user_id: user_id, points: record.points}5.5 单元测试# 文件路径demo_service/tests/test_points.py import pytest from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.pool import StaticPool from ..database import Base from ..models import UserPoints, PointsLog pytest.fixture def db_session(): 使用内存数据库避免依赖真实文件 engine create_engine( sqlite://, connect_args{check_same_thread: False}, poolclassStaticPool, ) Base.metadata.create_all(bindengine) TestingSessionLocal sessionmaker(bindengine) session TestingSessionLocal() try: yield session finally: session.close() def test_add_points(db_session): record UserPoints(user_idu_001, points100) db_session.add(record) db_session.commit() record.points 50 db_session.commit() db_session.refresh(record) assert record.points 150 def test_points_log_created(db_session): log PointsLog(user_idu_001, change_value50, reasonlogin_bonus) db_session.add(log) db_session.commit() query db_session.query(PointsLog).filter_by(user_idu_001).first() assert query is not None assert query.change_value 50 assert query.reason login_bonus5.6 运行验证# 在项目根目录执行 pip install fastapi uvicorn sqlalchemy pytest # 启动服务 uvicorn main:app --reload --port 8000 # 新增积分第一次给 u_001 增加 100 分 curl -X POST http://127.0.0.1:8000/api/users/u_001/points?change_value100reasonregister_bonus # 查询积分 curl http://127.0.0.1:8000/api/users/u_001/points # 运行测试 pytest tests/ -v预期输出POST 返回{user_id: u_001, points: 100} GET 返回{user_id: u_001, points: 100} pytest 显示2 passed这个示例本身并不复杂但它覆盖了 long-horizon 任务的核心环节建表、模型关联、接口实现、测试隔离、运行验证。你可以把这个任务丢给任何 AI 编程工具观察它如何拆解这些步骤。6. 在真实项目中应用 Long-horizon AI 编程的协作方式如果模型的长时序能力已经有明显提升那么开发者的工作方式也需要跟着调整。过去那种“一步一催”的用法会严重浪费模型的长任务能力。6.1 从“逐步指挥”到“目标描述”过去使用 AI 编程助手的典型姿势第一步帮我写一个 user_points 表 第二步帮我写一个查询接口 第三步帮我写一个新增积分接口 第四步帮我写测试这种用法虽然稳但效率低而且每次切换上下文都可能丢失信息。在支持 long-horizon 的模型中更推荐的做法是请为项目新增用户积分模块包含查询和新增两个接口。 要求使用 FastAPI SQLAlchemy数据存 SQLite 遵循项目现有的分层结构和 token 校验方式 新增积分时写流水表 编写 pytest 测试并用内存库运行 完成后跑一遍全部测试确认不破坏现有功能。一次性把目标、约束、验收标准说清楚让模型自己规划文件拆分和实现顺序。你会发现输出质量和完成效率反而更高。6.2 从“接受结果”到“审查计划”long-horizon 能力越强的工具越应该重视计划审查环节。在 AI 开始动代码之前先让它输出执行计划你确认无误后再让它开始。这个步骤在 Coding Plan 类功能中已经是标配。计划审查时重点关注三件事文件拆分是否合理是否贴合项目现有结构。依赖关系是否清晰有没有先实现底层再实现接口的顺序感。风险点是否被识别比如需要修改公共模块、需要改数据库表结构。6.3 从“人工排错”到“AI 自检”长任务最容易在细节上翻车比如漏改某个引用、忘记迁移数据库字段、测试隔离不彻底。好的 AI 编程工具应该在执行完任务后主动跑测试、检查 lint、确认无遗漏。如果工具没有自动做这些你应该在任务描述里显式要求完成实现后请执行 1. python -m pytest tests/ -v 2. python -m flake8 3. 检查是否所有新文件都有对应测试把验证步骤写进任务约束里是提高长任务完成率的有效手段。7. 常见问题与排查建议围绕 long-horizon AI 编程开发者最常遇到的问题有以下几类。我把它们整理成表格方便排查时直接对照。问题现象可能原因排查思路解决建议AI 生成到一半开始偏离原始需求模型上下文过长导致“忘记”早期约束检查任务描述中是否明确列出约束条件观察 AI 是否频繁重复确认需求将核心约束写在任务描述的开头和结尾各一次使用 Coding Plan 类功能先确认执行计划明明要求不改公共模块AI 还是改了只有口头约束没有结构化禁止项查看 AI 的执行计划中是否包含公共模块修改在任务描述中增加“禁止修改以下文件”清单并明确要求 AI 执行前先列出所有拟修改文件多文件任务完成后测试大量失败各模块之间接口约定不一致查看测试失败日志确认是类型不匹配还是导入路径问题要求 AI 在实现前先输出数据结构和接口签名执行顺序上先固定接口契约再实现业务逻辑AI 生成了代码但不执行验证步骤任务描述中未包含验证要求检查任务描述的约束部分是否包含“运行测试”在任务末尾明确要求“完成后运行 pytest并根据失败结果修复循环直到通过”长任务中途出现重复实现同一个功能写了两次模型状态追踪能力不足不记得前面的文件已包含该逻辑查看生成文件列表是否存在两个职责相似的模块在任务约束中要求“先扫描现有代码复用已有函数不得重复实现”如果支持观察执行过程日志使用 SQLite 测试时污染了真实开发库测试环境未做隔离检查测试代码中是否引用了真实数据库 URL测试统一使用内存数据库或独立测试库在任务描述中明确“测试不得连接 data/app.db”8. 最佳实践与工程建议8.1 任务描述要“约束前置”Long-horizon 任务成功率的第一个决定因素是任务描述的完整度。不要把约束散落在对话的不同轮次里而是集中放在任务描述的开头让模型在加载任务时就能看到全部约束。推荐的模板目标[一句话说清楚要做什么] 技术栈[列出项目使用的框架、语言版本、依赖管理方式] 已有约束 - 必须遵循现有的模块划分方式 - 不得修改 xxx 文件 - 认证统一走 xxx 中间件 - 日志使用 xxx 配置 验收标准 - 所有新接口有对应单元测试 - pytest 全部通过 - 不引入新的第三方依赖如确需引入先说明理由8.2 要求 AI 先输出执行计划无论工具是否自带 Coding Plan 功能你都应该在任务中要求 AI 先列出计划再开始实现。计划至少应包含拟创建和修改的文件清单。模块的实现顺序。验证方式。这一步的成本极低但对任务成功率提升非常明显。相当于在长跑前先看一遍路线图。8.3 验证自动化和失败循环Long-horizon 任务的完成标准不是“代码写完”而是“测试跑通”。在任务描述里加入自动验证循环能显著提高质量完成实现后执行 pytest tests/ -v。 如果测试未全部通过分析失败原因修复代码后重新运行。 重复直到全部通过然后汇报最终结果。这个“修复循环”要求会让 AI 在交卷前自己完成多轮调试而不是把调试工作留给你。8.4 安全边界与权限控制当 AI 编程工具拥有写文件、执行命令、修改数据库的能力时安全边界必须提前设定不要在未备份的情况下运行 AI 建议的数据库迁移命令。长任务中如果涉及数据库结构变更务必先备份或在独立分支验证。限制 AI 的文件操作范围。在大型项目中建议通过工具的工作区配置将 AI 限制在特定目录内。敏感信息不进对话。数据库密码、云厂商密钥、内网地址等不允许出现在任务描述中。生产环境的变更必须走代码评审。即使 AI 写得再快发布到生产前也需要人工 review CI 灰度流程。8.5 为团队定义 AI 编程规范如果团队开始在日常开发中使用 AI 编程工具建议尽快定义团队级别的规范内容包括哪些任务允许直接交给 AI 完成哪些必须人工主导。AI 生成代码的统一 review 清单。禁止 AI 执行的命令白名单/黑名单。Long-horizon 任务完成后的验证步骤。这样做的好处是AI 的使用不会变成“个别开发者的激进实验”而是变成有共识、有边界的工程实践。9. 总结与后续学习方向Long-horizon 任务正在成为衡量 AI 编程能力的核心指标这个判断从模型厂商的训练方向、Agent 产品的功能演进、以及社区热词的迁移都能得到印证。从 vibe coding 的随性而为到 coding plan 的谋定后动再到 spec-driven 的规格先行AI 编程工具正在把“长任务的稳定性”当作第一优先级来解决。对普通开发者来说最值得做的三件事是第一重新设计你的任务描述方式把约束和验收标准前置不要再用“碎催”式交互第二学会让 AI 输出执行计划并人工审查把大方向把握在自己手里第三建立自动验证循环把长任务的最终验收锚定在测试结果上。接下来的学习方向建议关注三个重点Coding Plan 的提示词设计学习如何在任务中嵌入计划生成和计划审查环节。Spec-driven 开发方法试着在个人项目中把需求先写成规格文档再让 AI 基于规格实现。Agent 工具的权限控制和沙箱机制当 AI 具备越来越强的执行能力时安全使用这些能力会成为新的核心竞争力。AI 编程的浪潮已经过了“能不能写代码”的阶段正在进入“能不能扛事”的阶段。理解 long-horizon 的语言理解显式训练的意义你就能比大多数人更早用上 AI 编程的真正红利。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。