EQTY LabDocs

LangChain

guardian_agent.langchain: create_agent, LangChain's agent described and routed through the proxy, and agent_of, the SDK's agent behind one.

View as Markdown

LangChain’s create_agent, as an agent that signs its own requests.

Change one import: create_agent takes the same arguments as langchain.agents.create_agent, plus the agent’s name. It describes the agent from those arguments, routes its models through the proxy, and returns LangChain’s compiled agent, unchanged:

python
from guardian_agent.langchain import create_agent

researcher = create_agent(
    ChatOpenAI(model="gpt-4.1"),
    tools=[search_docs],
    system_prompt="You research questions using the internal docs.",
    name="researcher",
)

Needs langchain (and langgraph, which it brings): install the langchain extra.

Functions:

  • create_agent – LangChain’s create_agent, described, and routed through the proxy.
  • agent_of – The SDK’s agent behind an agent create_agent made.

langchain.create_agent

python
create_agent(model: str | BaseChatModel, tools: Sequence[BaseTool | Callable[..., Any] | dict[str, Any]] | None = None, *, name: str, system_prompt: str | SystemMessage | None = None, middleware: Sequence[AgentMiddleware[Any, Any]] = (), response_format: ResponseFormat[Any] | type[Any] | dict[str, Any] | None = None, state_schema: type[AgentState[Any]] | None = None, context_schema: type[Any] | None = None, checkpointer: Checkpointer | None = None, store: BaseStore | None = None, interrupt_before: list[str] | None = None, interrupt_after: list[str] | None = None, debug: bool = False, cache: BaseCache[Any] | None = None, transformers: Sequence[TransformerFactory] | None = None, guardian: Guardian | None = None, description: str | None = None, version: str | None = None, exclude: Sequence[str] = ()) -> CompiledStateGraph[AgentState[Any], Any, InputAgentState, OutputAgentState[Any]]

LangChain’s create_agent, described, and routed through the proxy.

The definition is built from the arguments, never from a call: every model the agent calls (its own, then its middleware’s), the system prompt, every tool the model can call (yours and middleware’s), the middleware in the order it runs, the graph’s nodes and edges, a structured response_format’s schema, and the framework’s package versions. The same arguments always give the same definition.

Example:

python
researcher = create_agent(
    "openai:gpt-4.1",
    tools=[search_docs],
    system_prompt="You research questions using the internal docs.",
    name="researcher",
)
researcher.guardian_agent.register()  # optional: fail early
researcher.invoke({"messages": [{"role": "user", "content": "..."}]})

Parameters:

  • model (str | BaseChatModel) – A LangChain chat model, or a model name such as "openai:gpt-4.1", built with init_chat_model.
  • tools (Sequence[BaseTool | Callable[..., Any] | dict[str, Any]] | None) – Tools, as langchain.agents.create_agent takes them.
  • name (str) – The agent’s name, as enrolled with viper agent add.
  • system_prompt (str | SystemMessage | None) – The system prompt.
  • middleware (Sequence[AgentMiddleware[Any, Any]]) – LangChain middleware, in the order it runs, each recorded with the settings it was made with.
  • response_format (ResponseFormat[Any] | type[Any] | dict[str, Any] | None) – A structured response format, recorded by its JSON Schema.
  • guardian (Guardian | None) – The connection to the proxy; ga.Guardian(), from VIPER_PROXY_URL, by default.
  • description (str | None) – What the agent is for.
  • version (str | None) – Your own label for this version of the agent.
  • exclude (Sequence[str]) – JSON Pointers to leave out of the definition, as for guardian_agent.Definition.
  • state_schema (type[AgentState[Any]] | None) – As LangChain takes it, passed on; not recorded.
  • context_schema (type[Any] | None) – As LangChain takes it, passed on; not recorded.
  • checkpointer (Checkpointer | None) – As LangChain takes it, passed on; not recorded.
  • store (BaseStore | None) – As LangChain takes it, passed on; not recorded.
  • interrupt_before (list[str] | None) – Nodes to pause before, passed on and recorded.
  • interrupt_after (list[str] | None) – Nodes to pause after, passed on and recorded.
  • debug (bool) – As LangChain takes it, passed on; not recorded.
  • cache (BaseCache[Any] | None) – As LangChain takes it, passed on; not recorded.
  • transformers (Sequence[TransformerFactory] | None) – Stream transformers (langchain 1.4 and later), passed on; not recorded.

Returns:

  • CompiledStateGraph[AgentState[Any], Any, InputAgentState, OutputAgentState[Any]] – LangChain’s compiled agent. Its guardian_agent attribute is the SDK’s guardian_agent.Agent.

Raises:

  • TypeError – The model can’t be routed, middleware holds a model of its own that create_agent can’t route, or the system prompt is a SystemMessage of content blocks.
  • ValueError – A model name can’t be built into a chat model; the model sends a setting no definition can record; middleware holds one JSON can’t carry and exclude doesn’t leave out; or no guardian was given and VIPER_PROXY_URL isn’t set.
  • ModelNotRoutedThroughProxy – The model is aimed somewhere other than the proxy or its provider’s API.
  • DefinitionError – The definition is invalid or holds a credential.

A call the agent later makes is refused, before it’s sent, if middleware changed it to use a model the agent wasn’t bound to (ModelNotRoutedThroughProxy), or settings or a tool the definition doesn’t describe (ValueError). Middleware that calls a model directly, rather than through the agent’s model call, can’t be seen once the agent runs: run the proxy with --require-agent-header to have those calls refused.

langchain.agent_of

python
agent_of(compiled: object) -> Agent

The SDK’s agent behind an agent create_agent made.

Also for guardian_agent.deepagents.create_deep_agent and guardian_agent.langgraph.describe_graph. The same as compiled.guardian_agent, typed, and also found on the copies LangGraph makes (with_config(), copy()), which don’t carry that attribute: call its register() at start-up to fail early on a misconfigured proxy.

Raises:

  • TypeError – compiled wasn’t made by one of those.