万字图文:Loop Engineering【附代码详解】

导读: 最近"Loop Engineering"这个词突然刷屏——Claude Code 负责人 Boris Cherny 说"我不再写 Prompt,我的工作是写 Loop";OpenClaw 作者说"你不该再亲自 prompt 你的 Agent,而该设计 Loop 来 prompt 它们"。小编第一次看到这两句话的时候……愣了一下。然后看了看自己手边那堆 .md 文件,感觉被人说中了。今天这篇,咱们把这件事从根上捋清楚:Loop Engineering 是怎么从 ReAct、Reflection 一路演化来的,和前三大工程(Prompt / Context / Harness)是什么关系,设计上要注意什么,以及——nanobot 的源码里,它到底长什么样。万字长文,建议收藏慢慢看


1.1 第一次进化:Prompt Engineering——学会"好好说话"

核心问题:怎么跟模型说话?

这是一切的起点。大家发现同样一个问题换一种问法,结果能差出十万八千里。于是工程师们开始花大量时间研究:怎么把那条 prompt 写好?

调措辞、加 few-shot 示例、用 Chain-of-Thought 引导推理……你懂的,那段时间"Prompt 炼丹师"这个称号挺流行的。

💡 一句话定义:Prompt Engineering 就是——学会用"AI 能听懂的语言"跟它好好说话。

但是吧,Prompt 写得再好,模型能回答你的东西,只限于它训练时学到的那些。你们公司的内部文档?昨天发生的新闻?它不知道。

这个坑,Prompt Engineering 填不了。


1.2 第二次进化:Context Engineering——决定 AI 该"看"什么

核心问题:给模型看什么信息?

所以工程师的注意力往外移了一格:不只是"怎么问",而是"让它看到什么信息再问"。

给 Agent 的上下文窗口里,放什么?系统指令、工具定义、对话历史、RAG 检索结果、外部文档……这些东西怎么组织、什么时候放什么——这就是 Context Engineering 在做的事。

💡 一句话定义:Context Engineering 就是——给 AI 配一个"信息策展人",它推理之前,先替它把该看的摆好,不该看的拿走。

小编当时觉得,搞定这个之后 Agent 应该挺靠谱了。

然后它去删了一个不该删的文件。

原来光管"看什么"不够,还得管"能做什么"。


1.3 第三次进化:Harness Engineering——给 Agent 搭"安全脚手架"

核心问题:给 Agent 搭什么样的运行环境?

Harness Engineering 干的事,就是给 Agent 建一套"工作规章":哪些工具能用、权限是什么、输出需不需要审查、什么情况下必须叫停……

💡 一句话定义:Harness Engineering 就是——不让 Agent 裸奔,给它套上安全带、戴上安全帽、划定施工范围。

打个总的比方:Prompt 是教它说话,Context 是配好它该看的资料,Harness 是给它发工牌、划权限、装护栏。

到这儿,一次 Agent 运行已经相当稳了。

但——“一次稳"和"持续稳”,差着一个数量级的工程量。


1.4 三大工程都没回答的六个问题

你看,三大工程覆盖了"单次运行的质量"——但只要你想让 Agent 自己持续跑起来,就会撞上一堆谁都没管过的问题:

问题三大工程能回答吗?
谁去发现有待办任务?❌ 都不管
上一轮Agent做到哪了? 下一轮怎么接着来?❌ 都不管
改代码的Agent 和验代码的Agent是同一个吗?❌ 都不管
出了问题什么时候必须让人来看?❌ 都不管
这套系统每天跑,会不会把token烧穿?❌ 都不管
任务完成了, 经验怎么保存下来给下一轮用?❌ 都不管

六个问题,六个 ❌。

这不是三大工程做得不好,是它们本来就没打算管这件事。就像你不能怪一把好锤子不能拧螺丝——它是锤子,它干的是锤子的活。

“Prompt、Context、Harness,解决的是’这一次跑好’。Loop Engineering 解决的是’一直跑、跑好、跑完知道经验,出问题不瞎跑’。”


二、思想根源:Loop 不是天上掉下来的,你以前就见过它

