Skip to main content
Scan a compiled LangGraph StateGraph by handing AgentGuardian a module-level reference to the graph object — no wrapper script, no HTTP server, no extra glue code.

What this example tests

  • All 10 ASI categories against an in-process LangGraph target — the swarm calls graph.ainvoke(state) directly, so adversarial prompts drive the same code path your production traffic does.
  • Tool-abuse and KB-leakage probes against a tool-bearing graph (when your graph binds tools via ToolNode or similar).
  • The LangGraphAdapter duck-types your graph: it accepts anything with ainvoke(state) or invoke(state) that returns a state dict with a messages list. LangGraph is not a runtime dependency of AgentGuardian — the adapter only imports from your target’s process.
Source: src/agent_guardian/adapters/framework/langgraph.py.

Prerequisites

  • AgentGuardian installed in the same Python environment as your LangGraph project — pip install agent-guardian, or uv sync --extra examples --extra dev in a checkout of the repo to pull the bundled fixtures.
  • A compiled LangGraph StateGraph reachable on PYTHONPATH (your project’s, or one of the bundled fixtures under examples/langgraph/).
  • A model spec — --model stub for an offline dry-run, or a real model spec (gemini:gemini-2.5-flash, openai:gpt-4o, etc.) for a graded assessment.

Run target

The simplest legal target is a single-node graph that wraps one LLM call. Save the following as my_chatbot.py somewhere on PYTHONPATH:
my_chatbot.py
The only thing AgentGuardian needs is a module-level attribute holding the compiled graph (graph above). The attribute name is up to you — you pass it after the colon in --framework-ref. If you don’t want to write your own yet, the repo ships three working fixtures under examples/langgraph/: Each one exposes graph (for --framework langgraph) and run (for the code adapter).

Run AgentGuardian

Point --framework-ref at MODULE:ATTR. The CLI imports the module normally — any import-time side effects (logging setup, env reads) fire exactly as they would in your own process.
Flag-by-flag, all of these exist in src/agent_guardian/cli.py:
  • --framework langgraph — one of adk, autogen, crewai, langgraph, openai_agents, strands.
  • --framework-ref my_chatbot:graphMODULE:ATTR (colon form preferred; MODULE.ATTR dotted form is also accepted). The attribute must be the compiled graph, i.e. the return value of StateGraph(...).compile().
  • --model stub — universal safe default. Runs offline with no LLM keys. Swap for a real model spec for a graded assessment.
  • --mode fast — caps each agent at 3 probes / 4 turns (~45s, ~$0.008 on Gemini). --mode smart / --mode full (default) for deeper runs.
  • --output md --output-path scan.md — Markdown report. Other formats: json, sarif, junit, pdf.
To scan the bundled tool-using fixture instead, the only thing that changes is the ref:

Expected output

The Markdown report opens with the scan header. Numbers depend on your --model, your graph shape, and your --mode:
A --model stub scan always comes back clean — the stub model deliberately gives the swarm nothing to attack with. Once you re-run with a real model (--model gemini:gemini-2.5-flash is the cheapest useful choice), you’ll see a populated Top findings table and a real AIVSS score.

Common errors

  • ModuleNotFoundError: No module named 'my_chatbot'. The CLI does not modify sys.path. Either install your project as editable (pip install -e .), or run the CLI from a directory where python -c "import my_chatbot" already works.
  • AttributeError: module 'my_chatbot' has no attribute 'graph'. --framework-ref resolved the module but not the attribute. Double- check the colon form (MODULE:ATTR).
  • LangGraphAdapter expected a compiled graph with .ainvoke() or .invoke(). You passed g (the uncompiled StateGraph) instead of g.compile(). The adapter requires the compiled artifact.
  • tier = T4 against a tool-bearing graph. The framework adapter doesn’t introspect node tool bindings; it marks has_tools=True, has_memory=True, touches_pii=False regardless of your graph’s actual shape. Force the strictest tier with --tier T1 when your graph carries PII or sensitive tools.

Next step

  • For a multi-agent target with role-based collaboration, read Scan a CrewAI agent.
  • For an MCP-server-backed tool surface, read Scan an MCP server.
  • For CI gating, wire the same --framework-ref invocation into GitHub Actions with --fail-under 70 and --output sarif.