Skip to content

Progressive Crystallization

One of the costliest anti-patterns in production AI engineering is permanent stochasticity: keeping every routing decision and multi-step tool sequence inside an LLM call long after the underlying domain patterns have stabilized.

Early in a feature’s lifecycle, you want the flexibility of DecidedBy.Model routers and multi-tool @Agent loops so your system can handle messy, unanticipated user inputs. Over weeks of production traffic, however, 80–95% of executions often follow repeatable structural patterns:

  • A DecidedBy.Model router consistently picks EnterpriseApprovalAgent whenever order.amountCents > 100_000 or order.region === "EU".
  • An @Agent with four @Tool bindings calls FetchInvoiceTool followed immediately by ValidateTaxIdTool in the exact same order on 99% of runs.

Progressive Crystallization is the architectural practice of systematically identifying these settled stochastic Desire Paths via content-addressed revision hashes (agboss describe --json), multi-run pass@k vs pass^k reliability benchmarks, and execution traces (ExecutionRecord and Langfuse / OpenTelemetry spans), and replacing them in place without changing neighbor contracts:

  • DecidedBy.Model @Router and @Arbiter $\to$ DecidedBy.Code (0ms LLM latency, $0.00 token spend)
  • DecidedBy.Model @InputGuardrail, @OutputGuardrail, and @Judge $\to$ DecidedBy.Code (GuardrailHandler / deterministic JudgeHandler inspecting DTOs and toolCalls at $0.00 cost)
  • Repetitive @Tool sequences inside an @Agent $\to$ deterministic @Action steps or @ToolInterceptor gates
  • Model-summarized @Compaction $\to$ CompactionStrategy.Custom (CompactionHandler) writing structured facts into a knowledge graph or vector store
  • Human-in-the-loop ChannelOutcome.awaitReply() pauses on low-risk cases $\to$ immediate auto-approved ChannelOutcome.decided(...)

Step 1: Content-Addressed Revision Snapshots (agboss describe --json)

Section titled “Step 1: Content-Addressed Revision Snapshots (agboss describe --json)”

In typical agent frameworks, production traces in Langfuse or OpenTelemetry quickly drift from the Git repository: when looking at a trace from yesterday, neither an engineer nor an AI coding agent can tell whether the prompt text, DTO schema, or graph topology has changed since that run.

In AGBoss, npx agboss describe --json exports a deterministic, machine-readable snapshot of your entire @Application without requiring any API keys:

The JSON envelope includes three cryptographic content hashes:

Hash Field Scope What It Hashes
configHash Per @Workflow Complete graph topology: start/finish nodes, step sequence, .switch() / .chooseOne() edges, .joinQuorum() rules, and .onError() paths
promptHash Per @Agent / @Router / @Arbiter / @Guardrail Resolved system prompt template (prompt + promptUrls) and model configuration
schemaHash Per DTO Class Normalized JSON Schema compiled from @Text, @Integer, @Decimal, @Flag, @OneOf, @ListOf, and @Nested decorators

Every ExecutionRecord (result.record) and step trace emitted to OnExecutionEnd records these exact hashes (configHash, promptHash, schemaHash).


Step 2: Crystallizing a DecidedBy.Model Router into DecidedBy.Code

Section titled “Step 2: Crystallizing a DecidedBy.Model Router into DecidedBy.Code”

Suppose you launch a workflow with a DecidedBy.Model router (OrderTriageModelRouter) that classifies incoming orders using a fast decision model (typesafe/jev-1.13). Once execution traces for OrderTriageModelRouter’s promptHash and OrderTriageDto’s schemaHash confirm that the routing boundary is a pure function of OrderTriageDto fields (or a deterministic database lookup via an @Injectable() service), you (or your coding agent) crystallize the router in place by switching decidedBy to DecidedBy.Code:

Notice what did not change:

  • The @Workflow definition (*.workflow.ts) is completely untouched — .toRouter(OrderTriageRouter).chooseOne(...) works identically whether OrderTriageRouter is DecidedBy.Model or DecidedBy.Code.
  • Downstream Path Scope availability (Produced<Dto, P>) is preserved.
  • Latency for this node drops from ~150–400ms to <0.1ms, and token spend drops to $0.00.

Step 3: Crystallizing Repetitive @Tool Chains into an @Action

Section titled “Step 3: Crystallizing Repetitive @Tool Chains into an @Action”

A second prime target for crystallization is an @Agent whose traces show a fixed sequence of tool calls before producing a structured DTO.

Instead of paying an LLM to orchestrate ToolA -> ToolB on every turn:

  1. Extract the deterministic API/database calls into an @Injectable() service or a dedicated @Action node upstream of the @Agent.
  2. Wire .toAction(FetchAndEnrichAction).returns(EnrichedContextDto).toAgent(AnalystAgent) in the workflow.
  3. Now the deterministic data fetching executes with 0 LLM tokens and full ExecutionContext.step.idempotencyKey deduplication, while AnalystAgent receives the pre-fetched EnrichedContextDto in a single, KV-cache-friendly turn.

Step 4: Discovering Crystallization Candidates (pass@k vs pass^k) & Verifying Zero Regression

Section titled “Step 4: Discovering Crystallization Candidates (pass@k vs pass^k) & Verifying Zero Regression”

When running an @EvalSuite with --runs <k> (for example, k = 5), AGBoss reports two complementary metrics for every case:

  • pass@k ($\ge 1$ of $k$ runs passed): Measures whether the model can solve the task.
  • pass^k ($k$ of $k$ runs passed): Measures whether the workflow solves the task reliably on every production execution.

A case with high pass@k (1.00) but low pass^k (0.20–0.60) is the canonical signal of a stochastic step that should be crystallized into a DecidedBy.Code router, guardrail, @ToolInterceptor, or @Action.

Before promoting a crystallized component to production, verify that end-to-end quality, routing accuracy, and @Judge pass rates remain identical (while cost and latency drop):

The Progressive Crystallization Radar in agboss hub joins agboss describe --json (configHash, promptHash, schemaHash), stored ExecutionRecords (steps[].decision, inputHash, toolCalls), and EvalRunReport artifacts to highlight DecidedBy.Model routers whose decisions are invariant per inputHash and @Agent steps with deterministic tool sequences or low pass^k. See Evaluation, Golden Sets & A/B Profiles for full details on @EvalSuite, pass@k / pass^k, and CI regression gates.