很多人把 Loop Engineering 当成 2026 年才冒出来的新概念。

小编深入了解了一下, 这不就是前几天写的三大经典范式的演进吗?一篇文章吃透:智能体构建的三大经典范式

还没看这篇文章的小伙伴可以先收藏起来再去学习~


2.1 起点:ReAct——把"思考"和"行动"编织成闭环

2022 年,《ReAct: Synergizing Reasoning and Acting in Language Models》这篇论文提了一个听起来很朴素、但影响很深远的想法:

让模型别一次性推理到底,而是边思考边行动——想一步、做一步、看一下结果、再想下一步。

💡 一句话定义:ReAct = Reasoning(推理)+ Acting(行动),两者交替循环,每次思考指导行动,每次观察修正思考——就是这么一个闭环。

传统方式:  Prompt → 模型一口气推理并输出答案(但看不到外界信息)ReAct 方式:  Thought(思考:我需要查一下天气)    → Action(行动:调用天气 API)      → Observation(观察:北京今天晴,25°C)        → Thought(再思考:可以推荐户外活动)          → Action(行动:生成出行建议)            → Observation(观察:输出完成)              → 最终答案

这和之前的 Chain-of-Thought(链式思维)有什么本质区别?

对比维度Chain-of-ThoughtReAct
是否与外界交互❌纯内部推理✅可以调工具、查数据
知识来源只能用模型内部知识可以实时获取外部信息
出错了怎么办只能靠模型自己修正观察到错误可以重新思考
类比闭卷考试开卷考试+可以查资料

ReAct 第一次把"思考"和"行动"编织成了一个可以持续迭代的闭环

就这一件事——今天所有 Agent Loop 都从这里来的。


2.2 升级版:Reflection——让 Loop 有"记忆"和"自我反思"

ReAct 很好,但有个致命弱点:它不记事

上一轮试了某个方法、失败了——下一轮重新来,LLM 不知道自己之前踩过这个坑,大概率还会踩一遍。

就像一个每天上班都当第一天的同事——能干活,但经验永远存不住。

2023 年前后,研究者在 ReAct 基础上提出了 Reflection(反思) 设计模式,专门解决这个问题:

💡 一句话定义:Reflection = 失败了别直接重试,先复盘"这次为什么没成",把结论写进记忆,下轮带着经验来。

具体流程:

【普通 ReAct】  失败 → 直接重试(带着同样的错误)【Reflection 加持的 ReAct】  失败    → 触发反思:"这次为什么没成?"      → 生成改进建议:"下次应该先检查权限再调 API"        → 写入长期记忆(Memory Store)          → 下一轮开始时,先读取失败经验            → 基于经验做出更好的决策

这就是为什么 Loop Engineering 特别强调"Memory / State"层——没有记忆的 Loop,每一次都是全新的开始,错了白错。有了记忆,Loop 才有复利效应。每轮迭代都比上轮聪明一点点。

没有记忆的 Loop,是西西弗斯。有了记忆,才是复利机器。


2.3 完整的演化链:从 CoT 到 Loop Engineering

把这条演化链整个摊出来看,Loop Engineering 的根基早就有了,只是工程界最近才把它系统化、起了个新名字:

“ReAct 告诉我们 Agent 应该怎么思考和行动;Reflection 告诉我们怎么让 Agent 越跑越聪明;Loop Engineering 告诉我们怎么让这一切自动化、可控化、可审计地规模运转。”


三、Loop Engineering 全景:一个完整的循环系统长什么样?


3.1 先说一个特别容易混的区别:Agent Loop ≠ Loop Engineering

小编见过太多人把这俩混为一谈了——以为在终端里敲 /loop 1d 就算"做了 Loop Engineering"。

就好像以为买了辆车、会发动就叫"懂汽车工程"。

不是的。

维度Agent LoopLoop Engineering
本质运行机制, 一个功能系统设计方法论
在做什么启动一个会重复的Agent 任务设计发现->执行-> 验证->交接的完整系统
粒度一条命令,一次递归目标六大构件 + 状态 Schema + 安全策略 + 成本模型
成功标准“它又在跑了”“跑的对、跑的省、出事能停、人能看懂它干了什么”
典型产物/loop 1d 检查CI 一条命令STATE.md + Skills + Worktree策略 + Verifier
风险可能空转、重复犯错、烧token设计得当,放大产能 设计不当,放大错误

