Harness Engineering 之外:从非线性动力系统控制理解吸引子引导工程

本文面向已经熟悉 Harness Engineering、但还不熟悉 Attractor-Guided Engineering(吸引子引导工程,简称 AGE)的读者。

Harness Engineering 关注如何约束、验证、审计 AI 生成;AGE 进一步追问:这些控制机制到底要把仓库轨迹拉回到什么长期结构?

AGE 的详细介绍参见我此前的文章:Attractor Before Harness: AI 大规模开发的方法论。本文聚焦方法论类比:借助非线性动力系统控制的语言,特别是 PHS(port-Hamiltonian systems)的结构保持术语和 Immersion and Invariance 的目标流形图像,解释 AGE 中一些已经存在、但尚未被充分命名的结构:语义承诺如何守恒,变化义务如何转换,文档拓扑如何保持结构,AI 会话如何在跨时间的仓库中恢复同一个系统现实。

一、为什么需要这个类比

AGE 已经有一套核心语言:

状态空间 → 吸引子 → 轨迹 → 控制

这套 AGE 基础语言,精确刻画了 AI 大规模开发中的一个核心问题:当 AI 以高频、高幅度、无持续记忆的方式扰动仓库时,我们如何描述系统是否仍在长期收敛到稳定结构。

更准确地说,AGE 是从动力系统的思维图像来审视 AI 驱动的软件工程。一次 AI 任务可以看成仓库轨迹上的一次扰动和修正;单次输入输出只是这个轨迹的局部截面。仓库是随时间演化的状态空间;AI、人、持续集成、审计、文档更新都会改变轨迹;owner docs 定义系统应反复回到的吸引子;plans、tests、audits、logs 则提供局部校准机制。

非线性动力系统控制是系统化研究"状态、轨迹、稳定性、流形、反馈、观测、结构保持"的理论分支。PHS(port-Hamiltonian systems)是其中结构保持路线的典型代表。它把复杂系统拆成四类结构:Hamiltonian 记录系统储存了多少能量;互联矩阵记录能量如何在内部变量之间无损转移;阻尼记录电阻、摩擦等不可逆损失;端口记录系统和外部世界交换能量的边界。PHS 建模的关键作用,是把方程里的耦合项按功能分清楚:有些耦合项只是在内部搬运能量,有些项代表真实耗散,有些项来自外部端口。分清这些结构后,控制设计才知道哪些项应该保留,哪些项需要补偿或抑制。

本文不是要把 AGE 等同于 PHS,而是借用 PHS 这套代表性术语,进一步识别 AGE 中的守恒量、相变量、互联拓扑、耗散机制和端口边界。

本文的术语约定如下:

  • AGE:Attractor-Guided Engineering,吸引子引导工程。核心层级是"状态空间 → 吸引子 → 轨迹 → 控制"。
  • Harness Engineering:围绕 AI 生成建立 guardrails、verification、review、audit、diagnostics 等执行支架的工程实践。
  • PHS:port-Hamiltonian systems,非线性动力系统控制中结构保持路线的代表性语言,用能量函数、互联、耗散和端口描述复杂系统。
  • Hamiltonian:系统储能函数,刻画系统当前保存了多少能量。
  • Immersion and Invariance:浸入与不变性,通过构造目标不变流形来处理非线性控制、观测和自适应问题。
  • owner docs:指在仓库中拥有某类事实最终解释权的长期文档,例如架构基线、功能设计或组件合同。
  • closure audit:指任务完成前沿着需求、owner docs、代码、测试和日志重新检查闭合证据的审计。

与 PHS 相比,AGE 的基础语言还有一个尚未展开的层面:

在一次次输入、计划、实现、验证、审计、日志之间,到底有什么东西在被保持、被转换、被路由、被耗散?

如果只用普通流程语言回答,很容易退回线性流水线:

text 复制代码
input → requirement → design → plan → code → test → log

这个图像会误导读者。真实开发并不是只读上一阶段输出,再生成下一阶段产物。写代码和检查代码时,AI 通常需要同时参考:当前 requirement、owner docs、live code、tests、known-good baseline、bugs、logs、plan、audit、外部 contract,以及文档索引和架构层级给出的阅读路由。

换句话说,AGE 更像一个多端口耦合系统,单向级联流程只描述了它的局部投影。

非线性控制的启发正在这里:复杂耦合项不一定是噪音,很多耦合项本身就是系统保持结构的方式 。电机控制中常用 d-q 坐标,也就是随转子旋转的直轴/交轴坐标;在这个坐标下,某些速度相关、斜对称的交叉耦合项可以表示能量在不同坐标之间的无损流动。类似地,AGE 中 requirementsarchitectureplanscodetestslogs 之间的交叉引用,承担的是语义承诺在不同载体之间保持可恢复性的拓扑功能,不只是文档冗余。

二、PHS 的结构保持语言

