LangGraph owns the state machine: nodes, edges, and retries. ValGuard owns the contract on each model completion before the next node reads it. Point your chat model client at ValGuard, or validate inside a node, so a failed schema or policy check cannot become the next node's input.
When you need this
Node A classifies a ticket into {team, urgency}. Node B opens a refund tool when team == "billing". The model invents team: "billing_escalation". Without a gate, the router falls through or hits the wrong tool. With ValGuard, an enum rule fails, you re-ask or block, and graph state never carries the bad label.
Architecture
flowchart LR
G[LangGraph node] --> C[Chat model client]
C --> VG[ValGuard proxy]
VG --> M[Upstream model]
M --> VG
VG -->|pass| S[Update graph state]
VG -->|block| R[Route to human or end]
Keep LangGraph for control flow. Put the trust boundary on the OpenAI-compatible path so every language and worker that shares the same agent slug gets the same rules.
Setup (recommended pattern)
- Create a ValGuard agent per graph role (classifier, drafter, tool planner).
- Attach schema and policy packs; start in shadow mode.
- Point the LangChain / LangGraph chat model
base_urlat ValGuard withX-VG-Agent. - Store
validation_passed(or the block envelope) in graph state. Route on that field, not on raw text. - Enforce when shadow metrics look stable.
Code and config
Python client pointed at ValGuard (OpenAI-compatible):
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.valguard.ai/v1",
api_key=os.environ["VG_API_KEY"],
default_headers={"X-VG-Agent": "support-classifier"},
)
resp = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[
{
"role": "system",
"content": 'Return JSON only: {"team":"billing"|"fraud"|"general","urgency":1-5}',
},
{"role": "user", "content": "Card charged twice on invoice 4412"},
],
)
print(resp.choices[0].message.content)
curl for the same call:
curl -s https://api.valguard.ai/v1/chat/completions \
-H "Authorization: Bearer $VG_API_KEY" \
-H "X-VG-Agent: support-classifier" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"messages": [
{"role": "user", "content": "Card charged twice on invoice 4412"}
]
}'
In the graph, treat a block as a typed failure edge. Do not call tools after a failed validation.
On validation failure
| Mode | Graph behavior |
|---|---|
| Pass | Write parsed JSON into state; follow the happy edge |
| Re-ask | ValGuard may retry once; use the final response |
| Block | Take an escalate or end edge; attach rule IDs to the ticket |
| Shadow | Log only; still update state as you do today until you enforce |
Pair this with the Agentic Tool Call Validator pattern when a node proposes tools.
Latency
Engine: microseconds per pack. HTTP layer: about 0.36 ms p50 with a mocked upstream. A three-step ValGuard playbook (if you use one instead of LangGraph) adds about 1.8 ms (support archetype) to 1.4 ms (RAG archetype) p50. Model time still dominates.
Block and re-ask buffer the full reply. Warn, log, and shadow can stream. See methodology and Trust.
Correlating IDs
Put the LangGraph thread_id / run id in your logs next to ValGuard's X-Request-Id and X-Trace-Id. If you already emit traceparent, send it on the chat request so both systems share one trace tree.
What this does not cover
- LangGraph checkpointing, interrupts, and human-in-the-loop remain LangGraph's job.
- ValGuard does not replace LangGraph as a durable state machine.
- Framework-native validators in one repo do not automatically protect other services; the proxy does.
- Claims with no rule signature still pass.
- There is no local ValGuard runtime for offline graph tests; use shadow mode on hosted traffic or mock the proxy in CI.
Deployment
Hosted SaaS by default. Enterprise self-host only with a license. No public Docker image or CLI runtime. See Trust and pricing (Developer $69, Growth $149, Production $399, Enterprise from $1499).
Related
- Orchestration: playbooks vs keeping LangGraph
- ValGuard + n8n
- ValGuard + OpenAI Agents SDK
- How ValGuard complements LangGraph, CrewAI, and AutoGen
- Multi-agent orchestration patterns
- Chain agents tutorial
FAQ
Do I need a ValGuard playbook if I already have LangGraph? No. Keep LangGraph. Use ValGuard as the validation layer on model calls. Use a ValGuard playbook when you want the graph and the rules in one place.
Can I validate only some nodes? Yes. Point only those chat clients at ValGuard, or use different X-VG-Agent values per node role.
What about streaming tokens into the UI? Use warn/log/shadow if you need token-by-token output. Block and re-ask buffer first.
Exit cost? Export playbooks as valguard-playbook-template/1 JSON and pull per-agent validators from the API. Org-wide policy export is not shipped yet.
Next step
Start with the quickstart, then shadow mode rollout on one classifier node before you gate tool nodes.