用代码对比最直观:

# Agent Loop 是这个:while not done:    agent.run()# Loop Engineering 是设计整个 main():def main():    task = discover_task()          # 谁发现任务?怎么发现?    state = load_state()            # 上轮做到哪了?    env = setup_worktree(task)      # 隔离环境    result = maker.run(task, state) # 执行者    verdict = checker.verify(result)# 独立验证者(不是执行者自己)    if verdict.risk > threshold:        escalate_to_human()         # 人工闸门    save_state(result, verdict)     # 持久化经验    update_budget(tokens_used)      # 成本管控

3.2 六大构件:真正能"无人值守"的 Loop,需要这六样东西

Addy Osmani 和 Cobus Greyling 的开源参考库把一个成熟的 Loop 拆解为六个核心构件 + 一层记忆。

小编照单全收,逐一给你解释:

逐一解释一下关键构件:

① Automations / Scheduling(心跳调度)

这是 Loop 的"心跳"。没有调度,Loop 就是一个被动等待命令的工具。有了调度,Loop 就变成了一个主动发现任务、自动分诊的系统。

常见模式:Daily Triage(每日分诊)、PR Babysitter(监控 PR 状态)、CI Sweeper(扫 CI 失败)……

② Worktrees(隔离环境)——并行任务的"防撞墙"

如果两个 Agent 同时修改同一个文件,会发生什么?

不用猜,小编见过——一个 Agent 刚写好测试,另一个在它不知情的情况下动了同一个函数,merge 的时候两边工作互相覆盖,谁也没有"赢"。

Worktrees 的作用就是给每个 Agent 任务开一个独立的文件工作区——就像 git worktree 那样,同一份代码在磁盘上有多个并行的"分身",互不干扰,做完再合并。

💡 一句话定义:Worktrees 就是给每个 Agent 分一个独立操作间——彼此干活,互不串场,出了问题也知道找谁。

③ Skills(项目知识库)——别让 Agent 每次都当新人

这个构件,是小编觉得最容易被忽视、但忽视了最容易踩坑的一个。

每一轮 Loop,Agent 都是"冷启动"——它不知道你们团队有什么不成文的规矩、哪个目录是祖传代码别乱动、部署要走什么流程……这些在你脑子里"理所当然"的事,对 Agent 来说全是未知数。

如果不写进 Skills 或 AGENTS.md,它每轮都在重新猜——或者悄悄猜错了你也不知道。

这个隐性成本有个专业叫法:Intent Debt(意图债)。Skills 就是在还这笔债。

④ Plugins & Connectors(MCP 连接器)——打通外部世界

一个只能在沙箱里跑的 Loop,能做的事非常有限。

想让 Agent 真正介入你的工作流——拉 GitHub PR 数据、在 Linear 创建任务、发 Slack 通知、查生产数据库——就需要 Plugins & Connectors 这层。

好消息是,现在有了统一标准:MCP(Model Context Protocol)。各工具按 MCP 协议暴露接口,Loop 就可以像插 U 盘一样,即插即用地接入任何支持的外部系统。

💡 一句话定义:Plugins & Connectors 是 Loop 的"对外接口"——没有它,Agent 只是在自己的小黑屋里自言自语;有了它,才能真正操作你的工作流。

⑤ Sub-agents 分工:Maker/Checker 分离

💡 一句话定义:写代码的 Agent(Maker)和验证代码的 Agent(Checker)必须是不同的 Agent,禁止自评。

就像代码 review 不能自己 review 自己一样——写这段代码的人,最容易对它的 bug 视而不见。Checker 必须独立,甚至不能共享 context。

⑥ Human Gate(人工闸门)

Loop Engineering 不是要完全消灭人的参与,而是让人在对的时机介入

高风险操作(自动合并代码、删数据库、发消息给客户)必须暂停、等待人工审核。这不是效率的倒退,是安全的保障。