PHS 的基本出发点,是把一个物理系统看成"储能、互联、耗散、端口交换"的组合。常见的有限维形式可以写成:
x˙=(J(x)−R(x))∇H(x)+G(x)u,y=G(x)T∇H(x). \dot{x}=\bigl(J(x)-R(x)\bigr)\nabla H(x)+G(x)u, \qquad y=G(x)^T\nabla H(x). x˙=(J(x)−R(x))∇H(x)+G(x)u,y=G(x)T∇H(x).

这个公式展示了几个核心符号如何组织在一起:

  • HH H 度量系统当前储存的能量;
  • JJ J 只搬运能量,不创造也不消灭能量;
  • RR R 消耗系统内部能量;
  • uu u 是端口输入, yy y 是端口输出,二者配对形成端口功率 yTuy^Tu yTu;
  • GG G 描述端口和内部状态之间如何耦合。

我们可以借用这套术语来表达非线性控制中的三条方法论原则:

  1. 先找倾向守恒的量,再判断哪些误差需要被消除。
  2. 区分无损路由和真实耗散,不要把"信息移动了"误认为"系统收敛了"。
  3. 把"搬运、耗散、外部注入/取走"分开看,避免把所有耦合压平成一个线性任务链。

三、反馈线性化式的软件工程误区

在控制理论中,精确反馈线性化试图用坐标变换和反馈把非线性项消掉,让系统表现为一个线性对象。这在某些系统中有效,但也可能高度依赖精确参数,并破坏系统原有能量结构。

软件工程里有一种相似冲动:为了让 AI 更容易执行,把所有知识压进一种统一 artifact:spec、change、task list、issue、pull request description,或者某个总计划文档。

这种做法看似降低了复杂度,其实是在做工程意义上的"线性化":

  • raw input 中的语境被压平成需求条目;
  • owner docs 的长期结构被压平成本轮任务说明;
  • architecture precedence 被压平成 checklist;
  • logs、bugs、analysis 中的历史判断被压平成"已知事项";
  • tests 和 audits 被压平成"已完成证明"。

局部看,这样更容易让 AI 执行。长期看,它会破坏仓库的语义拓扑。不同类型的事实被挤进同一个坐标系后,AI 不再知道哪个材料回答"现在是什么",哪个材料回答"应该向哪里收敛",哪个材料只是"当时为什么这么做"。

AGE 可以使用 spec 和 checklist,但不应把所有知识强行压成同一种执行形态。docs/architecture/docs/components/docs/plans/docs/logs/docs/bugs/docs/analysis/ 需要保留不同职责,因为它们是同一个仓库系统中的不同能量端口和不同状态坐标。

四、语义承诺作为 AGE 的储能函数

在 PHS 中,Hamiltonian 是系统储能函数,回答"系统当前保存了多少能量"。套用到 AGE 时,可以把跨 session 需要被恢复、保存和继续约束未来演化的语义承诺,看作仓库系统中的"储能":
Hrepo =仓库中仍然有效、需要跨 session 被恢复并约束未来演化的语义承诺总量. H_{repo}=\text{仓库中仍然有效、需要跨 session 被恢复并约束未来演化的语义承诺总量}. Hrepo=仓库中仍然有效、需要跨 session 被恢复并约束未来演化的语义承诺总量.

这里的"语义承诺"指系统已经接受、不应随便丢失的事实、合同和判断;文件字数或文档条目数不等于语义承诺。例如:

  • 某个用户可见行为需要存在;
  • 某个 schema 字段具有确定语义;
  • 某个 package dependency direction 不得反转;
  • 某个 renderer contract 需要稳定;
  • 某个历史 bug 的根因不应被再次引入;
  • 某个 audit finding 已被证伪,不应继续驱动整改;
  • 某个 owner doc 定义了当前规范基线,而不是未来设想。

这些承诺可以粗略分解为:
Hrepo = Hintent + Hrequirement + Howner + Hcontract + Hbehavior + Hproof + Hmemory . H_{repo} =H_{intent} +H_{requirement} +H_{owner} +H_{contract} +H_{behavior} +H_{proof} +H_{memory}. Hrepo=Hintent+Hrequirement+Howner+Hcontract+Hbehavior+Hproof+Hmemory.

这些分量分别对应:

分量 含义 典型载体
Hintent H_{intent} Hintent 外部输入带来的真实意图 用户请求、产品经理说明、外部材料
Hrequirement H_{requirement} Hrequirement 当前切片需要兑现的需求承诺 requirement、plan goals
Howner H_{owner} Howner 长期稳定结构承诺 architecture docs、component design docs
Hcontract H_{contract} Hcontract 可被外部或下游依赖的合同 schema、API、public types、renderer contracts
Hbehavior H_{behavior} Hbehavior live repo 中真实运行的行为 code、examples、playground
Hproof H_{proof} Hproof 可复查的证明 tests、verification、audit evidence
Hmemory H_{memory} Hmemory 未来不应遗忘的轨迹判断 logs、bugs、retrospectives、analysis

