最近你可能听过一个新的 AG-UI(Agent-User Interaction Protocol)协议:定义了前端 UI 和后端 Agent 之间的集成标准。不过与 MCP/A2A 协议不同的是,AG-UI 是从实际产品中提炼出来的标准。这个产品就是 CopilotKit:一个强大的、用来集成前端 UI 与后端 Agent 的开源神器,也是 AG-UI 协议的参考实现。

本篇将结合实例,为你深入展示 CopilotKit 的核心能力。你不仅能掌握这一实用新工具,更能真正理解 AG-UI 协议的落地应用,摆脱停留在表面的概念认知。
CopilotKit 与 AG-UI 初探
挑战在哪里
MCP 简化了 Agent 与工具间的集成;A2A 则专注于 Agent 与 Agent 之间的互操作。但在实际应用中,还有一类集成:Agent 与前端 UI 间的集成。这里的集成并非简单的通过 FastAPI 来调用 Agent 可以解决。比如:
一个财务分析助手,不仅需要在后台调用大模型和数据库,还需要在前端实时渲染逐步生成的分析报告、动态更新图表、插入交互式的问答面板,让用户可以点击'深入分析'或'重新计算'按钮。这要求 UI 和 Agent 之间能以流式、事件驱动的方式同步状态,而不仅仅是一问一答的 API 调用。

AG-UI 协议与 CopilotKit 正是为了满足这种高频、细粒度、双向的人机协作需求而诞生。
AG-UI 协议
AG-UI 协议连接的目标就是前端 UI(代表客户)与后端 AI 智能体,对它们之间的通信、事件、协作等进行标准化。AG-UI 与 MCP、A2A 之间的区别与关系非常清晰:

CopilotKit
CopilotKit 可以被看作 AG-UI 协议实现的一个框架。它提供了完整的前后端集成方案,使开发者能够快速将 AI Copilot 引入应用,包括:TypeScript/React 前端组件库、Python/Node SDK、以及可选的云端代理服务等。
简单来说,CopilotKit 让你的应用可以在前端无缝嵌入一个 AI Copilot(聊天窗口、副驾驶面板等),并与后端任意 Agent 保持交互。它支持目前主流的智能体框架(LangGraph、LlamaIndex、CrewAI 等),并且开箱即用地支持事件流、多路 Agent、可插拔工具、HITL、生成式 UI 等高级功能。
接下来将通过一个实际的例子,演示如何一步步利用 CopilotKit 快速集成一个前端 AI 助手和后端 AI Agent,并深入体验其核心能力。
构建一个 CopilotKit 的演示 Demo
我们通过一个实际的 Demo 来演示 CopilotKit 的能力。该 Demo 架构如下:

主要包括三个部分:
- 后端 Agent:使用 LangGraph 构建的一个 Workflow 智能体。
- 前端应用:使用 React+TS 构建简单的 Demo(也可以是你的现成应用)。
- Copilot 助手:使用 CopilotKit 给前端应用嵌入的智能助手。
后端 Agent 准备与启动
准备一个简单的 LangGraph Agent,这里交给它两个 Tool,一个用来 Web 搜索,一个模拟查询天气。将该 Agent 保存在 agent.py,并可以导出使用。
为了让 Agent 与前端 UI 实现通信和调用,我们仍然需要 FastAPI。但这里需要使用 CopilotKit 提供的 FastAPI 集成工具进行配置,方法如下:
...
注意这里的 sample_agent.agent 就是导入上面创建好的 Agent。
接着正常启动(uvicorn.run)FastAPI 服务即可:

前端应用准备与启动
接着来准备前端 UI 应用。你使用现成的 ReactTS 应用。这里我们直接用 Next.js 脚手架创建一个全新的 React 应用:
npx create-next-app@latest
我们对 app/page.tsx 稍作美化,让前端主页面展示如下:

现在你可以启动这个 Next.js 应用,并在浏览器中观察效果。
集成 AI Copilot
现在给这个前端 UI 增加 AI Copilot,并实现与后端 Agent 的基本互动。
步骤 1:安装依赖包
给前端安装 CopilotKit 依赖包:
npm install @copilotkit/react-ui @copilotkit/react-core
npm install @copilotkit/runtime class-validator
步骤 2:增加路由到后端 Agent
目的:让后面上 Copilot 的请求能够被发送到后端 Agent。
方法:在 app/api/copilotkit 目录下增加 route.ts 文件,核心部分如下:
... const runtime = new CopilotRuntime({
remoteEndpoints: [{url: "http://localhost:8080/copilotkit"},],
});
export const POST = async (req: NextRequest) => {
const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
runtime,
serviceAdapter,
endpoint: "/api/copilotkit",
});
return handleRequest(req);
};
注意这里 http://.../copilotkit 就是上面 FastAPI 配置的端点。
步骤 3:配置全局 CopilotKit 功能
目的:让应用中的页面都可以使用 CopilotKit 创建 Copilot。
方法:在 app/layout.tsx 文件中的 RootLayout 函数中配置 CopilotKit 组件即可:
<CopilotKit
agent="sample_agent"
runtimeUrl="/api/copilotkit"
showDevConsole={false} >
{children}
</CopilotKit>
注意这里 agent 是后端 agent 的名字;runtimeUrl 与前面的路由匹配。
步骤 4:给页面增加 Copilot
现在我们可以给任何页面(这里只有一个主页面 page.tsx)增加 Copilot 界面,与 Agent 对话,实现智能交互体验。你可以选择 sidebar(边栏)、popup(弹出式)、chat(聊天)等多种 UI 形式。这里我们添加一个 popup 形式的 Copilot 到主页。
在 app/page.tsx 中添加一个 CopilotPopup 的 UI 组件即可:
... export default function YourApp() {
return (
<>
<Home/>
<CopilotPopup
defaultOpen={true}
instructions={"你是个智能助手,尽可能用已有的知识回答问题"}
labels={{
title: "智能 AI Copilot",
initial: ` # 👋 您好!我是你的智能 Copilot。..........`
}}
/>
</>
);
} ...
前端效果测试
OK!这就是全部工作。你无需设计对话的 UI、无需调试 CSS、无需实现对后端 Agent 的调用、无需考虑流式展现...等等一系列问题。
打开主页面,会发现右下角有一个 popup 按钮,点击后出现 Chat 界面,简单测试:

接下来我们将探索 CopilotKit 的更多能力。
CopilotKit 能力之:State 共享
什么是 State(状态)共享
我们知道 LangGraph 的 Agent 会维护一个内部的自定义状态(State),用来在工作流运行期间传递与同步信息。借助 CopilotKit,你可以实现在前端 UI 与后端 Agent 之间自动双向同步与共享这个自定义的 State 信息。

注意这里的前端 UI 并不仅仅是 Copilot 的 Chat 界面,而是整个应用。
实例展示
现在对上面的 Demo 做增强,来展示后端 Agent 状态如何实时同步到前端 UI 上展示。
步骤 1:定义 Agent 的 State
我们在后端 Agent 的 State 中增加一个信息用来保存搜索工具的调用历史:
class AgentState(MessagesState):
search_history: list[str] = [] # 搜索历史记录
然后在 Agent 的 LLM 调用节点中判断如果产生了搜索工具的调用需求,就增加一条搜索记录。大致如下:
...
# 如果是搜索工具,保存搜索历史
if response.tool_calls[0].get("name") in ["tavily-search"]:
search_history = state.get("search_history", [])
search_query = response.tool_calls[0].get("args", {})
search_history.append(search_query["query"])
updated_state["search_history"] = search_history
return Command(goto="tool_node", update=updated_state)
...
步骤 2:前端 Hook 设置
现在我们想把这个后端 State 中的搜索历史实时展示在前端 UI 上,只需要使用 CopilotKit 提供的 useCoAgent 这个 hook 函数(hook 是前端 React 框架的状态管理机制)即可:
... type AgentState = {
search_history: string[],
}
function Home() {
# 使用 useCoAgent hook 函数
const {state, setState} = useCoAgent<AgentState>({
name: "sample_agent",
initialState: {
search_history: []
},
})
# 在 UI 部分使用 state
return (
<div>
...{state.search_history}
</div>
)
}
这段代码中:
- 定义与后端 Agent 匹配的 AgentState,有一个对应的 search_history
- 使用 useCoAgent 设置前端状态,提供后端 Agent 名称与初始状态
- 接着就可以在 UI 部分使用 state.search_history 来直接展示后端 State
前端效果测试
在 Copilot 的 Chat 界面中提出两个需要 Web 搜索的问题,很快就可以在左边的 UI 上看到后端 Agent 在调用工具时的搜索关键词,它被自动同步到了前端!