3.3 三笔"债":Loop 跑起来之后,这三个坑等着你

cobusgreyling/loop-engineering 这个参考库里,有三个警告反复出现。

第一笔:Intent Debt(意图债)

就是刚才说的——你的团队规范没写进 Skills,Agent 每轮都在猜,猜错了你还不知道。这笔债每轮都在滚,不还就越欠越多。

第二笔:Comprehension Debt(理解债)

Loop 越快,仓库里"你没认真读过"的代码越多。Agent 提交了,你合并了——但你真的理解那段代码吗?

Loop 交付了,不代表你理解了。

时间一长,代码库对你来说越来越像黑盒。有一天出问题了,你发现自己根本不知道该从哪开始排查。

第三笔:Cognitive Surrender(认知投降)

这是最危险的一笔,也是最难察觉的。

就是把 Loop 当成了"不需要动脑子"的按钮。

“Build the loop. But build it like someone who intends to stay the engineer, not just the person who presses go.”

同一套 Loop,放在真工程师手里是放大器,放在只会按 Go 的人手里是放大灾难的工具。区别就在:你有没有把自己的判断力编码进 Skills 和 Verifier,还是只是甩手给 Agent 了事。

怎么样,是不是似曾相识。 想一下是不是踩坑的人就是你~


3.4 分阶段上线:第一周就冲 L3?劝你别

第一周就无人值守 = 找麻烦。小编的建议是分三步走,别急:

L1:只看报告,不行动  → Agent 分析情况,生成结构化报告  → 人来做决策  → 目标:建立信任感,观察 Agent 的判断是否准确L2:小步自动修复 + 独立 Verifier 验证  → Agent 处理低风险操作(小 bug 修复、文档更新)  → 独立的 Checker Agent 验证结果  → 高风险操作升级给人  → 目标:积累 Loop 运行数据,发现盲区L3:无人值守运行  → 完整的护栏到位:denylist + token budget + 可观测性  → 多 Loop 协调机制  → 定期人工审计 Loop 的输出质量  → 目标:真正的自动化复利

一个判断什么时候可以升级到下一级的简单标准:L1 运行两周,对 Agent 的每一条报告,你都觉得"判断对了"——才考虑升 L2。


四、nanobot 源码深度解析:Loop Engineering 的真实工程样本

聊了这么多理论,小编猜你已经跃跃欲试想看真实代码了——不然怎么有人把 Loop Engineering 真的造出来呢?

小编最近研究的是 OpenClaw 生态里的 nanobot 项目。读完它的 runner.py(1500+ 行)之后,小编脑子里只冒出一句话:

这不是"一个 while 循环",这是一台精密设计的机器。

nanobot 的核心是三层嵌套循环,像俄罗斯套娃一样:

第一层:消息总线循环       ← 一直在转,监听新消息,不堵塞  └─ 第二层:状态机循环    ← 每条消息走完一套 8 状态流程       └─ 第三层:工具迭代循环  ← LLM + 工具来回跑(最核心)

咱们从外往里,一层一层拆开来看。


4.1 第一层:不堵塞的消息监听

文件: nanobot/agent/loop.py

这一层解决的是:怎么让 Agent 一直在"等消息",但又不被等消息这件事本身卡住?

# loop.py 第 867-900 行async def run(self) -> None:    """Agent 主循环:一直监听新消息"""    self._running = True    await self._connect_mcp()   # 先连接 MCP 工具服务    while self._running:        # 外层死循环,不停转        try:            # 带 1 秒超时的等待——超时了继续循环,而不是死等            # 🔑 关键设计:为什么是 1 秒?            # 利用等消息的空闲时间,顺手做会话压缩检查            msg = await asyncio.wait_for(                self.bus.consume_inbound(), timeout=1.0            )        except asyncio.TimeoutError:            # 没消息来?没关系,趁机检查有没有需要压缩的老会话            self.auto_compact.check_expired(...)            continue   # 回到循环头继续等        # 来消息了!创建新任务处理它(不阻塞!不等它跑完)        # 自己继续盯着消息总线,保证下一条消息不会被延误        task = asyncio.create_task(self._dispatch(msg))