一次实现会改变承诺的承载形态:同一个语义承诺从"尚未兑现的变化义务",转换为"代码、测试、owner doc、日志中可恢复的稳定事实"。

Hrepo H_{repo} Hrepo 只描述已经被系统接受、需要被保留和恢复的承诺。它不包括尚未澄清、尚未归属、尚未验证的自由不确定性。后者单独记为:
Frepo =仓库中尚未绑定到稳定承诺、owner 或证据的自由语义不确定性. F_{repo}=\text{仓库中尚未绑定到稳定承诺、owner 或证据的自由语义不确定性}. Frepo=仓库中尚未绑定到稳定承诺、owner 或证据的自由语义不确定性.

因此, Frepo F_{repo} Frepo 不是 Hrepo H_{repo} Hrepo 的一个分量。它更像围绕语义承诺漂浮的未定能量:需求还没说清、owner 还没确定、测试还没证明、audit 还没闭合时,承诺已经出现,但还没有稳定落入仓库结构。

五、能量分配变的是权威权重,不是文件数量

不能把每个文件夹简单看成一个能量仓。Requirement 转成 code 后,requirement 文件并不会消失;owner doc 更新后,input 文件也仍然存在。真正发生变化的是同一语义承诺在不同载体中的 active authority,也就是解释权、约束权和证明权的重新分配。

例如,一个承诺最初出现在 raw input:

text 复制代码
"表单隐藏字段不应该参与提交。"

它进入 requirement 后,raw input 仍然保留,但当前实现的直接解释权转移到 requirement。它进入 architecture owner doc 后,长期基线解释权转移到 owner doc。它进入 code 和 tests 后,运行行为和证明权转移到实现与验证。它进入 bug note 或 log 后,历史判断变成未来 session 可恢复的记忆。

所以更准确的表述是:

text 复制代码
文件不守恒。
语义承诺的有效权重在多种载体之间重新分布。

在一个闭合切片内部,除非有明确的人类决策改变 scope, Hrepo H_{repo} Hrepo 不应该凭空增加或减少。真正应该减少的是 Frepo F_{repo} Frepo,也就是未绑定、未归属、未验证的自由语义不确定性。

AGE 的目标可以写成:
preserve Hrepo while reducing Frepo . \text{preserve }H_{repo}\quad\text{while reducing }F_{repo}. preserve Hrepowhile reducing Frepo.

需求澄清、owner-doc 对齐、测试、验证、closure audit 会把承诺从自由、模糊、可漂移的状态,绑定到稳定、可恢复、可证明的形态。

在 PHS 中, RR R 耗散的是物理能量 HH H;在 AGE 中, Hrepo H_{repo} Hrepo 表示应尽量保存的语义承诺总量,不应被当成要耗散的对象。后文的 R-flow 指降低 Frepo F_{repo} Frepo,也就是减少同一语义承诺尚未绑定、尚未归属、尚未验证时产生的自由不确定性。

六、q 与 p:稳定状态表示和变化义务表示

如果把 Hrepo H_{repo} Hrepo 看成定义在某个相空间上的标量,那么这个相空间至少需要两类共轭变量。

可以写成:
Hrepo (q,p). H_{repo}(q,p). Hrepo(q,p).

这里借用 qq q 和 pp p 这组记号来表示 AGE 中两个互补的语义维度,不把它们当作物理位置与动量。

qq q 是稳定状态表示:
qi=某个语义承诺当前以什么形式存在于仓库稳定结构中. q_i=\text{某个语义承诺当前以什么形式存在于仓库稳定结构中}. qi=某个语义承诺当前以什么形式存在于仓库稳定结构中.

它回答:现在系统是什么。

pp p 是变化义务表示:
pi=某个语义承诺对未来演化施加的方向性压力. p_i=\text{某个语义承诺对未来演化施加的方向性压力}. pi=某个语义承诺对未来演化施加的方向性压力.

它回答:系统接下来为什么需要动,以及往哪里动。

一个简单例子足以说明为什么一维情况下仍然需要 q/pq/p q/p 对偶。假设语义承诺是:
c=管理员可以导出 CSV(逗号分隔值)文件.c=\text{管理员可以导出 CSV(逗号分隔值)文件}. c=管理员可以导出 CSV(逗号分隔值)文件.

当前代码都没有 CSV 导出时,可能有两种完全不同情况:

情况 qc q_c qc pc p_c pc AI 应如何行动
CSV 明确 out of scope 当前不支持 无变化义务 不应实现
CSV 是最高优先级 active requirement 当前不支持 强变化义务 应按计划实现

只看 qq q,二者都是"当前不支持"。但 pp p 完全不同。

反过来,如果当前代码支持 CSV,但 owner doc 决定移除, qc q_c qc 仍然是"当前支持",而 pc p_c pc 变成反向变化义务。没有 pp p,AI 无法区分"稳定存在"和"应被删除但尚未删除"。

