← All posts
Greg HigginsGreg Higgins #graph-engineering#graph-engineering#fluxtion#fluxtion#ai#ai#compilers#compilers

Graph Engineering Needs a Compiler图工程需要编译器

AI can generate components faster than humans can understand their combined execution. Graphs make the application structure visible. A compiler can turn that structure into a deterministic orchestrator.AI 生成组件的速度远超人类理解其组合执行逻辑的速度。图(Graph)使应用结构变得可视化,而编译器则能将这种结构转化为确定性的编排器。

AI coding has created a strange inversion: writing code is becoming cheap, while understanding what all that code will do together is becoming expensive.AI 编程带来了一种奇怪的倒置:编写代码变得廉价,而理解所有这些代码组合在一起后的行为却变得昂贵。

An LLM can add a handler, connect an API, introduce a queue, implement a retry, update some state and call another service in minutes. Each change can look perfectly reasonable when read on its own.LLM 可以在几分钟内添加处理程序、连接 API、引入队列、实现重试、更新状态并调用另一个服务。每一项更改单独看都显得非常合理。

The problem appears when those reasonable pieces interact.问题在于这些合理的片段相互作用时。

The real behaviour of an application is rarely contained in one method. It emerges from the order in which callbacks, listeners, timers, queues, retries, lifecycle hooks and state changes combine.应用的真实行为很少包含在单一方法中,而是从回调、监听器、计时器、队列、重试、生命周期钩子和状态变更的组合顺序中涌现出来的。

An LLM can now generate this orchestration faster than a human can reconstruct the execution model it is creating.现在,LLM 生成这种编排的速度,已经超过了人类重构其所创建的执行模型的能力。

This is one reason graph engineering is attracting attention. LangChain recently used the term to describe constructing agentic systems as graphs containing deterministic code, model calls, tools and complete agents. The graph constrains the paths the system may follow instead of leaving every decision to an LLM.这就是图工程备受关注的原因之一。LangChain 最近使用该术语来描述将智能体系统构建为包含确定性代码、模型调用、工具和完整智能体的图。图限制了系统可能遵循的路径,而不是将每个决策都留给 LLM。

That is an important improvement — but making the graph visible is only half the solution. The other half is deciding exactly how the graph executes.这是一个重要的改进,但让图变得可见只是解决方案的一半。另一半是决定图究竟如何执行。

AI writes locally. Systems execute globally.AI 在局部编写代码,系统在全局执行。

LLMs are often very good at implementing local behaviour.LLM 通常非常擅长实现局部行为。

Suppose an application receives a trade and must:假设一个应用收到一笔交易,并且必须:

Update position
      ↓
Recalculate risk
      ↓
Publish the result

An LLM might generate:LLM 可能会生成:

updatePosition(trade);
publishPosition();
recalculateRisk();

Every method call is valid, the code is readable, and the implementation may compile and pass many tests. But the global ordering is wrong.每个方法调用都是有效的,代码可读,实现也可能通过编译和许多测试。但全局顺序是错误的。

Nothing in those method signatures tells the compiler that risk must be recalculated before the position is published. That requirement exists somewhere outside the code: in an architecture document, in a test, in a comment, or in the mind of an experienced developer.这些方法签名中没有任何内容告诉编译器,在发布头寸之前必须重新计算风险。这一要求存在于代码之外的某个地方:在架构文档、测试、注释或资深开发者的脑海中。

The dangerous AI-generated code is not usually obvious nonsense. It is locally plausible code that subtly violates a global invariant.危险的 AI 生成代码通常不是明显的胡言乱语,而是局部看起来合理,却微妙地违反了全局不变量的代码。

The problem compounds over time. One prompt introduces retries. Another moves work onto an executor. A third adds metrics. A fourth supports another event type.这个问题会随时间累积。一个提示词引入了重试,另一个将工作移交给执行器,第三个添加了指标,第四个支持了另一种事件类型。

Each change may be reasonable in isolation while changing:每次更改在孤立状态下可能都是合理的,但却改变了:

  • execution order;执行顺序;
  • state visibility;状态可见性;
  • reentrancy;重入性;
  • failure handling;故障处理;
  • completion semantics;完成语义;
  • replay behaviour.重放行为。