这里有两个设计细节值得单独讲:

细节 1:timeout=1.0 的"见缝插针"设计

不是死等消息,每隔 1 秒主动检查一次:有没有会话需要压缩?

就像你在等外卖的空档,顺手清了一下桌子——空闲时间一点不浪费。

细节 2:asyncio.create_task 的非阻塞分发

来了消息,不是"处理完再继续监听",而是把处理任务扔到后台,自己继续盯消息总线。

类比:一个靠谱的前台接待——有客人来了,不是自己去带他参观公司(这会让后面的客人等),而是叫来对应的人去接待,自己继续守在前台。


4.2 第二层:状态机——不乱套的处理流程

来了消息,不是直接调 LLM,而是先走一个状态机(State Machine)

什么是状态机?小编用地铁进站来类比:刷卡 → 闸机开 → 进站区 → 等车区 → 上车——每一步有前置条件,不能反着走,不能跳过。状态机就是给处理流程的每一步起了个名字,规定好"走完这步之后去哪"。

nanobot 把处理一条消息(一个 turn)拆成了 8 个状态:

# loop.py 第 80-88 行class TurnState(Enum):    RESTORE  = auto()  # 第1步:还原断点(上次中断的话,从哪恢复)    COMPACT  = auto()  # 第2步:检查会话是否需要压缩(省 token)    COMMAND  = auto()  # 第3步:是不是命令?(/help、/stop 等快捷命令)    BUILD    = auto()  # 第4步:组装发给 LLM 的 messages    RUN      = auto()  # 第5步:真正跑 LLM + 工具循环    SAVE     = auto()  # 第6步:把结果存到 session    RESPOND  = auto()  # 第7步:组装返回给用户的响应    DONE     = auto()  # 第8步:本轮结束

这 8 个状态通过一张"转移表"串起来:

# loop.py 第 171-180 行_TRANSITIONS = {    (TurnState.RESTORE,  "ok"):       TurnState.COMPACT,    (TurnState.COMPACT,  "ok"):       TurnState.COMMAND,    (TurnState.COMMAND,  "dispatch"): TurnState.BUILD,   # 普通消息→继续正常流程    (TurnState.COMMAND,  "shortcut"): TurnState.DONE,    # 是命令→直接结束!    (TurnState.BUILD,    "ok"):       TurnState.RUN,    (TurnState.RUN,      "ok"):       TurnState.SAVE,    (TurnState.SAVE,     "ok"):       TurnState.RESPOND,    (TurnState.RESPOND,  "ok"):       TurnState.DONE,}

状态机驱动的主循环:

# loop.py 第 1274-1326 行async def _process_message(self, msg) -> OutboundMessage | None:    # 从 RESTORE 状态开始走    ctx = TurnContext(state=TurnState.RESTORE, ...)    while ctx.state is not TurnState.DONE:    # ← 第二层循环        # 根据状态名,动态找到对应的处理函数        # 比如 state=BUILD,就调用 _state_build(ctx)        handler_name = f"_state_{ctx.state.name.lower()}"        handler = getattr(self, handler_name)        event = await handler(ctx)   # 执行,返回事件("ok" 或 "shortcut")        # 查转移表:(当前状态,事件)→ 下一个状态        next_state = self._TRANSITIONS.get((ctx.state, event))        ctx.state = next_state       # 状态切换

为什么这样设计,而不是一个大的 if-elif?

状态机的优势是:每个状态职责单一,互不干扰。出了问题很容易定位是哪个状态出的事。

举个具体例子:用户发了 /help,走到 COMMAND 状态时返回 "shortcut" 事件,查转移表发现直接跳到 DONE——根本不用走后面的 BUILDRUN 等步骤,效率拉满。


4.3 第三层:最核心的工具迭代循环

前两层更多是"调度和流程管理",这一层才是 nanobot 的心脏——也是 ReAct + Reflection 在生产代码里真正长出来的样子。

核心方法是 runner.py 里的 _run_core。小编把这段代码读了好几遍,每次都有新发现——不是因为代码多复杂,而是因为每一个 if 背后都是一个生产级的工程决策

