Skip to main content

Agent User Interaction Protocol (AG-UI)

还没翻译译自英文(docs.langchain.com)本页 37 段都还没译

Agent User Interaction Protocol (AG-UI) is an open, lightweight, event-based protocol that standardizes how AI agents connect to user-facing applications. Exposing a deep agent over AG-UI turns its run into a typed event stream (messages, tool calls, reasoning, state, and lifecycle) that any AG-UI client can consume, so you can drive a frontend without coupling it to LangGraph internals.

Note

AG-UI is designed for agent-to-user interaction: the connection between an agentic backend and a user-facing frontend. It is distinct from the other Deep Agents protocols:

Quickstart

Serve a deep agent as a LangGraph graph, then connect the TypeScript @ag-ui/langgraph adapter so AG-UI clients can drive it.

Install dependencies

Install Deep Agents, the LangGraph CLI, and the AG-UI LangGraph adapter:

npmyarnpnpm

npm install @ag-ui/langgraph deepagents @langchain/langgraph-cli

A deep agent created with createDeepAgent (create_deep_agent in Python) is a LangGraph graph. Expose it to AG-UI clients by serving it as a LangGraph server, then point the AG-UI adapter at that server.

Create a deep agent

Define the agent and export the graph so a LangGraph server can load it.

agent.ts
import { createDeepAgent } from "deepagents";

export const agent = createDeepAgent({
  model: "anthropic:claude-sonnet-4-6",
  systemPrompt: "You are an expert researcher.",
});

Serve the agent

Register the graph in a langgraph.json file at your project root.

langgraph.json
{
  "dependencies": ["."],
  "graphs": {
    "deep_agent": "./agent.ts:agent"
  },
  "env": ".env"
}

Start the LangGraph development server. It exposes the graph over HTTP at http://localhost:2024.

npx @langchain/langgraph-cli dev

Connect the AG-UI adapter

The TypeScript @ag-ui/langgraph adapter wraps the running graph as an AG-UI agent that any client can drive. Point it at the LangGraph server and name the graph to load. This works whether the graph was authored in Python or TypeScript.

ag-ui agent
import { LangGraphAgent } from "@ag-ui/langgraph";

const agent = new LangGraphAgent({
  graphId: "deep_agent",
  deploymentUrl: "http://localhost:2024",
});

AG-UI LangGraph adapter on npm

The @ag-ui/langgraph package implements the AG-UI protocol for LangGraph graphs, including deep agents.

Stream events

AG-UI is an event stream. As a deep agent runs, the adapter translates its LangGraph execution into typed AG-UI events. A client subscribes to those events and updates as they arrive, rather than waiting for the final answer.

A deep agent run maps onto many AG-UI event types. The main ones, among others:

Deep agent activityAG-UI events
Run lifecycleRUN_STARTED, RUN_FINISHED, RUN_ERROR
Graph node progressSTEP_STARTED, STEP_FINISHED
Assistant textTEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT, TEXT_MESSAGE_END
Tool callsTOOL_CALL_START, TOOL_CALL_ARGS, TOOL_CALL_END, TOOL_CALL_RESULT
ReasoningREASONING_START, REASONING_MESSAGE_CONTENT, REASONING_END
Shared state (todos, subagents, custom keys)STATE_SNAPSHOT, STATE_DELTA
Conversation historyMESSAGES_SNAPSHOT

State updates use STATE_SNAPSHOT for a full baseline and STATE_DELTA (JSON Patch, RFC 6902) for incremental changes, so a client can keep todos, plans, and subagent status in sync without re-sending the whole state on every step.

To watch the stream directly, run the agent with a subscriber. Each event has a matching on…Event callback:

observe.ts
import { LangGraphAgent } from "@ag-ui/langgraph";

const agent = new LangGraphAgent({
  graphId: "deep_agent",
  deploymentUrl: "http://localhost:2024",
  initialMessages: [
    { id: "1", role: "user", content: "Research the AG-UI protocol." },
  ],
});

await agent.runAgent(
  {},
  {
    onTextMessageContentEvent({ event }) {
      process.stdout.write(event.delta);
    },
    onToolCallStartEvent({ event }) {
      console.log(`\n[tool] ${event.toolCallName}`);
    },
    onStateSnapshotEvent({ event }) {
      console.log("\n[state]", event.snapshot);
    },
    onRunFinishedEvent() {
      console.log("\n[done]");
    },
  },
);

When a deep agent pauses for human input, the run finishes with an interrupt. By default, @ag-ui/langgraph emits a legacy on_interrupt custom event alongside RUN_FINISHED. To receive the structured AG-UI interrupt outcome on RUN_FINISHED (outcome.type === "interrupt"), set emitInterruptOutcome: true when you construct the agent:

const agent = new LangGraphAgent({
  graphId: "deep_agent",
  deploymentUrl: "http://localhost:2024",
  emitInterruptOutcome: true,
});

Resume the run by sending the standard AG-UI resume field on the next input:

const input = {
  threadId: "t1",
  runId: "r2",
  messages: [],
  resume: [
    { interruptId: "int-abc", status: "resolved", payload: { approved: true } },
  ],
};

For the interrupt model itself, see Human-in-the-loop.

Info

For the complete event schema, see the AG-UI events reference.

Connect a frontend

Any AG-UI client can drive a deep agent exposed over the protocol, so you do not have to build message rendering, streaming, or state sync yourself. Point the client at the adapter (or a runtime that wraps it) and select the agent by its graphId.

CopilotKit

React chat runtime with AG-UI support for LangGraph and Deep Agents, including the Python FastAPI bridge.

AG-UI clients

The full list of AG-UI clients and SDKs, including terminal and mobile clients.

Build a custom client

Consume the event stream directly with the AG-UI SDK to build your own interface.

Programmatic API

LangGraphAgent connects to a deep agent on a LangGraph server and exposes it as an AG-UI agent. Construct it with the graph to load, then drive it with a few methods.

import { LangGraphAgent } from "@ag-ui/langgraph";

const agent = new LangGraphAgent({
  graphId: "deep_agent",              // matches a key in langgraph.json
  deploymentUrl: "http://localhost:2024",
});
  • runAgent(parameters?, subscriber?): Run the agent and stream AG-UI events to the subscriber's on…Event callbacks (see Stream events). Resolves when the run finishes.
  • subscribe(subscriber): Attach a persistent subscriber that receives events across every run, rather than for a single call.
  • abortRun(): Cancel the run in progress.

To seed input, pass initialMessages to the constructor, or call addMessage or setMessages before running.

See also