The application gradually develops an execution model that no person—and no single prompt—ever explicitly designed.应用逐渐形成了一种没有任何人——也没有任何单一提示词——明确设计过的执行模型。

The loop is not the villain循环不是罪魁祸首

A small loop can be perfectly deterministic:一个小循环可以是完全确定性的:

while (running) {
    Event event = queue.take();

    updateState(event);
    calculateRisk();
    publishResult();
}

Given the same initial state and the same ordered inputs, this loop can produce the same result every time.在相同的初始状态和相同的有序输入下,这个循环每次都能产生相同的结果。

The problem is not that loops are inherently unpredictable. The problem is that real applications rarely remain one loop.问题不在于循环本身不可预测,而在于真实的应用很少保持为一个循环。

Over time, updateState publishes another event. A listener receives it. A timer refreshes reference data. A retry schedules more work. A framework invokes a lifecycle method. A callback observes some state before another callback has finished updating it.随着时间推移,updateState 发布了另一个事件,监听器接收到它,计时器刷新参考数据,重试机制调度更多工作,框架调用生命周期方法。一个回调在另一个回调完成更新之前观察到了某些状态。

The original loop has not disappeared. It has become distributed throughout the application:最初的循环并没有消失,而是分布到了整个应用中:

Event loop
   ├── listener
   │      └── callback
   │             └── queue
   ├── scheduled task
   ├── retry handler
   └── asynchronous publisher

Someone still has to understand the complete sequence.仍然需要有人理解完整的序列。

In a conventional project, that person is often a senior developer who has accumulated an unwritten model of the system over several years.在传统项目中,那个人通常是积累了多年非正式系统模型的资深开发者。

In an AI-generated project, we risk asking an LLM to become that global coordination engineer. That is a poor division of responsibility.在 AI 生成的项目中,我们冒着让 LLM 成为全局协调工程师的风险。这是一种糟糕的职责划分。

Graph engineering makes the application model visible图工程使应用模型可视化

A graph replaces implicit control flow with explicit relationships:图用显式关系取代了隐式控制流:

Trade
  ↓
Position
  ↓
Risk
  ↓
Policy
  ↓
Route

The graph says that risk depends on the updated position, policy depends on risk, and routing depends on the policy decision.图表明:风险取决于更新后的头寸,策略取决于风险,路由取决于策略决策。

That is easier to inspect than equivalent behaviour spread across queues, callbacks and listeners.这比分散在队列、回调和监听器中的等效行为更容易检查。

It is also a natural model for systems that combine ordinary code with probabilistic components:对于将普通代码与概率组件相结合的系统来说,这也是一种自然模型:

Request
   ↓
Classification agent
   ↓
Policy validation
   ↓
Human approval
   ↓
Approved action

The classification agent may remain probabilistic. The surrounding graph constrains where the model can operate and what must happen before an external action is permitted.分类智能体可能保持概率性。周围的图限制了模型可以在哪里操作,以及在允许外部操作之前必须发生什么。

Current agent graph frameworks generally make this graph explicit: nodes perform work, while edges or routing definitions determine what happens next. Microsoft’s Agent Framework, for example, describes workflows as directed graphs of executors and edges; LangGraph similarly uses nodes, state and transitions to define an agent workflow.当前的智能体图框架通常使此图显式化:节点执行工作,而边或路由定义决定下一步发生什么。例如,微软的 Agent Framework 将工作流描述为执行器和边的有向图;LangGraph 类似地使用节点、状态和转换来定义智能体工作流。

This is much better than hiding the workflow inside a large agent loop, but it still leaves an important problem: someone must author the orchestration.这比将工作流隐藏在大型智能体循环中要好得多,但仍然留下了一个重要问题:必须有人编写编排逻辑。

The graph is not the orchestrator图不是编排器

Consider a simple diamond:考虑一个简单的菱形结构:

        A
       / \
      B   C
       \ /
        D

The topology tells us that B and C depend on A, and D depends on B and C.拓扑结构告诉我们 B 和 C 依赖于 A,而 D 依赖于 B 和 C。