# runner.py 第 323-668 行async def _run_core(self, spec: AgentRunSpec, messages: list) -> AgentRunResult:    """    核心迭代循环:LLM → 工具 → LLM → 工具 → ... → 最终答案    这里是 ReAct + Reflection 的工程实现。    """    final_content = None    empty_content_retries = 0   # 空响应重试计数(对应:LLM 偶尔抽风返回空)    length_recovery_count = 0   # 截断恢复计数(对应:输出 token 超限被截断)    # ═══════════════════════════════════════════════════    # 核心:最多跑 max_iterations 次    # 这里就是 ReAct 循环的工程实现    # ═══════════════════════════════════════════════════    for iteration in range(spec.max_iterations):        # ─── 每次循环前先"治理"上下文 ───        # 对应 Loop Engineering 的 Memory/State 层        messages = self._microcompact(messages)       # 压缩旧工具结果,省 token        messages = self._snip_history(spec, messages) # 超出上下文窗口就裁剪        # ─── 调用 LLM(ReAct 里的 Thought 步骤)───        response = await self._request_model(spec, messages)        # ══════════════════════════════════════════════        # 分支 A:LLM 说"我要调工具"(ReAct 里的 Action 步骤)        # ══════════════════════════════════════════════        if response.should_execute_tools:            # 把 LLM 的工具请求加入对话历史            messages.append(build_assistant_message(                response.content,                tool_calls=response.tool_calls,            ))            # 执行工具(可能是并发的!下面会专门讲)            results = await self._execute_tools(spec, response.tool_calls)            # 把工具结果加入历史(ReAct 里的 Observation 步骤)            for tool_call, result in zip(response.tool_calls, results):                messages.append({                    "role": "tool",                    "tool_call_id": tool_call.id,                    "name": tool_call.name,                    "content": result,   # 工具输出,喂给下一轮 LLM                })            continue   # ← 关键:工具跑完,回到循环头,LLM 再次思考        # ══════════════════════════════════════════════        # 分支 B:LLM 说"我有答案了"        # ══════════════════════════════════════════════        # 边缘情况 1:LLM 给了空响应(偶尔会发生)        if is_blank_text(response.content):            empty_content_retries += 1            if empty_content_retries < 2:   # 最多重试 2 次,不死等                continue            # 超过 2 次就认了,用空响应继续往下走        # 边缘情况 2:LLM 输出被截断(output token 超出限制)        if response.finish_reason == "length":            length_recovery_count += 1            if length_recovery_count <= 3:   # 最多续写 3 次                messages.append(build_length_recovery_message())                continue   # 告诉 LLM"你刚才被截断了,请继续"        # 正常结束!        final_content = response.content        break   # ← 退出 for 循环    else:        # ↑ 这是 Python 的 for-else 语法(很多人没见过)        # 含义:for 循环跑完了所有次数但没有 break,才执行 else        # 对应场景:LLM 一直要调工具,max_iterations 次都没给最终答案        # → 超时强制停止        stop_reason = "max_iterations"    return AgentRunResult(final_content=final_content, ...)

整个循环就两个核心分支:

LLM 要调工具 → 执行工具 → continue(再次调用 LLM,看还需要什么)LLM 给出答案 → break(结束循环,返回答案)

就这么简单。

但是——

for 循环里每一个 if,都是一个生产级的工程决策。

小编接下来单独讲三个最有意思的细节。


4.4 细节一:上下文治理——在循环里防止"撑死"

每次迭代开始之前,nanobot 会做两件"卫生工作"。

第一件:microcompact(微压缩)

把那些已经用过的旧工具结果,压缩成单行摘要。

# runner.py# 这些工具的旧结果,可以被压缩(用完就没什么信息量了)_COMPACTABLE_TOOLS = frozenset({    "read_file", "exec", "grep", "find_files",    "web_search", "web_fetch", "list_dir",})# 保留最近 10 个工具结果不压缩,更早的都压缩成单行摘要_MICROCOMPACT_KEEP_RECENT = 10# 小于 500 字符的结果不压缩(本来就不大,没必要)_MICROCOMPACT_MIN_CHARS = 500

