Neuro-Symbolic Machine 的第一步: Agent, Kernel 与 Runtime

上一篇里我们提出了一种由神经模型, 符号环境和持续执行机制共同构成的计算环境. 这一篇讨论它的首个工程落点: 用原生内核嵌入 Common Lisp, 让模型在其中建立对象, 运行程序和利用反馈, 再由 Agent 与 Runtime 组织持续的工作.

首版要跑通的是一个完整的神经-符号循环: 模型提出可执行的操作, 符号环境处理对象与约束, 运行时连接外部能力, 结果再参与模型的下一步判断. 调度, 持久化和动态更新为这个循环提供连续性.

本文描述准备实现的结构与执行规则, 示例用于说明接口语义. 完成后的实现细节与验证结果将另行补充.

原生内核与 Lisp 层

首版计划采用 C++ 与 Embeddable Common-Lisp. ECL 提供将 Common Lisp 作为库嵌入原生程序的能力. 用户启动一个程序, 即可进入同一进程中的 Agent 环境.

原生内核保持精简, 负责启动, 事件循环, 资源句柄以及对宿主能力的访问. Lisp 层负责 Agent 对象, 计算规则, 工具定义, 任务编排和 Harness, 也就是组织模型调用, 上下文与行动的策略代码.

Runtime 指整套执行机制, 包含原生内核和 Lisp 中的调度, 状态管理逻辑. 语言边界不必等同于功能边界: 先把规则放在容易检查和修改的位置, 再根据性能与可靠性需求调整.

两层之间使用窄接口, 传递结构化请求, 结果和明确生命周期的句柄. ECL 对象的保活, 异常传播和线程进入规则集中在适配层处理. 未来迁移到 Rust 内核与 Rust 实现的 Common Lisp Runtime, 或探索完全使用 CL.

建立模型能够操作的符号环境

首版的符号层需要让模型发现对象, 理解可用操作, 并检查执行结果. 仅仅提供一个接受 Lisp 字符串的入口, 还不足以组织长期工作.

环境先提供三组对象: 带来源的材料与判断, 带版本的程序与工具, 以及带生命周期的计算与动作. 它们通过稳定标识相互引用, 检查接口按需返回字段, 依赖和状态, 原始材料则保留在可回溯的位置.

模型通过这些接口读取必要的上下文, 提出结构化动作或受支持的 Lisp 程序. 临时计算可以查询, 转换和检验对象; 修改持久状态或访问外部系统时, 则经过明确的提交与能力边界.

一次调查可以这样推进: 模型把材料整理为带证据引用的主张, 生成查询检查日期冲突, 观察冲突结果, 再决定补充检索还是保留两种解释. 报告引用已保存的证据对象; 之后证据更新, 系统可以找到依赖它的主张和报告.

其中, 模型负责提出解释与下一步探索, 程序执行确定的查询和检查, 环境保留对象之间的联系. 执行成功表示程序按规则完成, 并不保证模型提取的主张符合原文. 语义正确性仍需证据比对, 独立检查或人工评估.

Harness 如何组织这个循环

Harness 决定模型看到哪些对象, 可以选择哪些操作, 以及何时继续调用模型. 它以 Lisp 实现, 也作为可检查, 带版本的程序存在于环境中.

每轮求解先从目标和当前计算状态出发, 按需选择对象及操作说明, 再请求模型给出候选行动. 环境检查请求, 执行后返回结果, 错误或等待状态. Harness 根据反馈决定继续探索, 产生子任务, 请求人工输入或结束计算.

工具输出, 对象变更和验证结果可以保存为外部轨迹. 它们记录可观察的求解过程, 无需依赖模型隐藏的内部推理. 模型上下文是对这些状态的选择性呈现, 持久状态则由环境管理.

首版用这套轨迹检查问题出在哪里; 后续再加入策略比较, 修改评估和训练数据筛选. 这样, 上一篇中的求解, 演化和学习三个循环可以逐步落到同一套对象与记录上.

四个基本概念

  • Agent 是持续存在的主体, 保存身份, 共享记忆, 策略版本, 能力集合和消息队列.
  • 计算 是一项正在推进的工作, 保存局部状态, 当前位置, 等待条件和所用代码版本. 一个 Agent 可以拥有多条尚未结束的计算.
  • Effect 是计算向运行时提交的外部动作请求, 例如调用模型, 执行工具, 等待输入或向其他 Agent 发消息. 它包含动作标识, 参数和所需能力.
  • 事件 表示已经发生的事情, 例如消息到达, 动作完成或计时器触发. 事件携带关联标识, 供运行时定位并恢复相应计算.

Agent 的长期记忆和计算的局部状态需要分别存放. 等待人工确认的调查可以保留自己的中间材料, 另一条计算则读取已提交的共享知识, 生成阶段报告.

一次动作如何运行

计算推进到需要外部结果的位置时, 生成 Effect 并让出执行权. 运行时检查能力, 记录请求, 然后交给对应执行器. 执行器返回事件, 运行时记录结果, 再恢复计算.

以下是用于解释语义的接口草图, perform 并非 Common Lisp 的内建操作:

