剥离了主流框架的黑盒封装后,前序几篇始终围着同一个核心 while 循环添砖加瓦:用 Schema 严格界定模型输出边界,靠上下文压缩与状态记忆掌控下一轮迭代的视野,引入计划层约束多步任务的拓扑依赖,挂载检查模块对齐轨迹日志,最后在执行网关处埋入护栏拦截越权,辅以并发调度、超时兜底、幂等键透传与全链路审计落盘,把单次 run 的高可用与状态可追溯彻底夯实。这些组件拆开单看,各自架构都已自洽。
然而要把这些独立模块缝合成一套具备实战生产力的完整 Agent,最棘手的问题随即浮出水面:在状态机的轮转周期里,组件究竟该按什么顺序挂载流转?举几个最直白的反例——上下文压缩前置或后置失当,模型每次裸调 API 看到的仍是未经裁切的上下文巨集;护栏若挪到工具执行完毕后才校验,未经验证的写操作(如酒店订单)早已穿透落盘;审计日志若只留存压缩后的摘要副本,事后轨迹回放时真实 ID 与上下文细节便全部丢失。组件的设计初衷都没错,错的是挂载位置——位置一错,整条链路随之雪崩。
因此这篇不再造新轮子,也不引入花里胡哨的新概念,业务目标依然死磕那个经典的“西安 10 月 1 日住两晚” Case(下雨订 Suite,否则订 Standard)。只聚焦一件事:把前期手搓的组件严丝合缝接回同一个主循环体,彻底打通这一次 run 的全生命周期——从任务切入循环体,到模型输出终答或触发用户确认而挂起状态机,再到确认后的上下文回灌与续跑下单,把底层的数据流与控制流梳理清楚。
下文出现的架构术语,全文仅遵循以下严谨定义:
| 术语 | 架构语义 |
|---|---|
run | 一次任务从切入主循环体,到最终触发退出网关的完整生命周期 |
| 一轮 | 核心循环体的单次迭代链路:裸调大模型 API、路由分发执行工具、打平回灌上下文 |
| 层 | 前序系列文章中各自独立封装的工程组件与中间件代码 |
| 出口 | 当前 run 满足终止条件,状态机彻底销毁退出 |
| 停住 | 状态机挂起(非出口):维持全量 messages 堆栈在内存或持久化介质中,等待外界 User 态输入唤醒流转 |
最底层的状态机循环依然是那个循环。只不过在工程实现上,上下文压缩必须卡在问模型之前,护栏拦截必须卡在工具执行之前,而审计落盘必须死死锁定在消息打平回灌之后。
Table of contents
Open Table of contents
一、循环的本质从未改变
抛开重型框架动辄数百行的嵌套,Agent 核心循环的骨架,依然是最开始那几行朴素的糊代码:
while True:
resp = ask_model(messages) # 携带 tools 裸调大模型 API,下发决策推断
if not resp.tool_calls:
return resp.content # 触达出口:模型给出终答,状态机跳出循环
messages.append(assistant_msg) # 将模型的工具调用意图(AST)压入上下文栈
for call in resp.tool_calls:
messages.append(tool_msg(call)) # 路由分发到底层执行,并回灌执行结果
即便把上述所有高阶组件全挂载进去,系统依然死守这个最基础的拓扑结构。多出来的中间件代码,无非是作为钩子精准注入到两个核心生命周期节点:一是在发起大模型网络请求之前,对即将发出的 Payload 副本做动态干预;二是在工具路由执行之前与之后,对这一轮真实落地结果做状态拦截与重塑。
for turn in range(1, max_turns + 1):
messages[0] = system_with(memory) # 将短期记忆持久化,透传进 System Prompt 基座
outgoing = compact(messages) # 触发上下文截断/压缩生成副本,保持原始 messages 堆栈不被污染
resp = ask_model(outgoing) # 发起网络请求,辅以严格的超时兜底机制
if not resp.tool_calls:
write_audit(run_id, messages, memory)
return resp.content # 触达出口,或发起敏感操作确认后将状态机挂起停住
if memory.used_tokens > budget:
return "累计 Token 超限,系统触发熔断强制终止。"
if is_spin(calls):
return "检测到死循环打转,护栏网关强制拦截并终止。" # 护栏必须卡在工具真实执行之前
messages.append(assistant_msg)
messages.extend(execute_turn(pending, memory.confirmed)) # 核心执行层:并发调度、超时兜底、透传幂等键,最终按请求顺序打平回灌
write_audit(run_id, messages, memory) # 每一轮迭代终了,强制将未压缩的全量快照落盘审计
在这套极简又硬核的架构里,大模型被降维成一个纯粹的决策大脑,只负责输出“我想调用哪个工具的 AST 语法树”;剩下的状态维护、上下文管理、并发调度与异常兜底,全由你亲手撸出来的代码精准把控。
二、架构层在流转中的精准卡位
各个工程组件在链路里都扮演不可替代的角色,卡位一旦失准,迎接你的就是连锁崩溃:
| 架构层 | 挂载节点 | 缺失或错位引发的雪崩效应 |
|---|---|---|
| 记忆 | 每轮初始,透传写入 system 消息 | 经历上下文压缩后,模型将彻底丢失关键 ID 与天气状态,直接触发幻觉胡编乱造 |
| 计划 | 嵌于记忆模块,随 system 同步下发 | 模型在单次 run 中被迫反复推演步骤,极易引发逻辑跳跃或链路断裂 |
| 压缩 | 裸调模型 API 前,基于独立副本操作 | 历史 Context 滚雪球式膨胀,早期废话直接将近端关键意图挤出滑动窗口 |
| Schema | 实例化 tools 时一次性固化映射 | 传参格式错乱或字段越界,只能依赖耗时的 API Error 回灌机制做低效重试 |
| 路由分发 | dispatch 调度层按工具名称哈希分流 | 外部脏工具绕过鉴权直接上抛,不可控的废数据强行入栈污染 messages |
| 护栏 | 提取出 tool_calls 之后,真实执行前 | 未经用户授权的越权写操作被直接击穿落盘,或模型在死胡同里陷入死循环请求 |
| 并发调度 | 护栏网关放行后的只读工具池 | 串行执行引发严重 I/O 阻塞,一轮调度三个工具沦为三段网络延迟的叠加 |
| 超时兜底 | 包裹于每一次物理执行调用的最外层 | 外部服务响应僵死,导致主循环既无法回灌上下文也无法退出,进程永久挂起 |
| 幂等键 | 深度绑定于写操作分发网关 | 发生网络超时后触发无脑重试,直接导致灾难性的“双重扣款”或“重复下单” |
| 回灌顺序 | 协程批量收尾后,强制按原始发起顺序打平入栈 | 异步并发谁先完成谁先写,乱序回灌导致大模型 API 校验直接抛出 400 Bad Request |
| 轨迹日志 | 回灌操作彻底完成后即时打点落盘 | 链路回溯时只剩孤零零的终答,中间态的 AST 传参和执行细节彻底黑盒化 |
| 审计 | 强制绑定 run_id,逐轮迭代完毕后落盘 | 事后轨迹检查缺乏全景快照支撑,状态机挂起后的上下文续跑完全无从读回 |
| 检查 | 游离于核心循环之外,基于审计文件做后置离线跑批 | 只能粗粒度验收最终结果,却对底层的状态流转与逻辑推演路线一无所知 |
相比于套壳调用臃肿的外部框架,外部工具在这套架构里只占一个纯粹的执行槽位:由 dispatch 层按工具映射做路由分发。本地逻辑直接走内存态的 REGISTRY,外部服务则通过 call_tool 协议透传,并在回灌上下文前严格依据白名单做字段清洗。list_tools 动作只在切入主循环前初始化一次,转化为标准 Schema 挂载至请求头;白名单之外的未注册工具根本不予生成 Schema——从物理隔绝的维度直接剥夺模型的视野。
为了支撑本地高效联调,循环拓扑、messages 栈、状态记忆与护栏拦截的底层实现均保持硬核锁定。代码里抽象了一层环境开关:默认开启本地 Mock 数据流(强制透传“下雨”天气),保障“下雨订 Suite”的核心用例能被反复跑通;一旦拨动开关,同一个 get_weather 接口会被动态路由至远端 MCP Server,并自动前置串接异步的 search_location 获取坐标。
三、决定生死的三处强依赖顺序
之所以反复强调执行顺序,是因为某些组件的位置哪怕只错位一行代码,整条架构的数据流转就会雪崩。
上下文压缩必须卡在问模型之前。 核心要义在于:压缩算法只能作用于即将发往 API 的那份临时 Payload 副本,绝不能反向污染 messages 堆栈本体。次序一旦颠倒,当前轮次不但省不下 Token 开销;一旦篡改了 messages 本体,后续落盘的审计快照与等待唤醒的续跑数据,便只剩一堆信息熵归零的残缺摘要。
护栏拦截必须卡在工具执行之前。 无论是识别大模型陷入同参打转的死循环,还是拦截未经验证的写操作(如越权发起订房),这类高优校验根本不需要真实的底层执行结果——系统只需解析 tool_calls 中携带的参数 AST,就足以在网关层完成鉴权。若把护栏挪到执行之后,意味着酒店订单已经无脑穿透落盘,此时再向上下文回灌 Error,不过是在通知模型“你犯了个错”,而非在物理层面阻断越权。值得注意的是,被拦截的死请求依然要向堆栈回灌一条对应的 role=tool 兜底信息,以维持大模型上下文 Role 交替的配对连贯性。
审计落盘必须死死锁定在消息回灌之后。 审计文件要在每轮迭代收口时即时落盘,冻结的是该轮生命周期彻底完结时的全景 messages 快照——既包含 Assistant 生成的 tool_calls 意图,也囊括按原始请求顺序严格打平的 Tool 执行回执。一旦把审计落盘提早到回灌之前,持久化下来的消息体就是半截废数据,等你跨进程唤醒系统续跑时,API 必然因 Role 校验失败直接抛 400。
除此以外,其余组件的挂载点仍有微调弹性。比如轨迹日志在审计前打点还是审计后打点并无大碍;累计 Token 的限流探针是裸调模型后直接粗暴熔断,还是等这一轮跑完再优雅销毁状态机,也都说得通——底层工程原则只有一个:保证每次 run 内部状态绝对隔离,各算各的账。
四、状态机流转:跑通西安订房的全链路
追踪一次典型的 run 从头到尾,透视每一轮迭代中底层到底发生了什么:
| 轮次 | 模型生成了什么决策意图 | 架构中间件层做了哪些处理 | 短期记忆池演变为哪种状态 |
|---|---|---|---|
| 1 | 发起 set_plan 拆解四步前置计划 | 触发计划层中间件,解析 AST 并序列化写进记忆池 | plan 中挂载了四条 Pending 的子任务节点 |
| 2 | 决议 get_weather + search_hotels | 并发调度器拉起两个纯读工具,注入超时探测,执行收口后按请求顺序打平回灌 | 记忆池注入 weather=rain,并缓存 hotel_ids=[HT-001, HT-002] |
| 3 | 执行 mark_step(1, done) 等操作 | 触达计划层状态机,更新节点游标 | 前置两步任务标记为 done |
| 4 | 未生成任何 tool_calls 结构 | 模型输出终答向用户发起预订确认,触发全局审计落盘,状态机挂起停住 | confirmed 状态依然被锁死为 false |
| — | 人类通过外界 UI 传入「确认」指令 | 系统反序列化提取该 run_id 对应的 messages 与记忆池快照,尾部拼接 User 消息入栈,唤醒续跑 | confirmed=true 鉴权通过 |
| 5 | 发起高危写操作 book_hotel(...) | 护栏网关校验通过,写操作走独立调度通道,强制透传幂等键防重试 | 状态更新 booked=BK-001,总价 800 |
| 6 | 再次未生成任何 tool_calls | 汇总天气、酒店名、房型与总价输出终答,触达状态机销毁出口 | 记忆池状态终态保持不变 |
第 2 轮释放了轮内并发调度的性能红利:天气探测与酒店检索在业务拓扑上无严格依赖,系统直接用异步协程打平请求。而关键的第 4 轮与第 5 轮之间,系统经历了一段由人类介入导致的异步休眠期——在这个窗口内,主进程完全可以被安全杀死释放资源,因为全量 messages 历史栈与记忆快照早已持久化在本地审计日志中。特别要强调的是,第 5 轮透传的 hotel_id 绝不依赖模型那毫无边界的幻觉记忆,而是严格源自第 2 轮工具回灌进白名单的合法数据;底层代码会强制执行 memory.hotel_ids 哈希校验,大模型企图捏造的任何非法入参,都会在网关处被直接击碎。
针对 confirmed 这一高危状态的判定,系统在两处实现了严谨的双重校验。记忆池里的状态位只是一份只读提示,工程价值在于让模型知晓当前是否具备发起 book_hotel 的前置权限;护栏层则在真实底层执行前把守最终生死网关,哪怕大模型陷入严重幻觉企图霸王硬上弓发起写请求,也会被护栏直接熔断拦截。前者负责上下文引导,后者负责物理级阻断。同时,计费视角的累计 Token 探针跨越续跑阶段持续累加,绝不内存清零:第 5、第 6 轮产生的通信开销,在底层计费系统中仍被精准归因于当前这笔 run 的总账单。
五、状态机的三个出口与一次挂起
在复杂的业务流转中,何时该果断退出、何时该休眠等待,需要建立极其严苛的判定网关:
| 异常或稳态触发场景 | 当前处于什么生命周期 | 底层的 messages 堆栈该如何处置 |
|---|---|---|
| 模型输出最终解答 | 当前轮次未捕捉到任何 tool_calls | 强制触发审计落盘,当前 run 生命周期彻底终结 |
| 触发护栏网关熔断 | 识别到参数死循环打转,或裸调大模型 API 超时 | 强制触发审计落盘,当前 run 生命周期彻底终结 |
| 触发限流阈值熔断 | 累计 Token 开销超限,或循环深度探底 max_turns | 强制触发审计落盘,当前 run 生命周期彻底终结 |
| 停住等待外界确认 | 输出终答并反问用户是否执行高危敏感操作 | 强制触发审计落盘,状态机不结束,挂起休眠等待后续 User 消息入栈 |
前三个场景属于标准的生命周期出口,一旦触碰边界,本次 run 便宣告终结销毁。第四个场景截然不同:它的 run_id 保持不变,messages 堆栈本体未遭破坏,记忆池快照维持原状,整个底层架构仅仅将核心主循环暂时挂起进入休眠态。当人类用户在外部接口回复「确认」指令后,系统会精准截获该文本,封装为 User 角色消息强行入栈,随后从第 5 轮的逻辑原点直接唤醒上下文,继续朝下推进。
如果你打算重启一次全新的 run,那在工程上完全是另一个维度的开销:旧的记忆池会被系统回收清空,早前检索的 hotel_ids 灰飞烟灭。若在此刻强行发起订房,模型要么重新走一遍繁琐的检索流,要么陷入极度幻觉凭空捏造一个 ID 参数——但不必惊慌,在那个风险时刻,能死死按住它不让越权执行的,依然是你代码里那份不带状态污染的纯净白名单,而不是寄希望于大模型那薛定谔的记忆力。
六、极客排错指南:当底层行为对不上时
随着手搓 Agent 的链路不断延伸,排查隐蔽 Bug 往往成了一门玄学。在此提供一份标准且硬核的排错映射表:
| 你在系统日志中捕捉到的异象 | 应该优先去重构或审查哪一层组件 |
|---|---|
| 累计 Token 消耗呈现滚雪球式暴涨 | 上下文压缩模块彻底失效,或者代码错误地切片了原始的 messages 堆栈本体 |
模型陷入严重幻觉,凭空捏造了一个 hotel_id | 短期记忆未被正确序列化并透传至 system,或激进的压缩算法误删了近端的回灌快照 |
| 模型在每轮迭代中都在重新推演下一步做什么 | 计划树的状态丢失,未能成功持久化写进记忆池 |
| 用户尚未授权确认,高危预订订单却已穿透落盘 | 护栏层被错误地置于底层执行之后,或仅仅依赖于 Prompt 软提示而非硬代码网关拦截 |
| 大模型 API 校验直接抛出致命的 400 Bad Request | 异步回灌未按原始请求拓扑顺序打平入栈,或者发生丢包漏灌,亦或审计落盘早于回灌时机 |
| 一轮并发派发三个工具,耗时却等同于三者的串行之和 | 轮内并发调度器未正确挂载,系统被迫退化为同步阻塞模式 |
| 外部工具请求无限期挂起,导致核心循环陷入死锁僵尸态 | 外部工具调用层缺乏全局或者细粒度的网络超时兜底包壳 |
| 遭遇网络超时发起重试后,系统居然生成了双份僵尸订单 | 核心写操作分发网关缺乏幂等键透传,或重试前未强制执行前置状态自检 |
| 人类回复「确认」唤醒进程后,记忆池快照却是空的 | 代码错误地初始化了全新的 run 实例,未能从审计快照中执行反序列化回放 |
| 事后轨迹检查框架抛出无法回放还原的异常 | 审计层错误地留存了被高强度压缩过的残缺 Payload 副本 |
| 离线检查脚本全量 Pass,但真跑的线上业务逻辑依然崩溃 | 检查逻辑运行在了理想状态的 Mock 对照轨迹上,而不是复用线上真跑产生的那份物理审计文件 |
处理上述系统级故障时,核心心法在于“一次只动一层”。遇到压缩策略导致的上下文丢失,千万别头痛医头去粗暴改大 max_turns 上限;遭遇护栏未拦截的越权漏洞,不要试图改 Schema 做徒劳规避;遭遇上下文配对错乱抛出的 400 异常,不要先怀疑大模型底座智商不行而急于切模型。
七、极客视角的完整工程实现
这套脱离了重型框架、纯手搓的 Agent 底层架构完整源码,已开源在 agent-in-action/part1-handmade-agent/09-agent-full-loop/。
源码目录遵循极致的解耦与隔离原则,没有任何多余的跨级交叉引用,每一个架构层被干净利落地剥离在单一物理文件中。而 loop.py 中的 run() 函数,正是按上述剖析的八大阶段严丝合缝编排串联,形成坚不可摧的底层流转:
agent.py 系统入口:解析运行时入参,路由决断执行分支与策略
└─ loop.py 单轮迭代编排层(整个工程中唯一控制「流转先后拓扑顺序」的核心中枢)
├─ memory.py 短长期状态记忆管理、演进(absorb)逻辑、上下文截断与压缩
├─ toolset.py 向上面向模型屏蔽实现细节(呈现什么 Schema),向下负责执行器哈希路由映射
│ ├─ tools.py 本地沙盒实现(遵循绝对的纯函数设计,禁止一切针对记忆池的副作用)
│ └─ mcp_tools.py 外部服务网络桥接(单文件双栖架构:兼顾 Client / Server 两种进程态)
├─ guards.py 执行前置的高危拦截筛选网关
├─ executor.py 并发调度、超时兜底、写操作安全锁、以及强制有序打平回灌
└─ audit.py 执行后置的日志留痕与全景物理快照落盘
config.py 全局常量字典、超时阈值、System Prompt 基座:仅作为被读端,绝不反向依赖任何模块
checks.py 游离于核心主循环之外:专注于读取审计快照文件的后置离线检查脚本
selftest.py 脱离大模型 API 的纯代码沙盒:演示护栏拦截、并发打平回灌、幂等锁与压缩算法等核心链路的干跑
在工程架构的分层设计上,死磕两条铁律。第一,依赖关系只能单向朝下:tools 和 mcp_tools 在物理层面彻底隔离互不相识,它们之间横亘着 toolset 作为唯一合法的桥接层;执行侧的 executor 绝不知道 guards 护栏的存在;后置的离线 checks 模块也绝不允许反向依赖顶层 config。第二,核心的顺序编排只能收敛在一个物理位置:前文不厌其烦强调的「护栏必须卡在执行之前」,在 loop.py 的主循环体中就是清清爽爽相邻的两行代码,绝不会被封装深藏在某个难以察觉的黑盒函数调用栈深处。
allowed, blocked = screen(pending, mem.confirmed)
tool_msgs = tool_messages(pending, {**execute(mem, allowed, mcp), **blocked})
工具节点被设计为绝对干净的纯函数,不夹带任何状态私货,也绝不允许直接穿透篡改记忆池:无论是当下的计划树进度游标、本次检索捕获的 hotel_id,还是追踪链路的 run_id,全部由 toolset 在路由分发时显式透传进去;而底层执行结果究竟如何影响系统记忆的演进,唯一合法入口被死死锁在 memory.absorb 这一处。正因如此,“白名单到底是从哪里生成的”这个问题,Debug 排查时只需顺藤摸瓜看准那一行代码即可,即使并发起再多次高负载的 run,记忆快照也绝不会发生内存泄漏与串线污染。
另外极其值得一提的是 mcp_tools.py 这个文件,极具极客美学——一个物理文件同时肩负两副身份:被外部 import 导入时,它扮演调用端的 Client 代理角色;被作为独立子进程拉起时,跑的却是自身 __main__ 入口的 Server 逻辑,向外挂载着 search_location 和 get_weather 提供网络服务。这两副身份之间没有任何共享内存的余地,只能严格依赖网络协议做进程间通信(IPC)——所以在这套硬核架构里,“大模型输出的参数不可信、回灌内容需清洗”绝不仅仅是一句写在 README 里的开发提醒,它是被真实的操作系统进程边界从物理层面硬性隔离出来的绝对安全底线。
python agent.py # 正常联调跑批,直至模型输出终答并等待确认,期间完整 messages 栈落盘于 audit/ 目录
python agent.py --confirm # 截获外部指令,反序列化读回对应的 run_id 快照,向尾部追加 user 消息「确认」,唤醒续跑进入底盘下单环节
python agent.py --mcp # 天气服务路由动态切换至 MCP 模式:通过 list_tools 拉取 Schema,在 dispatch 中走 call_tool 协议透传网络调用
python agent.py --check # 脱离核心主循环,直接载入 audit 审计日志中的 messages 历史栈跑轨迹级的一致性离线校验
python agent.py --selftest # 掐断大模型网络 API,注入 mock 数据纯本地干跑,硬核验证护栏拦截、并发打平回灌、幂等锁与上下文压缩等底层控制流
运行 --selftest 模式时,你能肉眼可见地观察到整套状态机的严谨编排顺序:同一批下发的 tool_calls 队列中,若订单确认状态位未解锁,book_hotel 的越权操作会被护栏网关精准拦截,并直接向堆栈回灌 Error 兜底信息;旁路的两个纯读工具则丝毫不受阻碍,照常发起并发请求,最终回灌依然严格坚守 c1 → c2 → c3 的入栈拓扑顺序;当状态流转至合法确认后,系统即使被蓄意要求连续触发两次预订请求,底层幂等锁也会直接生效,BOOKINGS 数据库里自始至终只产生一笔真实的物理单据;经历上下文压缩算法的洗礼后,堆栈中陈旧的 tool content 节点被精准切割替换为精简摘要,而维系配对连贯性的核心 tool_call_id 则一个不落地得以保留。如果加上 --mcp 开关再跑一次干跑,就能清晰捕捉到模型视角的工具列表被动态替换的瞬态映射:本地写死的 get_weather 被优雅路由置换为远端 Server 上的 search_location 与 get_weather 组合技,而整个调用链路中其余的输出流却能保持一字不差的等效性。
至于 --check 脚本,它读取的正是那份沉甸甸的物理落盘文件 audit/run-xian.json:针对计划树是否被优先执行、是否存在跳步越级、参数是否追根溯源有所出处、房型枚举是否合法边界,这四大硬核校验项,结结实实跑在真跑留下的那份无删减版 messages 堆栈历史中。检查脚本本身绝不向大模型发起任何网络请求,也完全脱离运行期的状态机主循环——主循环的快照里烙印下什么原始罪证,它就冷酷无情地校验什么。
八、接下来去哪儿
“手搓 Agent”这条充满极客乐趣、不妥协于黑盒框架的底层架构演进路线,到这里算是彻底收束了。剥开所有迷雾后,你会发现大模型在整个 AI Native 体系中其实只做了一件极其单纯的事:利用自身的 Transformer 推理能力,输出它想调用哪个工具的 AST 意图。
而剩下所有的脏活、累活、苦活——系统的工具池里到底挂载了什么路由、模型在每个迭代阶段能看清多少上下文滑动窗口、多步计划中优先调度哪一步协程、高危越权风险操作在什么时候被果断拦截、整个状态机在什么时刻被优雅挂起停住、每一次底层流转又留下怎样详实的全景审计快照——这一切的控制权,全由你键盘下敲出的那几十行核心代码死死掌控。
如果哪天业务膨胀,你必须妥协去引入市面上那些花里胡哨的重型框架了,请务必先对照这套底层架构逻辑去审视它:它到底把上下文压缩、网关护栏、全链路审计这几层核心组件,分别埋在主循环的哪个节点?如果拓扑位置对得上,你换掉的仅仅是一种更繁复的语法糖与代码写法;一旦拓扑位置对不上,那你亲手换掉的,可就是整个系统架构至关重要的行为准则与生死命运。
至于目前市面上的框架生态到底怎么划分底盘势力,又该以这套底层架构原理对应评估并学习哪一个?我们将在下一篇做深度拆解。
一句话总结
剥离了框架的黑盒封装后,最底层的状态机循环依然没变。所有的工程架构层都只能精准挂载到两个核心枢纽上:一是在问模型之前动态干预即将发出的 Payload 副本,二是在执行前后彻底掌控这一轮真实动作该如何落地。
请死死记住:上下文压缩必须卡在问模型之前,护栏拦截必须卡在执行之前,而全链路审计落盘必须锁定在消息打平回灌之后。三个标准出口能彻底销毁当前的
run,唯独在停住等待外界确认时,状态机绝不结束——底层系统会死死保留那份全量messages快照堆栈,静静等待下一条 User 消息入栈,随后唤醒续跑。