The diagram alone does not necessarily answer:仅凭该图并不一定能回答:

  • Does B run before C?B 是否在 C 之前运行?
  • May B and C run concurrently?B 和 C 可以并发运行吗?
  • When do their state changes become visible?它们的状态变更何时变得可见?
  • Should D run if B produced no change?如果 B 没有产生变更,D 是否应该运行?
  • What happens if C emits another event?如果 C 发出另一个事件会发生什么?
  • Is that event handled immediately or queued?该事件是立即处理还是排队?
  • What happens when B fails?当 B 失败时会发生什么?
  • When does end-of-cycle cleanup occur?周期结束清理何时发生?
  • Can D observe a partially completed update?D 能观察到部分完成的更新吗?

Workflow runtimes answer these questions through their execution semantics and the graph definition supplied by the author. That is entirely appropriate when routes must remain dynamic. But it means the global coordination plan is still authored software.工作流运行时通过其执行语义和作者提供的图定义来回答这些问题。当路由必须保持动态时,这完全合适。但这意味着全局协调计划仍然是人工编写的软件。

In applications whose components already express structural dependencies, an explicit workflow can also duplicate relationships that exist elsewhere in the program. Even when there is no literal duplication, someone still has to construct and maintain the global routing and lifecycle plan.在组件已经表达了结构依赖的应用中,显式工作流也可能重复程序中其他地方已存在的关系。即使没有文字上的重复,仍然需要有人构建和维护全局路由和生命周期计划。

Fluxtion asks a narrower question:Fluxtion 提出了一个更狭窄的问题:

When the component graph is closed and its local event semantics are known, how much of the global coordinator can a compiler derive?当组件图闭合且其局部事件语义已知时,编译器能推导出多少全局协调逻辑?

Inferred orchestration推导式编排

This is the approach I have been exploring through Fluxtion.这就是我通过 Fluxtion 探索的方法。

I did not arrive at this problem through agent frameworks. Fluxtion grew out of electronic-trading systems, where event order, latency, replay and the ability to reconstruct a decision were production requirements. The recent rise of AI-generated software has made the same coordination problem much more general.我并不是通过智能体框架接触到这个问题的。Fluxtion 源于电子交易系统,其中事件顺序、延迟、重放和重建决策的能力是生产要求。AI 生成软件的兴起使得同样的协调问题变得更加普遍。

Fluxtion treats orchestration as a compiler problem.Fluxtion 将编排视为一个编译器问题。

None of the ingredients is unprecedented. Jane Street’s Incremental maintains a dependency graph and recomputes the affected portion when inputs change; its graph may also change at runtime. Dagger uses compile-time graph analysis to generate Java that constructs and wires dependencies, while Dagger Producers extends that approach to dependent asynchronous computations. Fluxtion applies related ideas to a different layer: repeated event coordination across a closed graph of stateful business components, including event-specific dispatch, change and trigger propagation, lifecycle, reentrancy, audit and replay, specialised into a standalone Java processor.其中的成分并非前所未有。Jane Street 的 Incremental 维护一个依赖图,并在输入变化时重新计算受影响的部分;其图也可能在运行时改变。Dagger 使用编译时图分析来生成构建和连接依赖的 Java 代码,而 Dagger Producers 将该方法扩展到依赖的异步计算。Fluxtion 将相关思想应用于不同的层:跨闭合的有状态业务组件图进行重复的事件协调,包括特定于事件的调度、变更和触发器传播、生命周期、重入、审计和重放,并将其专门化为一个独立的 Java 处理器。

Developers write ordinary Java components containing local state and behaviour. References between those components form an object graph. Annotations and interfaces declare event-handling and lifecycle semantics. Depending on the authoring style, the topology may be expressed through Java object references, a fluent DSL or Spring wiring — the important point is not that every graph originates identically; it is that the author declares the structure once rather than separately implementing its runtime coordinator.开发者编写包含局部状态和行为的普通 Java 组件。这些组件之间的引用形成对象图。注解和接口声明事件处理和生命周期语义。根据编写风格的不同,拓扑结构可以通过 Java 对象引用、流畅的 DSL 或 Spring 装配来表达——重点不在于每个图的起源是否相同,而在于作者一次性声明了结构,而不是分别实现其运行时协调器。

Once the complete graph is known, the compiler analyses it and derives the orchestration.一旦整个图已知,编译器就会对其进行分析并推导出编排逻辑。

Java components
+ dependencies
+ event semantics
        ↓
Closed object graph
        ↓
Execution inference
        ↓
Compiled orchestrator
        ↓
Generated Java