(let* ((documents (perform :search :query topic))
       (report (perform :llm :task :summarize
                        :input documents)))
  (save-report report))

表面上是顺序程序, 实现上却需要在 perform 处保存可恢复状态. 首版可以将受支持的任务表达式转换为显式步骤, 保存步骤编号与所需局部数据. 一般的 Lisp 计算在步骤内部执行.

恢复依赖这套任务表示, 不能把任意原生调用栈或 Lisp 闭包直接当成可持久化的计算. 文件句柄, 连接和其他宿主资源也要通过逻辑标识重新获取.

并行任务

首版采用单个 Lisp 执行线程和协作式调度. 每次运行一个计算步骤, 在等待边界交还控制权; 网络请求等耗时 I/O 由异步执行器处理, 完成后送回事件.

这样, 多条计算可以同时处于进行中, 而共享 Lisp 状态的修改保持串行. 计算等待工具时, Agent 可以处理新消息, 启动另一项任务.

这也意味着长时间不让出的 Lisp 代码会阻塞调度. CPU 密集任务需要分块或交给外部执行器. 协作式调度本身不提供对任意代码的强制抢占.

恢复需要记录什么

恢复机制至少需要保存计算状态, 待执行动作, 已收到的结果, 以及对应的代码和数据版本. 计算状态与待发送动作应当一起提交, 避免出现状态已经前进, 动作却丢失的间隙.

重启后, 运行时加载状态, 重建等待关系, 并继续处理未完成动作. 重放遇到已有结果的模型调用时, 使用记录的结果, 不重新询问模型. 时间和随机数等影响执行路径的输入也需要受到记录或约束.

最棘手的情况是外部动作已经完成, 本地却没有记下结果. 重试可能造成重复执行, 因此动作接口需要幂等键或结果查询能力; 无法确认的动作应保留“结果未知”状态, 交由策略或人工处理.

持久化保证的是在规定边界恢复工作. 它不会自动赋予外部系统恰好执行一次的能力.

动态修改需要版本边界

Common Lisp 支持运行中修改定义, 但语言层面的重定义不能代替应用层的版本管理.

首版可以让新计算使用新策略, 已有计算继续引用创建时的版本. 要实现这一点, 需要版本化的定义或显式分派, 单纯覆盖同名函数并不能保留旧行为.

正在运行的计算若要切换版本, 应在明确的等待点进行状态迁移. 每次修改记录来源, 差异和评估结果, 并保留可重新启用的旧版本.

模型生成的修改也走同一条路径: 提出候选, 执行检查, 评估效果, 再决定是否启用. 对任意 Lisp 代码的同进程执行属于可信代码能力; 包命名和接口检查不足以构成安全隔离, 需要强隔离的扩展应放到进程边界之外.

ReAct 与任务图放在哪里

首个 Harness 可以采用 ReAct, 按观察, 决策与行动循环推进. 对运行时而言, 这只是生成计算步骤和 Effect 的一种策略.

同时, 用相同接口表达任务图: 节点描述工作, 边描述依赖, 节点完成后触发后续计算. 图定义应当与某次执行的状态分开, 修改图时明确是影响新实例, 还是迁移当前实例.

模型可以新增检查节点, 拆分任务或尝试另一条路径. 运行时负责验证依赖和权限, 保证执行状态仍可解释. 首版先建立这些接口, 无需同时实现所有编排方式.

为分布式保留边界

单机阶段要为 Agent, 计算和 Effect 分配稳定标识, 并为请求, 事件与持久化状态定义带版本的数据格式. 外部动作通过执行器接口分发, 避免在计算中直接依赖本机地址或原生对象指针.

本地调度仍可保持简单. 以后增加远程执行器时, 再实现节点发现, 路由, 超时, 重复消息处理和所有权转移. 某个动作远程执行与整个 Agent 迁移是两种能力, 后者还涉及共享状态和运行中计算的协调.

首版的完成标准

首版先支持文本交互, 可检查的符号对象, 模型调用, 少量工具, 以及一个 Agent 内的多条计算. 实现是否成立, 用一组连贯的场景判断:

  • 模型把材料转化为带来源的对象, 运行检查并根据结果修订判断, 最终产出引用这些对象的报告.
  • 新任务能够查询并复用已有对象与程序; 修订证据后, 可以定位依赖它的结论.
  • Agent 发起调查并等待外部结果, 期间响应新消息, 生成阶段报告.
  • 进程在等待期间退出, 重启后恢复状态; 对已记录结果的调用不重复执行.
  • 外部动作结果不明时, 系统展示待确认状态, 而非直接宣告成功.
  • 更新一项策略后, 新任务使用新版本, 旧任务仍按其绑定版本继续.

这组场景同时检验神经与符号的协作, 状态连续性和动态更新语义. 评估时还需要比较直接使用模型与加入符号环境后的任务质量, 错误定位能力和执行成本.

下一步是在这些对象与协议之上展开任务图, 受控策略改进和远程执行. 首版由此成为长期愿景的可检验起点: 先让模型在一个持续存在的符号世界里有效工作, 再让这个世界逐步具备演化与分布式协作的能力.