更多功能
以上展示了将后端 Agent 状态同步到前端。相反,你也可以将前端设置的状态实时更新给后端 Agent 使用,这是一种双向同步的机制。可以很方便的用到这些场景:
- 用户在前端 UI 上更改 Agent 设置,这些设置被自动同步给 Agent。比如:更改 Agent 回复的语言或风格。
- 后端 Agent 运行时将当前进度保存到状态中,前端可以实时的获取并渲染 Agent 的运行状态,而不只是'加载中...'。
CopilotKit 能力之:调用前端'工具'
什么是前端工具
Agent 的基本能力之一是工具(Tool)的使用,CopilotKit 可以让后端的 LangGraph Agent 拥有一项神奇的能力:它不仅可以调用后端设置的工具(比如搜索、访问数据库、MCP),还可以调用前端定义的 UI'工具'(比如更改样式)!

实例展示
我们继续增强上面的 Demo 来展示这种能力。
步骤 1:注册前端'工具'
使用 useCopilotAction hook 来注册一个前端 Action。比如,我们创建一个前端 Action 向用户弹出简单的 Alert 消息:
useCopilotAction({
name: "sayHello", // Action 名称,Agent 将通过此名称来调用工具
description: "向指定用户问好", // 对该 Action 的描述(供 Agent 理解用途)
parameters: [ // 定义参数列表
{ name: "name", type: "string", description: "要问好的对象名字" }
],
render: "正在发送问候...", // (可选) 执行时在 Chat 中显示的提示文本
handler: async ({ name }) => { // 定义具体执行逻辑的函数(异步支持)
alert(`Hello, ${name}!`); // 这里在浏览器弹出提示框
return('问候已发送给' + name); // 返回给 Agent 的结果
}
});
这个 Action 是不是非常像开发 Agent 时定义的工具呢?
上面代码在前端注册了一个名为 "sayHello" 的 Copilot 动作:它需要一个字符串参数 name。我们提供了 handler 函数,当 Agent 触发该工具时,handler 会被调用,在浏览器中弹出问候信息。render: "正在发送问候..." 则用于在 Chat 界面上显示一个临时消息提示,让用户知道 Agent 正在执行'问好'操作。
步骤 2:给后端 Agent 添加工具
首先,你需要让 Agent 的 State 从 CopilotState 派生而不是之前 LangGraph 提供的 MessagesState,其他无需改变:
from copilotkit import CopilotKitState
class AgentState(CopilotKitState):
search_history: list[str] = [] # 搜索历史记录
其次,将前端 Action 作为工具给 Agent 使用。我们的例子中是通过 LLM 绑定:
... # 3. 绑定工具到模型
model_with_tools = model.bind_tools(
[
*state["copilotkit"]["actions"], # CopilotKit actions
*all_tools, # 其他后端的工具
],
)
这里只需要一行代码,就可以从 State 中获得前端的 Action,并作为工具交给 Agent 使用。
前端效果测试
现在我们在前端 Copilot 的 Chat 界面中测试一个问题:

Agent 在理解意图后,会选择调用我们定义的前端 sayHello 工具,并传入参数 { "name": "张三" }。前端 CopilotKit 收到工具调用事件后,就会执行注册的 handler:

与此同时,CopilotKit 会把执行结果反馈给后端 Agent,Agent 随后继续生成并在 Chat 界面显示结果:

注意我们并没有在后端 Agent 明确编写任何关于前端工具的逻辑:CopilotKit 自动完成了前端 Action 的注册和后端 Agent 之间的协议对接。