Fluxtion calls the compiler technique execution inference. The programming model it enables is inferred orchestration: developers define components, dependencies and local event semantics, while the compiler derives and emits the global dispatcher.Fluxtion 将这种编译器技术称为“执行推导”(execution inference)。它所启用的编程模型是“推导式编排”(inferred orchestration):开发者定义组件、依赖和局部事件语义,而编译器推导并发出全局调度器。

Execution inference does not guess the developer’s intentions from method names or comments. It derives the consequences of explicit structure that already exists: object references, event handlers, trigger methods, lifecycle callbacks, sinks and exported services.执行推导不会从方法名或注释中猜测开发者的意图。它从已经存在的显式结构(对象引用、事件处理器、触发器方法、生命周期回调、接收器和导出服务)中推导后果。

From that structure, Fluxtion derives:基于该结构,Fluxtion 推导出:

  • which components are affected by each event;每个事件影响哪些组件;
  • their valid topological execution order;它们有效的拓扑执行顺序;
  • when changes should propagate;变更应何时传播;
  • when trigger methods become eligible;触发器方法何时变得可用;
  • lifecycle and cleanup ordering;生命周期和清理顺序;
  • audit-hook placement;审计钩子的位置;
  • queued reentrant event handling.排队的重入事件处理。

“Inferred” does not mean that the compiler guesses intent or that developers declare nothing. A component still states its local role: that it handles a particular event, triggers after an upstream change, participates in lifecycle processing or exports a service. What the developer does not write is the global coordination program — the complete route, execution order, change-propagation plan, lifecycle sequence and reentrancy behaviour. Execution inference derives that global program from the closed graph and its local declarations.“推导”并不意味着编译器在猜测意图或开发者什么都不声明。组件仍然会声明其局部角色:它处理特定事件、在上游变更后触发、参与生命周期处理或导出服务。开发者不需要编写的是全局协调程序——即完整的路由、执行顺序、变更传播计划、生命周期序列和重入行为。执行推导从闭合图及其局部声明中推导出该全局程序。

It then generates the runtime dispatcher as ordinary Java source.然后,它将运行时调度器生成为普通的 Java 源代码。

The orchestration is compiled rather than separately authored.编排逻辑是编译出来的,而不是单独编写的。

A small example一个小例子

Imagine three stateful components:想象三个有状态组件:

final class Position {

    @OnEventHandler
    public boolean onTrade(Trade trade) {
        // Update local position state.
        // Return true if downstream calculations are affected.
        return positionChanged;
    }
}

final class Risk {

    private final Position position;

    Risk(Position position) {
        this.position = position;
    }

    @OnTrigger
    public boolean recalculate() {
        // Recalculate using the updated position.
        return riskChanged;
    }
}

final class TradeGate {

    private final Risk risk;

    TradeGate(Risk risk) {
        this.risk = risk;
    }

    @OnTrigger
    public boolean evaluate() {
        // Decide whether trading remains permitted.
        return gateChanged;
    }
}

The object references express the dependency structure:对象引用表达了依赖结构:

Trade
  ↓
Position
  ↓
Risk
  ↓
TradeGate

There is no separate master loop that must manually call every component in the correct order.没有单独的主循环需要手动以正确的顺序调用每个组件。

There is also no second edge list duplicating the same relationships.也没有重复相同关系的第二个边列表。

Once these objects form a closed graph, execution inference can generate an event-specific dispatcher conceptually resembling:一旦这些对象形成闭合图,执行推导就可以生成一个特定于事件的调度器,概念上类似于:

public void onEvent(Trade trade) {
    boolean positionChanged = position.onTrade(trade);

    if (positionChanged) {
        boolean riskChanged = risk.recalculate();

        if (riskChanged) {
            tradeGate.evaluate();
        }
    }

    afterEvent();
}

The real generated processor handles more sophisticated propagation, convergent paths, triggering and lifecycle behaviour, but the principle is the same:真正的生成处理器处理更复杂的传播、收敛路径、触发和生命周期行为,但原理是一样的:

Developers define local behaviour and structural dependency. The compiler generates global coordination.开发者定义局部行为和结构依赖。编译器生成全局协调逻辑。

The output is a compiled orchestrator — by which I mean the generated Java dispatcher that encodes the event schedule, change propagation, lifecycle and reentrancy rules for this particular graph.输出是一个编译后的编排器——我指的是生成的 Java 调度器,它为该特定图编码了事件调度、变更传播、生命周期和重入规则。

