LangChain × TypeSafe AI · architecture
How a LangChain agent and Jev — a non-generative decision model — split one running loop between them: one does the thinking, the other judges every step it takes.
LangChain runs the agent loop. Jev never joins it — it taps it, at the framework's own middleware hooks. Every tap reads the agent's current state and returns a typed, calibrated decision that steers what the loop does next.
before_model and wrap_tool_call, Jev reads the agent's state and returns a typed decision the loop must obey. Remove the drops and you have a plain agent; the arrows that vanish are exactly what Jev adds.The split follows each model's shape. One generates open-endedly; the other answers only bounded questions — but does it in ~100–950 ms for a fraction of a cent, cheap enough to run on every step. That price is the whole reason a supervisor can exist here at all.
Neither runs the demo alone: drop the agent and nothing thinks; drop Jev and supervising every step becomes too slow and too expensive to attempt.
Each supervisor is an AgentMiddleware — the same extension surface LangChain's own router and guardrail middlewares use. Jev is called through TypeSafeClassifier; the code owns every threshold and every branch.
Runs before each model step, once there's activity to judge.
Runs on every tool call, before the tool executes.
Runs on the tool's result, before the model sees it.
“Fetch a page and summarize it” — where the page is booby-trapped with instructions to exfiltrate data. Watch control pass back and forth between the two models.
fetch_url on the target page.A demo can call two APIs side by side without their outputs ever meeting. Here they meet at the level that counts — control flow.
Jev runs at LangChain's own hooks (before_model, wrap_tool_call), not in a wrapper bolted alongside it.
The LLM does what Jev can't (generate); Jev does what the LLM is too slow and costly to do every step (judge).
A verdict becomes an injected message, a real interrupt(), or a quarantine — it changes what the graph does next, not just a dashboard.
Built on langchain-typesafe's TypeSafeClassifier, so the repo doubles as a reference others can lift.
The coordination is one-directional: Jev supervises the agent, but nothing flows back into Jev's questions. To close the loop, let the LLM draft the task-specific success rubric once at launch, then have Jev score against it every step — the model defines the standard, the supervisor enforces it.