这篇不是上一篇的项目复盘续写,而是把同一个项目往下再挖一层:我后来才意识到,我当时真正搭出来的,不只是一个 agent,而是一套让 agent 能持续工作的 harness。
上一篇我写的是:这个系统是怎么一步步搭出来的,架构怎么演进,哪些坑最真实。
这一篇我不想重复那些过程。
我更想回答一个问题:
我当时到底在搭什么?
回头看,最有意思的部分,不是“我做了一个 AI Agent”,而是: 我在还不知道这个词的时候,就先把一套 agent harness 搭出来了。
当时我并没有从 graph、runtime、orchestration framework 这些词出发。
我真正面对的问题只有一个:
怎么让一个真实业务系统可以持续摄入信息、进行推理、执行动作、保留状态,并且通过用户已经在用的界面稳定运转。
它的起点不是 AI 抽象,而是业务系统本身的运行压力。
这篇不再讲 feature,而是讲层
当 IMLANG 不再只是一个 demo,而是真的开始承担业务任务时,我很快发现:
“和 LLM 聊天”只是整个问题里最小的一部分。
如果换个角度看,上一篇里那些实现细节,其实是在逼着系统长出五层结构。
第一层:后台执行能力
最先长出来的,不是“对话”,而是后台执行能力。
真实业务不会等你打开对话框再发生,所以系统必须先有自己的心跳。
也就是说,它得先能:
- 定时检查外部输入
- 持续更新状态
- 在用户没发消息时也推动流程继续跑
这一刻,系统其实已经不只是聊天机器人了。 它开始变成一个持续运行的业务系统。
第二层:工具层
第二层自然变成了工具层。
用户说的不是底层命令,而是结果。
他不会说“去读数据库”或者“去查文件系统”,他只会说:
- 帮我找资料
- 帮我起草
- 帮我推进
- 帮我发出去
所以系统不能只有语言理解,它必须有一个可调用、可约束、可执行的业务动作面。
做到这里时,项目本质已经变了: 它不再只是“给模型写 prompt”,而是在给模型提供 action surface。
第三层:Agent 调度循环
有了工具之后,静态路由很快就不够用了。
一旦任务开始变成条件式、多跳式,系统就必须有自己的调度循环,而不是固定映射。
于是核心问题不再是“模型能不能回答”,而变成:
- 什么时候继续行动
- 什么时候停下来
- 什么时候把结果交还给用户
这一步非常关键。
因为从结构上看,这已经不是一个“调用大模型的功能点”,而是一套协调推理与执行的 runtime。
第四层:连续性
第四层是连续性。
业务工作不是无状态的。
今天讨论的客户,明天还是同一个客户。
上次回复过什么、现在处在哪个阶段、后台刚处理了什么结果,这些都不能丢。
所以系统真正需要的,不只是 prompt window,而是分层上下文:
- session memory
- per-customer context
- 最近讨论历史
- 长期记忆
- workflow 结果回流
很多“玩具 agent”的问题就在这里: 能回答一个问题,不等于能持续工作。
第五层:transport abstraction
第五层是 transport abstraction。
开发者最顺手的平台,往往不是用户真实使用的平台。
所以一旦系统开始走向真实使用环境,就必须把“消息平台”从产品本体里拆出来,变成 adapter / transport layer。
这一步的真正意义是:
Telegram 不再是 bot 本体,它只是一个 transport。
听起来像一个小重构,但实际上它改变了整个系统的边界。
从这一步开始,你构建的已经不是某个平台上的助手,而是一套可以穿过多个界面运行的 runtime。
真正难的不是功能,而是 coordination
项目早期,每增加一个能力,看起来都像在补 feature。
但做到一定程度之后会发现,真正难的已经不是某一个功能点,而是 coordination。
真正难的是:
- workflow 什么时候触发?
- 系统什么时候继续执行,什么时候停止?
- 上一步状态应该带多少进下一步?
- 输出怎么适配不同界面?
- 外部 API 的结果如何标准化,才能继续被模型推理?
- 什么可以自动完成,什么必须交还给人审批?
这已经不是“胶水代码”了。
这就是 harness 真正开始出现的地方。
因为 harness 的本质,从来都不是“把很多工具挂在一起”。 而是: 让推理、状态、执行和界面在一个闭环里保持一致。
为什么 Telegram + 外部 API 这件事,本质上就是 harness
我后来越来越觉得,这个系统根本不是围绕模型本身建立的。
模型只是中间的 planner。
一个真实请求经过的,不是“用户问一句,模型答一句”,而是一整条协调链:
- 用户通过某个界面发来消息
- 系统加载 session 和记忆、客户上下文
- 模型判断缺什么信息
- 系统去调外部执行面
- 结果被规范化后再回流给模型
- 模型决定继续还是结束
- 回复再适配到目标平台发出去
所以更准确的说法不是“chatbot + integrations”, 而是:
- interaction surface
- execution surface
- planning runtime
其中:
- 用户界面是 interaction surface
- Outlook / Supabase / OneDrive / WhatsApp API 这类系统是 execution surface
- 模型是 planner
- harness 是把这些东西维持成闭环的那层系统
第一性原理,比框架词汇更适合作为起点
如果我一开始就从框架词汇出发,项目很可能在纸面上更优雅,但在现实里更难用。
因为真正决定架构的,从来不是这些问题:
- 这是不是 graph?
- 我应该选哪个 framework?
- 最优雅的 tool-calling 抽象是什么?
真正决定架构的是这些约束:
- 什么状态必须保留?
- 什么动作必须能执行?
- 什么应该自动完成,什么必须交给人?
- 哪些流程必须在后台持续运行?
- 系统要通过哪些界面活着?
- 哪些外部系统真的会改变世界状态?
这才是架构真正的来源。
所以我现在理解的“第一性原理式 agent 开发”,不是先学一个框架,而是先回答这些最底层的问题。
如果这些问题回答得足够诚实,系统最后自然会长成某种 framework-like 的形状。
后来再看 LangGraph / harness,这些词才真正有意义
只有当 IMLANG 这套系统已经搭出来之后,LangGraph、agent harness 这些词对我来说才不再只是标签。
在那之前,它们只是名词。
在那之后,它们才变成一组我已经亲手踩过的问题:
- 状态连续性
- 工具编排
- 迭代式推理
- transport abstraction
- failure boundary
- cost control
- human checkpoint
这也改变了我对框架的看法。
我现在不把框架看成起点,而更愿意把它理解成两种东西:
- 帮你少重复造基础设施的 shortcut
- 帮你给已经踩出来的模式命名的一套 vocabulary
框架当然有用。
但很多时候,大家在项目最早期高估了框架的重要性,低估了真实业务约束的重要性。
最后一句话
如果你今天也在搭一个 agent system,我最想给的建议其实很简单:
不要先问: “我应该用哪个 framework?”
先问:
- 什么状态必须保留?
- 什么动作必须能执行?
- 什么决策必须交给人?
- 哪些后台流程必须自动运行?
- 系统要通过哪些界面和用户互动?
- 哪些外部系统真的能改变世界状态?
当这些答案具体了,架构就会自己浮出来。
如果你足够从第一性原理出发去做,很可能会像我一样,最后才意识到:
你从来不只是“做了一个 agent”。
你真正做出来的,是那套让 agent 能存在、能工作、能扩展的 harness。