Why a compiled orchestrator matters为什么编译后的编排器很重要

One source of structural truth单一的结构真理来源

In an explicitly orchestrated system, the domain objects and the workflow metadata may both represent dependencies.在显式编排的系统中,领域对象和工作流元数据可能同时表示依赖关系。

With inferred orchestration, those dependencies are the compiler input.通过推导式编排,这些依赖关系是编译器的输入。

Changing an object relationship changes the graph that is analysed. The orchestration is regenerated from that graph rather than repaired separately.更改对象关系会改变被分析的图。编排逻辑是从该图重新生成的,而不是单独修复的。

This reduces the opportunity for the application model and orchestration model to drift apart.这减少了应用模型和编排模型发生偏离的可能性。

Deterministic execution within a defined boundary定义边界内的确定性执行

A compiler can calculate a stable execution schedule from the closed graph.编译器可以从闭合图中计算出稳定的执行计划。

Given the same:给定相同的:

  • generated processor version;生成的处理器版本;
  • initial state;初始状态;
  • ordered input events;有序输入事件;
  • configuration;配置;
  • clock values;时钟值;
  • external responses;外部响应;

the same handlers can be invoked in the same order.相同的处理器可以以相同的顺序被调用。

That qualification matters. Compilation does not make networks, humans, databases or LLMs deterministic. Determinism always exists within a declared boundary.这种限定很重要。编译并不能使网络、人类、数据库或 LLM 变得确定性。确定性始终存在于声明的边界内。

Inside that boundary, ordering is encoded in the generated schedule rather than emerging from listener-registration order, framework callback timing or an LLM recreating the control flow in another file.在该边界内,顺序被编码在生成的计划中,而不是从监听器注册顺序、框架回调时序或 LLM 在另一个文件中重建控制流中涌现。

An inspectable runtime artefact可检查的运行时工件

The orchestrator is generated source code.编排器是生成的源代码。

It can be read in an IDE, committed, compared between versions and stepped through with an ordinary debugger.它可以在 IDE 中阅读、提交、在版本间进行比较,并使用普通调试器进行单步调试。

The graph can also be exported and inspected.图也可以导出并检查。

That gives a reviewer three related views of the system:这为审查者提供了关于系统的三个相关视图:

Declared components
        ↓
Inferred graph
        ↓
Generated execution code

The generated code is not merely an optimisation detail. It is an executable description of how the graph will run.生成的代码不仅仅是一个优化细节,它是关于图如何运行的可执行描述。

Replay and audit重放和审计

When dispatch order and audit points are generated from the same graph, replay becomes a structural capability rather than an afterthought.当调度顺序和审计点从同一个图生成时,重放就成为了一种结构性能力,而不是事后补救。

A recorded sequence of inputs can be sent through the same processor version to reproduce a decision path.记录的输入序列可以通过相同的处理器版本发送,以重现决策路径。

The system can record which nodes were reached, which state changed and which downstream actions were triggered.系统可以记录到达了哪些节点、哪些状态发生了变化以及触发了哪些下游操作。

This is particularly valuable when the software is making operational, financial or safety-related decisions.当软件在进行运营、财务或安全相关决策时,这一点尤其有价值。

Specialised execution专门化执行

A general graph runtime must retain machinery for many possible graphs.通用图运行时必须保留用于许多可能图的机制。

A compiled orchestrator only needs to execute one known graph.编译后的编排器只需要执行一个已知的图。

It can generate event-specific paths, call components directly and avoid repeatedly interpreting generic routing metadata. It can also avoid visiting unaffected parts of the graph when an upstream value has not changed.它可以生成特定于事件的路径,直接调用组件,并避免重复解释通用路由元数据。当上游值未更改时,它还可以避免访问图中未受影响的部分。

Fluxtion generates a flat, specialised dispatcher from a topologically ordered plan rather than walking a generic reactive graph for every event.Fluxtion 从拓扑排序的计划中生成扁平的、专门化的调度器,而不是为每个事件遍历通用响应式图。

Performance is not the main argument here, but it is a natural consequence of specialising the coordination layer.性能并不是这里的主要论点,但它是专门化协调层后的自然结果。

A safer division of labour for AI为 AI 提供更安全的劳动分工

