Brex published a pattern for running the same AI workflow code through both Temporal Cloud in production and a lightweight in-process eval harness without code duplication. A five-engineer TypeScript team built the approach because their agents run for an hour across dozens of LLM calls, making eval-production drift expensive and risky.
The problem is structural. Durable workflow engines like Temporal persist every step result, replay history after crashes, and enforce strict determinism: no `Date.now()`, no direct I/O inside orchestration, hard payload size limits. That machinery suits long-running onboarding agents that cannot afford to lose forty minutes of progress after a pod recycle. But it breaks evals—offline runs against labeled datasets to catch regressions. You inherit persistence, task queues, workers, and replay semantics for a loop that needs none of it. The loop should be local, ephemeral, cheap enough to run hundreds of times per hour.
The dominant alternative creates a different trap. Frameworks like LangGraph and Mastra express orchestration directly in their own SDKs. The orchestration logic and the framework are the same artifact. To eval the logic, you run the framework. To ship it, you run the same framework. There is no version of the orchestration independent from the runtime. Brex's old approach was to reimplement agents in a separate eval runtime—two copies of the same logic, guaranteed to drift.
| Approach | Code Copies | Eval Harness | Production Runtime | Drift Risk | Framework Coupling |
|---|---|---|---|---|---|
| Reimplemented agents (Brex old) | 2 (prod + eval) | Separate reimplementation | Temporal Cloud | High — guaranteed drift | None |
| Coupled framework (LangGraph / Mastra) | 1 | Run full framework | Framework runtime | Low | Total — logic = framework |
| Brex decoupled adapter (new) | 1 | Lightweight in-process runner | Temporal Cloud via K8s workers | None — same code path | None — injected at execution time |
Brex's solution: write the workflow as pure business logic with no knowledge of where it runs, then inject a runtime adapter at execution time. In production, the adapter plugs into Temporal Cloud via workers on Brex's Kubernetes cluster. In evals, it plugs into a lightweight in-process runner on their in-house eval platform. LLM calls route through the Vercel AI SDK to an internal LLM Gateway that centralizes rate limiting and auth. One version of the orchestration exists. Whatever goes through eval matches what ships, eliminating a class of bugs from code drift.
Enforcement is architectural, not disciplinary. The team built the constraint into the build system: if a developer writes orchestration code depending on runtime-specific features, the build fails. Pressure to use native Temporal primitives is constant—they are powerful and tempting. The agnostic layer fails if it depends on individual developers staying within it.
The cost is real. Decoupling means orchestration loses direct access to runtime native features. Every new capability beyond the common denominator between production and eval has to be re-exposed through the agnostic interface. That wiring overhead is real engineering work. The pattern only pays off if a team genuinely needs both production durability and fast offline evaluation on the same code path. Teams running shorter agents or tolerating separate eval and production implementations should not pay this cost.
| Dimension | Benefit | Cost |
|---|---|---|
| Code parity | Eval and production run identical code — no drift class of bugs | — |
| Durability | Full Temporal Cloud durability for hour-long agents (survives pod recycles) | — |
| Eval speed | Lightweight in-process runner; hundreds of eval runs per hour | — |
| Native runtime features | — | Orchestration cannot directly use Temporal-native primitives |
| New capabilities | — | Every feature beyond common denominator must be re-exposed via agnostic interface |
| Engineering overhead | — | Adapter wiring is real up-front work; only pays off for long agents + frequent evals |
Brex's stack: TypeScript, Kubernetes, Temporal Cloud, Vercel AI SDK, an internal LLM Gateway, and an in-house eval platform. Five engineers own the platform.
The decision: if your agents run long enough that pod recycling is a failure mode, and your eval cadence is frequent enough that framework overhead slows iteration, this pattern removes the forced choice between durability and speed. Budget for the adapter wiring it replaces.