assistant-ui Runtime 架构与后端集成

Runtime 抽象层:将 UI 原语与后端解耦,支持 Vercel AI SDK、LangGraph、自定义 SSE 等多种后端切换。

#type / concept #status / evergreen #tech / dev / frontend #tech / ai

[!info] related notes

assistant-ui Runtime 架构与后端集成

Runtime 是 assistant-ui 的核心抽象层。所有 UI 原语通过 Runtime 获取状态和触发操作,与后端实现完全解耦。

架构概览

┌──────────────────────────────────┐
│  UI 原语 (Thread, Message...)    │
│  ↕ AssistantRuntimeProvider      │
├──────────────────────────────────┤
│  Runtime 接口                    │  ← 统一的运行时抽象
├──────────────────────────────────┤
│  useChatRuntime (Vercel AI SDK)  │
│  useLangGraphRuntime             │
│  useDataStreamRuntime            │
│  useLocalRuntime (自定义)        │
└──────────────────────────────────┘

AssistantRuntimeProvider

所有原语必须包裹在 Provider 内:

// app/layout.tsx 或页面组件
import { AssistantRuntimeProvider } from "@assistant-ui/react";

export default function ChatLayout({ children }) {
  const runtime = useChatRuntime({ api: "/api/chat" });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      {children}
    </AssistantRuntimeProvider>
  );
}

Vercel AI SDK 集成

最常用的运行时,连接 Next.js API Route:

// app/chat/page.tsx
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";

function ChatPage() {
  const runtime = useChatRuntime({
    api: "/api/chat",
    // 可选配置
    maxSteps: 5,           // 最大工具调用轮次
    onFinish: (message) => {
      console.log("生成完成:", message);
    },
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <Thread />
    </AssistantRuntimeProvider>
  );
}
// app/api/chat/route.ts
import { openai } from "@ai-sdk/openai";
import { streamText } from "ai";

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: openai("gpt-4o"),
    messages,
    tools: {
      search: {
        description: "搜索知识库",
        parameters: z.object({ query: z.string() }),
        execute: async ({ query }) => {
          return await searchKnowledgeBase(query);
        },
      },
    },
  });

  return result.toDataStreamResponse();
}

LangGraph 集成

用于需要复杂 Agent 工作流的场景:

// app/chat/page.tsx
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";

function AgentChatPage() {
  const runtime = useLangGraphRuntime({
    apiUrl: "/api/langgraph",
    // LangGraph 特定配置
    assistantId: "agent",
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <Thread />
    </AssistantRuntimeProvider>
  );
}

自定义数据流 Runtime

连接任意 SSE / WebSocket 后端:

// app/chat/page.tsx
import { useDataStreamRuntime } from "@assistant-ui/react-data-stream";

function CustomBackendChat() {
  const runtime = useDataStreamRuntime({
    // 自定义数据流适配
    adapter: {
      sendMessage: async (messages) => {
        const response = await fetch("/api/chat", {
          method: "POST",
          body: JSON.stringify({ messages }),
        });
        return response.body;  // 返回 ReadableStream
      },
    },
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <Thread />
    </AssistantRuntimeProvider>
  );
}

useLocalRuntime

完全本地的运行时,用于自定义后端或测试:

// 自定义运行时实现
import { useLocalRuntime } from "@assistant-ui/react";

function CustomChat() {
  const runtime = useLocalRuntime({
    // 自定义消息处理
    run: async (messages) => {
      const response = await myCustomAPI(messages);
      return {
        content: [{ type: "text", text: response }],
      };
    },
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <Thread />
    </AssistantRuntimeProvider>
  );
}

运行时配置对比

运行时包名适用场景
useChatRuntime@assistant-ui/react-ai-sdkNext.js + Vercel AI SDK
useLangGraphRuntime@assistant-ui/react-langgraphLangGraph Agent 工作流
useLangChainRuntime@assistant-ui/react-langchainLangChain 链式调用
useDataStreamRuntime@assistant-ui/react-data-stream自定义 SSE/数据流
useLocalRuntime@assistant-ui/react完全自定义后端
useAgUiRuntime@assistant-ui/react-ag-uiAG-UI 协议
useGoogleAdkRuntime@assistant-ui/react-google-adkGoogle ADK

Tool UI 注册

工具调用结果需要注册对应的 UI 组件:

// components/ToolUI.tsx
import { makeAssistantToolUI } from "@assistant-ui/react";

// 搜索工具 UI
export const SearchToolUI = makeAssistantToolUI<{
  query: string;
  results: Array<{ title: string; url: string }>;
}>({
  toolName: "search",
  render: ({ args, result, status }) => {
    if (status.type === "running") {
      return <div className="animate-pulse">搜索中: {args.query}...</div>;
    }
    return (
      <div className="rounded-lg border p-3">
        <h4 className="font-medium">搜索: {args.query}</h4>
        <ul className="mt-2 space-y-1">
          {result?.results?.map((r, i) => (
            <li key={i}>
              <a href={r.url} className="text-blue-500 hover:underline">
                {r.title}
              </a>
            </li>
          ))}
        </ul>
      </div>
    );
  },
});
// 注册 Tool UI — 放在 AssistantRuntimeProvider 内部
<AssistantRuntimeProvider runtime={runtime}>
  <SearchToolUI />
  <Thread />
</AssistantRuntimeProvider>

运行时切换模式

// 通过配置切换后端,UI 代码完全不变
function ChatWithBackend({ backend }: { backend: "openai" | "langgraph" | "custom" }) {
  const runtime = backend === "openai"
    ? useChatRuntime({ api: "/api/chat" })
    : backend === "langgraph"
    ? useLangGraphRuntime({ apiUrl: "/api/langgraph" })
    : useLocalRuntime({ run: customHandler });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <Thread />  {/* 同一套 UI,不同后端 */}
    </AssistantRuntimeProvider>
  );
}

优雅之处

  • Runtime 抽象层让 UI 和后端完全解耦——同一套原语可连接任意后端
  • makeAssistantToolUI 将工具调用渲染为声明式 React 组件,参数类型自动推断
  • 从 Vercel AI SDK 迁移到 LangGraph 只需替换 useChatRuntimeuseLangGraphRuntime

创建于 2026/6/25 更新于 2026/6/25