An LLM can still write the wrong business rule.LLM 仍然可能编写错误的业务规则。

It can still choose the wrong component or declare the wrong dependency.它仍然可能选择错误的组件或声明错误的依赖。

A compiler cannot manufacture requirements that were never expressed.编译器无法制造从未表达过的需求。

But execution inference narrows the responsibility given to the model.但执行推导缩小了赋予模型的责任范围。

Instead of asking the LLM to generate:与其要求 LLM 生成:

  1. the components;组件;
  2. the dependencies;依赖;
  3. the routing layer;路由层;
  4. the scheduling behaviour;调度行为;
  5. the lifecycle coordination;生命周期协调;
  6. the audit plumbing;审计管道;

we can ask it to produce components, rules and explicit relationships.我们不如要求它生成组件、规则和显式关系。

The compiler then derives a consistent orchestrator from that structure.编译器随后从该结构中推导出一致的编排器。

Errors become visible structural claims rather than accidental interactions hidden across callbacks.错误变成了可见的结构性主张,而不是隐藏在回调中的意外交互。

Probabilistic islands in a deterministic sea确定性海洋中的概率岛屿

A compiled graph does not make an LLM deterministic — nor should it pretend to.编译后的图并不能使 LLM 变得确定性——也不应假装如此。

A model call may return a different answer. A human may make a different decision. An API may fail. Inputs may arrive in a different order.模型调用可能会返回不同的答案。人类可能会做出不同的决定。API 可能会失败。输入可能会以不同的顺序到达。

The useful distinction is between the parts that are intended to reason and the parts that are intended to enforce.有用的区别在于:旨在进行推理的部分与旨在进行强制执行的部分。

Request
  ↓
Approved context construction
  ↓
LLM
  ↓
Schema validation
  ↓
Policy checks
  ↓
Human approval when required
  ↓
Permitted action

The LLM remains a probabilistic node.LLM 仍然是一个概率节点。

The surrounding system can deterministically control:周围的系统可以确定性地控制:

  • which information the model receives;模型接收哪些信息;
  • which tools it may request;它可以请求哪些工具;
  • how its output is validated;其输出如何被验证;
  • which policies apply;适用哪些策略;
  • when human approval is mandatory;何时必须进行人工审批;
  • which external actions are permitted;允许哪些外部操作;
  • what evidence is retained.保留哪些证据。

A useful design principle is:一个有用的设计原则是:

Keep probabilistic reasoning in explicit islands. Compile the deterministic sea around them.将概率推理保留在显式的岛屿中,并围绕它们编译确定性的海洋。

Dynamic agent graph runtimes remain valuable for long-running work, runtime-created paths, checkpointing, human interaction and model-directed delegation. LangGraph, for example, deliberately supports both constrained graph paths and more dynamic agent behaviour.动态智能体图运行时对于长期运行的工作、运行时创建的路径、检查点、人类交互和模型驱动的委派仍然很有价值。例如,LangGraph 就特意支持约束图路径和更动态的智能体行为。

The two approaches can compose:这两种方法可以组合使用:

Dynamic agent workflow
          ↓
Compiled policy and control graph
          ↓
Operational systems

Interpret the parts that must remain dynamic.解释那些必须保持动态的部分。

Compile the parts that should not improvise.编译那些不应即兴发挥的部分。

The compiler idea is old. The pressure is new.编译器的想法很古老,但压力是新的。

Fluxtion sits at the intersection of established ideas rather than claiming a new primitive. Incremental-computation systems restrict work to affected subgraphs; compile-time dependency-injection systems generate inspectable wiring; synchronous dataflow languages such as Lustre statically schedule closed graphs.Fluxtion 处于既定思想的交叉点,而不是声称发明了新的原始概念。增量计算系统将工作限制在受影响的子图中;编译时依赖注入系统生成可检查的装配代码;诸如 Lustre 之类的同步数据流语言对闭合图进行静态调度。

Fluxtion applies those ideas to repeated event coordination across ordinary stateful Java components: event-specific dispatch, change and trigger propagation, lifecycle, reentrancy, audit and replay, specialised into a generated dispatcher.Fluxtion 将这些思想应用于跨普通有状态 Java 组件的重复事件协调:特定于事件的调度、变更和触发器传播、生命周期、重入、审计和重放,并将其专门化为一个生成的调度器。