在 AGE 文档体系中, qq q 主要由这些材料承载:

  • docs/architecture/ 中的 current baseline;
  • docs/components/*/design.md 中的组件合同;
  • live code 和 exported types;
  • passing tests 和 examples;
  • schema、public contracts、runtime behavior。

pp p 主要由这些材料承载:

  • active plan;
  • backlog 或 audit finding;
  • failing test;
  • bug report;
  • open question;
  • stale-doc conflict;
  • closure gate;
  • human decision pending。

这只是职责倾向,不是固定目录映射。同一个文件可能同时携带 qq q 和 pp p。Requirement 既描述目标状态,也携带实现义务;plan 既写 current baseline,也写 closure pressure;bug note 既记录历史事实,也给未来变化施加约束。

七、开发就是把合法的 p 转换成稳定的 q

AGE 中一次正确的实现,会把合法的变化义务转换为稳定状态承诺。"完成任务"只是表层叙述,真正重要的是这次变化是否进入了可恢复、可证明的仓库结构。

仍以 CSV 导出为例。

下表中的 T(p)T(p) T(p) 表示变化义务的张力或压力总量,不是新的物理能量,只是为了标出"系统为什么还需要继续演化"。

实现前:

分量 状态
Hrequirement H_{requirement} Hrequirement 高,requirement 承载"需要支持 CSV"
Howner H_{owner} Howner 低或待更新,owner doc 未吸收该能力
Hbehavior H_{behavior} Hbehavior 低,代码未实现
Hproof H_{proof} Hproof 低,没有测试或验证
T(p)T(p) T(p) 高,plan/backlog 有变化压力

实现后:

分量 状态
Hrequirement H_{requirement} Hrequirement 仍在,但未闭合义务下降
Howner H_{owner} Howner 如果成为稳定能力,则上升
Hbehavior H_{behavior} Hbehavior 上升,代码承载行为
Hproof H_{proof} Hproof 上升,测试和验证承载证据
Hmemory H_{memory} Hmemory 上升,log/audit 记录闭合
T(p)T(p) T(p) 下降,变化义务被释放

换成工程语言,就是:

text 复制代码
active requirement / plan pressure
→ owner baseline / code behavior / proof / memory

承诺没有消失,只是从"未来需要兑现的义务"变成了"当前系统已经支持的稳定事实"。

这也解释了为什么 closure audit 不应只看 checkbox。- [x] 只能说明执行者声称某项完成了。真正的问题是:这个 pp p 是否已经转换成稳定的 qq q,还是只是从 plan 挪到了 summary,从 summary 挪到了 log,从 log 挪到了下一轮 follow-up。

八、J-flow 与 R-flow:路由不是耗散

PHS 中, JJ J 表示无损互联结构, RR R 表示耗散。AGE 中也需要区分两类完全不同的动作。

这里的 J-flowR-flow 是本文借用控制论语言创造的工程标签,并非标准控制理论术语。

J-flow 是语义承诺在正确拓扑中的搬运与转换。

例如:

  • raw input 被记录到 docs/input/
  • 需求被合成到 requirement;
  • 稳定规则进入 owner doc;
  • 计划引用 owner doc 和 live baseline;
  • code/test/log/audit 之间建立可追踪链接。

这些动作本身不一定降低不确定性。它们主要让承诺沿着正确的拓扑流动,避免被塞进错误位置。

R-flow 才真正降低 Frepo F_{repo} Frepo:

  • 人类明确裁掉 scope;
  • requirement 写出可测试 acceptance criteria;
  • owner doc 吸收稳定 baseline;
  • 自动化测试证明行为;
  • focused verification 执行真实路径;
  • independent closure audit 推翻或确认完成叙事;
  • bug note 记录非显然根因,降低未来重复漂移风险。

这一区分非常关键。很多看似勤奋的文档工作其实只是 J-flow

  • 把歧义从 input 搬到 discussion;
  • 把未决设计写进 plan;
  • 把计划总结写进 log;
  • 把 audit 初筛发现直接变成 backlog;
  • 把"应该测试"写成 closure gate,但没有真实执行。

这些可能是必要步骤,但它们主要改变自由语义能的位置,并没有真正消除自由语义能。真正危险的是把 J-flow 误认为 R-flow,把"信息移动了"误认为"系统收敛了"。

九、Park 变换:从 chat 坐标到 repo 坐标

非线性控制视角下,Park 变换的意义在于把原本隐藏在时变三相坐标中的旋转耦合,转换到更容易识别功率关系和互联结构的 d-q 坐标中。

AGE 中也有类似动作。原始 chat、产品经理资料、长上下文中的讨论,是一个时变、强耦合、隐式坐标系。需求、架构、执行、证明、历史、假设混在一起。AI 在这个坐标系中很容易把探索当基线,把计划当事实,把历史判断当现行合同。

docs/ 体系的作用,就是把这个混合语义场变换到更稳定的 repo 坐标:

坐标 职责
docs/architecture/ 当前规范架构和 owner precedence
docs/components/ 组件级合同和 schema 语义
docs/plans/ 本轮工作如何收口
docs/logs/ 发生过什么和短期上下文
docs/bugs/ 非显然缺陷和回归风险
docs/analysis/ 探索、比较、被拒绝方向
docs/testing/ 手工或探索性证明
live code/tests 当前实现事实和可执行证据

这一步更像一次坐标变换:把隐藏的语义互联结构变成可路由、可审计、可恢复的拓扑。文档分类只是这个坐标变换的外在形式。

可以说:

text 复制代码
AGE 的文件体系类似一种 Park-style 重坐标化:它把 chat 中时变、隐式、强耦合的语义量,表达到 repo 中较稳定、可路由、可审计的责任坐标中。这个过程不是无损变换,而是包含解释、归属和证据绑定的结构化转写。

十、空间、时间与守恒

如果继续沿着能量函数语言展开,AGE 中的"空间"和"时间"也可以获得更清晰的解释。

这里说的空间指语义责任空间,而不是文件系统路径本身:
space=一个承诺可以被安放、解释、约束、证明的位置集合.space=\text{一个承诺可以被安放、解释、约束、证明的位置集合}. space=一个承诺可以被安放、解释、约束、证明的位置集合.

也可以称为:
space≃semantic ownership topology.space\simeq\text{semantic ownership topology}. space≃semantic ownership topology.

例如同一个承诺"表单隐藏字段是否参与提交",可能同时落在:

  • docs/architecture/form-validation.md
  • docs/architecture/data-domain-owner.md
  • runtime code;
  • validation tests;
  • historical bug note;
  • plan closure evidence。

这些位置更像坐标轴;它们共同定义这个承诺在仓库中的空间分布,而不是组成前后相接的阶段。

这里说的时间指仓库状态的离散演化序列,而不是自然日期本身:
time=sequence of repository state transitions across sessions.time=\text{sequence of repository state transitions across sessions}. time=sequence of repository state transitions across sessions.

一次 plan closure、一次 audit overturn、一次 commit、一次 full-green baseline、一次 owner-doc update,都是 AGE 时间中的事件。

AI 没有人的连续记忆。因此,AGE 的时间不是心理时间,而是仓库可恢复的外部化时间。一个决定如果只存在聊天里,没有进入仓库,它在 AGE 时间中几乎没有存在过。

由此可以定义两个重要的均一性。

时间均一性:同一个仓库状态在不同日期、不同 AI 会话、不同上下文窗口中被重新读取时,应恢复同一组有效承诺和执行规则。

这就是 file-in/file-out 的深层含义:
时间均一性=session 平移不变性.\text{时间均一性}=\text{session 平移不变性}. 时间均一性=session 平移不变性.

如果今天 AI 知道某功能 out of scope,但明天换一个会话就不知道了,因为它只写在聊天里,那么时间均一性被破坏, Hrepo H_{repo} Hrepo 发生语义泄漏。

空间均一性:同类语义承诺无论出现在哪个局部功能中,都应遵循同类 ownership、routing 和 proof 规则。

例如权限承诺不应因为它出现在 CSV 导出按钮里就绕过权限 owner doc;schema authoring 语义不应因为它出现在某个示例里就绕过 compiler/runtime contract;复杂宿主能力不应因为当前实现方便就直接泄漏进核心 scope。

AGE 的空间不是均匀欧氏空间,而是带拓扑和曲率的责任空间:

  • protected area 是高曲率区,进入后轨迹需要改变;
  • owner doc 是势场中心,周围变化会被拉回 baseline;
  • stale docs 是坐标奇点,不应直接当真;
  • external integration 是开放端口,可能注入或移出承诺;
  • audit 是观测面,不是事实源本身。

因此 AGE 不要求所有空间点同质。它要求同类责任区域内部均一,跨区域转换遵守明确拓扑。

十一、浸入与不变性:从吸引子到目标流形

Immersion and Invariance 的核心是先构造一个目标流形,而不是把所有未知参数估准。浸入指的是:把期望的低维目标动态嵌入原系统的状态空间,使目标行为成为系统可以达到的一组状态关系。不变性指的是:一旦轨迹落到这组关系上,系统演化不会把它带离这个流形。控制器或观测器的任务,是让轨迹收敛到这个流形,并在流形上保持自洽演化。

它和吸引子概念的关系可以这样理解:吸引子回答"系统长期应该收敛到什么结构",浸入与不变性回答"在未知参数和局部不可观测存在时,怎样构造一个可收敛、可保持的目标流形"。前者定义长期结构,后者给出一种让轨迹进入并停留在该结构附近的控制设计图像。

AI 开发中也有大量永远无法完全知道的"参数":

  • 产品经理的全部真实意图;
  • 用户未来行为;
  • 外部系统完整边界;
  • legacy code 的全部历史原因;
  • 下一个 AI 会话会误解什么;
  • 某个抽象半年后的真实演化压力。

传统做法容易陷入两个极端:要么试图把所有未知都问清楚后再动,要么把未知全部吞掉直接编码。

AGE 更接近浸入与不变性的折中:

text 复制代码
不要求知道所有参数,只要求当前 slice 被嵌入并收敛到一个可关闭的不变流形里。

对应到 AGE,owner docs 定义长期吸引子;当前 plan 的 goal、non-goal、accepted assumptions、verification gates 和 closure audit 定义本次 slice 的局部目标流形。一个 slice 可以不解决所有未知,但需要说明自己被嵌入到哪个局部流形中,以及为什么完成后不会逃离这个流形。

这个流形由以下材料共同定义:

  • goal;
  • non-goal;
  • owner-doc invariants;
  • accepted assumptions;
  • blocking assumptions;
  • verification gates;
  • closure audit;
  • live code baseline。

一个计划真正应该写清楚:

text 复制代码
本 slice 允许忽略 X,因为 X 与本次 closure 正交。
本 slice 需要解决 Y,因为 Y 改变当前合同或用户可见行为。

这不会为模糊需求开绿灯。恰恰相反,它要求把不确定性分型:哪些未知可以保持未知,哪些未知需要通过人类决策或 owner-doc 对齐先消除。

十二、结构保持观测器:审计不是另一个叙事源

结构保持 PHS 观测器设计的关键启发是:观测器可以保持系统原有结构,而不是脱离系统拓扑另造一个估计器。

AGE 中的 audit 也应如此。一个好的 closure audit 会沿着同一套 owner-doc precedence、live code、tests、logs、plan gates 重新观察系统状态;实现者的完成叙述只是待验证材料。

这也是为什么 AGE 中的 closure audit 不应只问"任务是否完成",而要问:

  • live behavior 是否真的落地;
  • owner doc 是否仍描述当前基线;
  • tests 是否保护承诺而非偶然实现;
  • plan 的 Goals/Non-Goals 是否仍诚实;
  • closure evidence 是否存在于 repo,而不是只存在于 summary;
  • 有没有把 in-scope 缺陷降级成 vague follow-up;
  • 有没有把 J-flow 误报成 R-flow

审计若不保持结构,就会变成另一个高密度叙事源。它可能制造新的发现、制造新的 backlog、制造新的完成感,却没有真正降低 Frepo F_{repo} Frepo。

因此,AGE 中的 audit 应该像结构保持观测器:它按照既有事实拓扑重新估计系统状态,并用 live repo 证据校准估计;它不另造一套事实拓扑。

十三、对 AGE 实践的启发

这个非线性控制类比对 AGE 实践的价值,是指出几个可以直接改进的方法论点。新术语只有在帮助区分真实工程动作时才有意义。

1. Plan 应显式写 Reference Set

写代码和检查代码都需要超出上一阶段文件。Plan 可以更明确地要求列出本轮切片的 reference constellation:

markdown 复制代码
## Reference Set

- Context / routing:
- Active owner docs:
- Live code routes:
- Tests / verification baseline:
- Logs / bugs / known regressions:
- External contracts:
- Plan / audit evidence:

这可以避免 AI 把 plan 当作唯一事实源。

2. Plan 应显式写 Commitment Phase State

当前 plan 已经强调 baseline、goals、non-goals 和 closure gates。非线性控制视角进一步要求写清 q/pq/p q/p:

markdown 复制代码
## Commitment Phase State

- Stable state now (`q`):
- Active change pressure (`p`):
- Target stable state after closure:
- Proof that `p` was converted into stable `q`:
- Remaining pressure and why it is non-blocking:

这能区分"当前没有这个行为,因为稳定地不需要"和"当前没有这个行为,但需要实现"。

3. Closure audit 应检查语义守恒

可以增加一个问题:

text 复制代码
Did any in-scope commitment disappear, weaken, or move to a non-authoritative artifact?

这比"文档是否更新"更准确。真正要避免的是承诺在转换过程中泄漏。

4. Owner docs 应写 Stable Commitments

对重要 owner docs,可以逐步增加这类结构:

markdown 复制代码
## Stable Commitments

## Allowed Variation

## Drift / Leakage Signals

## Correction Path

这让 owner docs 更像结构方程,而不是说明书。

5. Audit prompt 应区分 J-flow 和 R-flow

审计时应问:

text 复制代码
Which changes merely routed commitments between artifacts?
Which changes actually reduced free semantic uncertainty through decision, proof, or owner-doc alignment?

这样可以避免把"写了更多文档"误判为"系统更收敛"。

十四、结语:AGE 的非线性动力系统控制图像

如果把 AGE 放在非线性动力系统控制的视角下重新理解,它可以被看成一种结构保持型 AI 工程控制系统。PHS 提供能量、互联、耗散和端口的代表性术语;浸入与不变性则补充了目标流形、未知参数和轨迹收敛的图像。

这个图像可以概括为:

  • Hrepo H_{repo} Hrepo 是跨 session 应守恒的语义承诺总量;
  • qq q 是承诺的稳定状态表示;
  • pp p 是承诺的变化义务表示;
  • 开发是把合法的 pp p 转换成稳定的 qq q;
  • J-flow 负责让承诺沿正确 owner topology 流动;
  • R-flow 负责降低未绑定、未验证、未归属的自由语义能;
  • docs 体系是从 chat 坐标到 repo 坐标的 Park 变换;
  • file-in/file-out 维护时间均一性,也就是 session 平移不变性;
  • owner docs、plans、tests、audits、logs 共同构成多端口耦合的收敛机制。

核心判断是:

AI 开发中的混乱不只是噪音,它往往是尚未被正确坐标化的语义能量。AGE 的下一步,是更清楚地建模这些语义承诺如何注入、路由、储存、转换、证明和守恒,而不是简单堆更多流程。

因此,AGE 可以被理解为:

面向 AI 高速扰动的软件工程非线性动力系统控制图像:用 owner docs 定义吸引子,用 plan 把本次 slice 嵌入局部目标流形,用 routing 保持结构,用 verification/audit 降低自由语义能,用 logs/bugs 保存跨时间的轨迹记忆。

附录:PHS 数学背景

PHS 是 van der Schaft、Maschke 等人在 1990 年代前后围绕非线性系统、广义键合图和端口互联发展出的结构化建模框架,并与 Ortega 等人的无源性控制和能量整形工作紧密交汇。它和普通状态空间模型的差别在于把能量函数和互联拓扑放到第一位置。机械系统、电路、电机、电力网络、流体网络都可以在这个视角下被看成储能元件、耗散元件和端口互联的组合。

Interconnection and Damping Assignment Passivity-Based Control(互联与阻尼配置无源性控制)进一步把这个思路用于控制设计:控制器不是简单抵消非线性,而是重新配置闭环系统的互联结构和阻尼分布,使闭环能量函数具有期望形状。结构保持观测器、PHS 网络稳定性、微电网无源互联等方向,也都继承同一个判断:保留结构往往比抹平结构更稳健。

有限维 PHS 的常见形式是:
x˙=(J(x)−R(x))∇H(x)+G(x)u,y=G(x)T∇H(x). \dot{x}=\bigl(J(x)-R(x)\bigr)\nabla H(x)+G(x)u, \qquad y=G(x)^T\nabla H(x). x˙=(J(x)−R(x))∇H(x)+G(x)u,y=G(x)T∇H(x).

其中:

符号 含义
xx x 系统状态,例如机械位置/动量、电路磁链/电荷等
H(x)H(x) H(x) 系统总能量函数
∇H(x)\nabla H(x) ∇H(x) 能量对状态的梯度,也常称为 co-energy variables;在具体端口选择下可对应力、电压、电流等共轭量
J(x)J(x) J(x) 斜对称互联矩阵,满足 J(x)T=−J(x)J(x)^T=-J(x) J(x)T=−J(x),表示无损能量路由
R(x)R(x) R(x) 半正定耗散矩阵,满足 R(x)=R(x)T⪰0R(x)=R(x)^T\succeq 0 R(x)=R(x)T⪰0,表示电阻、摩擦等耗散
G(x)G(x) G(x) 外部端口如何耦合进系统
uu u 端口输入,例如外加电压、外力
yy y 端口输出,通常与 uu u 配对形成输入功率 yTuy^Tu yTu

沿系统轨迹对 HH H 求导:
H˙=∇HTx˙=∇HTJ∇H−∇HTR∇H+∇HTGu. \dot{H} =\nabla H^T\dot{x} =\nabla H^TJ\nabla H-\nabla H^TR\nabla H+\nabla H^TG u. H˙=∇HTx˙=∇HTJ∇H−∇HTR∇H+∇HTGu.

由于 JJ J 斜对称,任意向量 aa a 都满足:
aTJa=0.a^TJa=0. aTJa=0.

所以:
H˙=−∇HTR∇H+yTu. \dot{H}=-\nabla H^TR\nabla H+y^Tu. H˙=−∇HTR∇H+yTu.

如果没有耗散和外部输入,即 R=0R=0 R=0 且 u=0u=0 u=0,则:
H˙=0. \dot{H}=0. H˙=0.

能量守恒。若 u=0u=0 u=0 但 R⪰0R\succeq 0 R⪰0,则:
H˙≤0. \dot{H}\le 0. H˙≤0.

系统能量单调不增。这就是 passivity-based control 和 energy shaping 能成立的基本原因。

把上式从 00 0 积分到 tt t,得到无源性不等式:
H(x(t))−H(x(0))≤∫0ty(τ)Tu(τ) dτ.H(x(t))-H(x(0))\le \int_0^t y(\tau)^T u(\tau)\,d\tau. H(x(t))−H(x(0))≤∫0ty(τ)Tu(τ)dτ.

它表达的意思是:系统储能的增加不会超过外部端口输入的总能量。系统可以储能、释放能量、耗散能量,但不能无中生有地产生能量。

这个不等式解释了为什么 PHS 特别适合网络系统。若两个无源系统通过功率守恒方式互联,例如:
u1=−y2,u2=y1, u_1=-y_2, \qquad u_2=y_1, u1=−y2,u2=y1,

则两个端口功率相加为:
y1Tu1+y2Tu2=y1T(−y2)+y2Ty1=0. y_1^Tu_1+y_2^Tu_2 =y_1^T(-y_2)+y_2^Ty_1 =0. y1Tu1+y2Tu2=y1T(−y2)+y2Ty1=0.

互联本身不注入也不耗散能量,只是在两个子系统之间搬运能量。因此,无源系统的无损互联仍保持无源。这条性质是 PHS 能从单个电机、机械臂、电路,扩展到微电网、网络化系统和大规模物理系统建模的关键。

最小的 canonical Hamiltonian 系统可以写成:
x=(q,p), q˙ p˙ = 0 I −I 0 ∂H∂q ∂H∂p .x=(q,p), \qquad \begin{bmatrix} \dot{q}\\ \dot{p} \end{bmatrix} = \begin{bmatrix} 0&I\\ -I&0 \end{bmatrix} \begin{bmatrix} \frac{\partial H}{\partial q}\\ \frac{\partial H}{\partial p} \end{bmatrix}. x=(q,p),q˙p˙=0−II0∂q∂H∂p∂H.

这里 qq q 是位置类变量, pp p 是动量类变量,中间的矩阵就是最基本的辛结构。它的作用不是耗散能量,而是让能量在"位置势能"和"动量动能"之间往复转换。

如果加入耗散和端口,就得到更一般的形式:
q˙ p˙ = 0 I −I 0 ∂H∂q ∂H∂p −damping terms+port input terms. \begin{bmatrix} \dot{q}\\ \dot{p} \end{bmatrix} = \begin{bmatrix} 0&I\\ -I&0 \end{bmatrix} \begin{bmatrix} \frac{\partial H}{\partial q}\\ \frac{\partial H}{\partial p} \end{bmatrix} -\text{damping terms} +\text{port input terms}. q˙p˙=0−II0∂q∂H∂p∂H−damping terms+port input terms.

电机中的 Park 变换之所以重要,是因为它把静止三相坐标中的时变旋转关系转换到 d-q 坐标中,使速度相关的交叉耦合更容易被识别为互联结构的一部分。这个交叉项从能量角度看不是普通扰动,而是能量在 d 轴、q 轴和机械动量之间流动的结构通道。

可以用一个二维斜对称矩阵看出这个事实:
S= 0 −1 1 0 ,ST=−S. S= \begin{bmatrix} 0&-1\\ 1&0 \end{bmatrix}, \qquad S^T=-S. S=01−10,ST=−S.

对任意二维向量 zz z,都有:
zTSz=0.z^TSz=0. zTSz=0.

如果一个局部动态里出现 ωSz\omega Sz ωSz,它会让 zz z 的两个分量相互旋转、交换能量形态,但不会改变二次能量 12zTz \frac{1}{2}z^Tz 21zTz:
ddt (12zTz) =zTz˙=zT(ωSz)=ωzTSz=0. \frac{d}{dt}\left(\frac{1}{2}z^Tz\right) =z^T\dot{z} =z^T(\omega Sz) =\omega z^TSz =0. dtd(21zTz)=zTz˙=zT(ωSz)=ωzTSz=0.

这就是为什么 PHS 视角会警惕"把交叉耦合项全部补偿掉"的直觉。某些交叉项并不是误差,而是系统拓扑在局部坐标中的表现。

AGE 应用开发模板

相关推荐
Jiude1 小时前
AI 写代码太快之后,团队协作反而更难了
人工智能·架构·github
BenedictHook3 小时前
潮际好麦在线使用:AI电商营销革命,10分钟生成全套商品素材
aigc·ai电商·电商工具·潮际好麦·商品图生成
ServBay3 小时前
月之暗面 Kimi Code 0.4.0 发布,终端 AI 编码助手全面采用 TypeScript,实现毫秒级启动
后端·aigc·ai编程
心疼你的一切3 小时前
高效内容生产:如何实现规模化创作
大数据·人工智能·ai·ai编程·ai写作
AI 小老六4 小时前
Claude Code 如何压缩上下文:Microcompact、Prompt Cache 与 cache_edits 工程拆解
数据库·人工智能·ai·语言模型·架构·系统架构
kyriewen4 小时前
我关掉了Copilot:因为我写的代码出现在了别人的建议里
前端·javascript·ai编程
孟健4 小时前
flomo MCP 之后,笔记管理该重做了
ai编程
1点东西4 小时前
Codex + 智谱 GLM 完整跑通教程 (全网唯一测试通过教程)
aigc·openai·ai编程