用做笔记来类比:今天的会议详细记一遍,三周前的会议只留个结论要点。一本笔记本才能用很久,不会因为全是流水账而撑爆。

第二件:snip_history(历史裁剪)

当 prompt 的 token 估算超出上下文窗口,从历史头部开始裁剪:

# runner.py 第 1445-1518 行def _snip_history(self, spec, messages):    """token 超限时,从头裁剪历史,但 system 消息永远保留"""    estimate = estimate_prompt_tokens(messages)    if estimate <= budget:        return messages    # 没超,不动    # 从尾部往前贪心选择:保留尽量多的最近消息    kept = []    for message in reversed(non_system_messages):        if kept_tokens + msg_tokens > remaining_budget:            break   # 放不下了就停        kept.append(message)    kept.reverse()    return system_messages + kept   # system 消息永远保留(最重要的指令)

逻辑很直观:最近的消息最有用,最老的消息最先扔掉,但 system 指令永远不能丢。

两件事加在一起,nanobot 跑几十轮工具调用、上下文无限增长,也不会把自己"撑死"。

这就是 Loop Engineering 中"Memory / State 层"在代码里的体现——循环的记忆不是无限的,需要主动管理。


4.5 细节二:并发工具调度——能并行的绝不串行

当 LLM 一次请求多个工具,nanobot 不是一个一个慢慢跑,而是先分批:

可以并发的工具:同一批,用 asyncio.gather 并行执行
不能并发的工具:单独跑,等完再执行下一个

# runner.py 第 1520-1543 行def _partition_tool_batches(self, spec, tool_calls):    """把工具调用分成并发批次"""    batches = []    current_batch = []    for tool_call in tool_calls:        tool = get_tool(tool_call.name)        # 工具自己声明是否"并发安全"(concurrency_safe)        can_parallel = bool(tool and tool.concurrency_safe)        if can_parallel:            current_batch.append(tool_call)   # 加入当前并发批            continue        # 遇到不可并发的工具:        # 先提交之前的并发批        if current_batch:            batches.append(current_batch)            current_batch = []        # 自己单独一批        batches.append([tool_call])    if current_batch:        batches.append(current_batch)    return batches# 并发执行同一批工具if len(batch) > 1:    results = await asyncio.gather(*(        self._run_tool(spec, tc) for tc in batch    ))

举个具体例子:LLM 同时请求"查天气"、“查股价”、"写文件"三个工具。

"查天气"     → concurrency_safe = True"查股价"     → concurrency_safe = True"写文件"     → concurrency_safe = False(IO 副作用,不能并发)分批结果:  批次1:["查天气", "查股价"]  → asyncio.gather 并发执行  批次2:["写文件"]           → 单独执行总耗时 ≈ max(查天气耗时, 查股价耗时) + 写文件耗时        而不是 三者相加

这是 Loop Engineering 里"Worktrees 隔离"思想在单轮执行层面的体现——能并行的任务不要串行,但有 IO 副作用的操作必须隔离


4.6 细节三:mid-turn 注入——后台任务的"插队通道"

这是 nanobot 里小编觉得最精妙的设计——跟 Reflection 模式的思想完全吻合。

场景:主 Agent 正在跑循环,同时它启动了一个后台 SubAgent 去执行一个耗时任务(比如爬虫、代码分析)。SubAgent 完成了,结果怎么告诉正在跑的主循环?

正常思路:等主循环跑完,下一轮再传结果——但这样后台任务就失去了"实时性"。

nanobot 的方案:后台任务完成后,把结果往"注入队列"里一丢,主循环下一轮迭代自动感知并处理。