What has changed is the economic context. For most of software history, writing code was expensive, and it was reasonable for developers to spend substantial effort manually constructing the coordination layer around it. AI is making code generation cheap; understanding and trusting the combined behaviour of that code is not.改变的是经济背景。在大多数软件历史中,编写代码很昂贵,开发者花费大量精力手动构建其周围的协调层是合理的。AI 使得代码生成变得廉价;理解并信任这些代码组合后的行为却并非如此。

Graph engineering makes the application structure explicit. Execution inference makes the deterministic coordination explicit.图工程使应用结构显式化。执行推导使确定性协调显式化。

See it run查看运行效果

The Fluxtion Playground requires no installation, account or API key. You can edit Java, generate the processor, inspect the inferred graph and generated source, run events and step through the audit trail from the browser.Fluxtion Playground 无需安装、注册或 API 密钥。你可以在浏览器中编辑 Java 代码、生成处理器、检查推导出的图和生成的源代码、运行事件并单步执行审计追踪。

For examples that use hosted source generation, the graph definition is sent to Fluxtion’s build-time generator and the generated Java is returned to the playground. The hosted generator is the commercial part of the production toolchain; the generated source belongs to the project and the resulting processor runs on the open runtime with no cloud call or API key.对于使用托管源代码生成的示例,图定义被发送到 Fluxtion 的构建时生成器,生成的 Java 代码返回给 playground。托管生成器是生产工具链的商业部分;生成的源代码属于项目,生成的处理器在开放运行时上运行,无需云调用或 API 密钥。

Open the accept/reject example in the Fluxtion Playground. It models a payment-authorisation flow with guarded approval and decline branches. Each branch fans out to independent actions and then converges on a final decision. Inspect AcceptRejectProcessor.java beside the inferred graph, run events and step through the audit trail for each decision.在 Fluxtion Playground 中打开 accept/reject 示例。它模拟了一个带有受保护审批和拒绝分支的支付授权流程。每个分支发散到独立的操作,然后汇聚到最终决策。检查 AcceptRejectProcessor.java 以及推导出的图,运行事件并为每个决策单步执行审计追踪。

Fluxtion Playground showing an accept/reject payment graph beside the generated AcceptRejectProcessor.java orchestrator

The two compiler artefacts side by side: the inferred GraphML graph and generated Java orchestrator, including guard checks, dirty-state propagation and audit hooks derived from the component graph. Click to view full size.两个编译器工件并排显示:推导出的 GraphML 图和生成的 Java 编排器,包括从组件图中导出的守卫检查、脏状态传播和审计钩子。点击查看大图。

The code-generation examples show the same deterministic dispatcher produced from several authoring styles, while the inferred orchestration and execution inference pages describe the programming model and compiler technique in more detail.代码生成示例展示了从几种编写风格中产生的相同确定性调度器,而推导式编排和执行推导页面更详细地描述了编程模型和编译器技术。

From generated code to generated systems从生成的代码到生成的系统

Graph engineering is an important response to AI-generated software.图工程是对 AI 生成软件的重要响应。

It moves system structure out of hidden control flow and into something humans and machines can inspect.它将系统结构从隐藏的控制流中移出,变为人类和机器可以检查的内容。

But graph engineering should not always stop at drawing a graph and handing it to a generic runtime.但图工程不应总是止步于绘制图表并将其交给通用运行时。

Where topology is genuinely dynamic, runtime orchestration is appropriate.在拓扑结构真正动态的地方,运行时编排是合适的。

Where the graph is closed, stable and operationally important, its coordination can become compiler output.在图闭合、稳定且在运营上很重要的地方,其协调逻辑可以成为编译器的输出。

That changes the role of the developer—and of the LLM. They define the components, the local behaviour, and the dependencies and constraints. The compiler derives the execution paths, lifecycle and coordination.这改变了开发者——以及 LLM——的角色。他们定义组件、局部行为以及依赖和约束。编译器推导出执行路径、生命周期和协调逻辑。

Graph engineering makes the application model visible. Execution inference turns that model into a compiled orchestrator.图工程使应用模型可视化。执行推导将该模型转化为编译后的编排器。

AI should help us describe and build the machine.AI 应该帮助我们描述和构建机器。

The compiler should generate the orchestrator.编译器应该生成编排器。