# runner.py 第 175-228 行async def _try_drain_injections(    self, spec, messages, assistant_message, injection_cycles,) -> tuple[bool, int]:    """每次迭代末尾调用:检查有没有待注入的消息"""    # 非阻塞地取一下注入队列    injections = await self._drain_injections(spec)    if not injections:        return False, injection_cycles   # 没有注入,告诉外层继续正常迭代    # 有注入!把 assistant 消息先记录,再追加注入内容    if assistant_message:        messages.append(assistant_message)    messages.extend(injections)   # 后台任务结果注入到对话历史    return True, injection_cycles + 1   # 告诉外层:要 continue,让 LLM 看到新内容# 在核心迭代循环里,每次迭代末尾都调用一次:should_continue, injection_cycles = await self._try_drain_injections(...)if should_continue:    continue   # 有后台任务完成了?把新信息喂给 LLM,继续迭代

这个机制的工作方式:

主 Agent 循环在跑  ↓(某个后台 SubAgent 完成了任务)  ↓SubAgent 把结果放入 pending_queue  ↓主循环下一轮迭代开始时,_try_drain_injections() 取出结果  ↓结果追加到 messages,喂给 LLM  ↓LLM 现在知道了后台任务的结果,据此做出更好的决策

这就是 Reflection 模式在工程里的样子:外部观察(后台任务的结果)实时注入到循环里,让 Agent 能基于最新信息持续修正决策。


五、全景:四大工程的嵌套关系 + 你现在在哪个阶段?

5.1 四大工程不是替代关系,是嵌套关系

容易踩的一个认知坑:有人学完 Loop Engineering,以为前面的三大工程就可以扔了。然后他们的 Loop 就开始出各种稀奇古怪的问题。

事实是:四大工程不是"升级换代",而是层层嵌套、缺一不可。

Prompt 写得好,Agent 才能理解任务;Context 管理得好,Agent 才能拿到正确信息;Harness 搭得好,Agent 才能安全可控地行动;Loop 设计得好,Agent 才能持续自动地运转。

缺任何一层,整个系统都会出问题。

小编一直觉得用"开餐厅"来类比最好记:

  • Prompt Engineering:厨师学会按菜谱做菜——你跟 AI 怎么沟通,它就怎么理解;
  • Context Engineering:采购把对的食材备好放台面——信息摆对了,厨师才能做出对的菜;
  • Harness Engineering:餐厅的操作规范——厨师能用哪把刀、能不能进冷库、出了事怎么处理;
  • Loop Engineering:整个餐厅的运营系统——订单怎么来、谁负责哪个工位、出品谁验收、每天收摊后复盘哪道菜要改方子。

光有好厨师(Prompt),没有食材(Context),菜做不出来。有食材没规范(Harness),厨房早晚出事。有规范没运营(Loop),每天开门都得老板亲自盯——这不叫系统,叫消耗品。

你的目标是:让餐厅没有你在的时候也能正常运转。这才是 Loop Engineering 的终点。


5.2 四大工程终极对比表

维度Prompt EngineeringContext EngineeringHarness EngineeringLoop Engineering
核心问题怎么跟AI讲话?给AI看什么?AI怎么安全运行?系统怎么自动转?
类比教员工说话配信息策展人建工作制度设计工厂流水线
工程师角色操作员策展人环境工程师系统架构师
关注范围一条prompt一次会话的信息一次任务的运行持续自动化运转
出错了怎么办一条prompt重发调整检索策略加校验、改权限分析循环日志,改Skill/State
门槛⭐️最低⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️最高
目标单词回答更好单词回答更准单词执行更安全系统持续稳定产出

5.3 你现在在哪个阶段?

能看到这里的,都是真·认真的人。来对号入座,看看自己现在在哪一格:

  • 还在手动写每一轮 prompt?→ 说明你在 Prompt/Context 阶段。先固化团队的 Skills 和项目约定,这是成本最低的升级。
  • 会用 /loop 但没有 STATE、没有 Verifier?→ 有 Loop,无 Engineering。补一个 STATE.md,加一个 L1 报告模式。花两小时,收益很大。
  • 有分诊 Skill + STATE + Maker/Checker 分离?→ Loop Engineering 入门了。下一步:跑一次 loop-audit,设 token budget,扩到 L2。
  • 多 Loop 并行 + 完整闸门 + 可观测性都有了?→ 恭喜,Loop Engineering 成熟了。你现在的工作是:定期审计 Loop 的输出质量,研究 failure modes,协调多 Loop 之间的优先级。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值