你有没有注意到一件事:大多数「AI 接入 React 应用」的教程,最终都止步于同一个地方——对话框里显示一段文字。
问天气,返回「北京今天晴,气温23度」。
问数据,返回一段 Markdown 表格。
问任务状态,返回一坨 JSON。
这没什么问题,能用。但跟你精心设计的 React 组件比起来,差了一个维度。你的 `
CopilotKit 要解决的,就是这个问题。
* * *
## 先说清楚问题在哪
接过 LLM API 的都知道,模型返回的是文字流。你拿到文字,渲染成 Markdown,最多高亮一下代码块,这就是 99% 的 AI 聊天接入方案。
这个方案的上限很低:
**用户问「帮我看下销售数据」**,你能返回一段描述,或者一个纯文本表格。但你不能直接弹出一个带筛选、排序、图表的 `
本质上,AI 只是在你应用的旁边说话,没有真正进入你的应用。
**CopilotKit 换了一个思路**:把你的 React 组件注册成 AI 可以调用的「工具」,AI 决定什么时候调、传什么数据,你的组件负责渲染。
* * *
## Generative UI 的三种模式
在讲具体代码之前,先把概念理清楚,因为「Generative UI」这个词现在被用烂了,不同地方说的其实是不同的东西。
根据 CopilotKit 官方的分类(来自其 generative-ui 仓库),有三种模式:
模式 控制权 代表协议
Controlled(受控)开发者写组件,AI 选何时渲染 AG-UI
Declarative(声明式)AI 生成组件描述,客户端渲染 A2UI
Open-ended(开放式)AI 生成完整 UI(HTML/代码)MCP Apps
这三种模式是一个「控制权 vs 自由度」的光谱。
**最右边(Open-ended)** 自由度最高,AI 生成什么就渲染什么,但风险高、样式不可控、安全边界模糊。
**最左边(Controlled)** 最稳,你写好所有组件,AI 只是决定「现在该渲染哪个、传什么数据」——布局、样式、交互全在你掌控里。
这篇聚焦 **Controlled 模式**,对应 CopilotKit 的 `useFrontendTool` hook。这是最适合生产环境的用法,也是最容易上手的起点。
* * *
## useFrontendTool:核心 API
`useFrontendTool` 做的事很简单:把一个 React 组件注册成 AI 可以触发的工具。
**安装依赖:**
npm install @copilotkit/react-core @copilotkit/react-ui @copilotkit/runtime
**最小可用代码:**
`import { useFrontendTool } from “@copilotkit/react-core”;“import { z } from “zod”;“function WeatherWidget() {“useFrontendTool({“name: “get_weather”,“description: “获取某个城市的当前天气,并以卡片形式展示”,“parameters: z.object({“location: z.string().describe(“城市名称,例如:北京、上海”),“}),“handler: async ({ location }) => {“// 这里调你自己的天气 API“const data = await fetchWeather(location);“return data;“},“render: ({ status, args, result }) => {“// inProgress:AI 正在调用中“if (status === “inProgress” || status === “executing”) {“return
三个关键字段:
•`handler`:AI 调用工具时执行的逻辑,运行在**浏览器里**(不是服务端),可以直接访问前端状态•`render`:根据执行状态渲染不同的 UI,`status` 有 `inProgress` / `executing` / `complete` 三种•`description`:AI 靠这个判断什么时候该调这个工具,写清楚,别写废话
* * *
## 完整流程走一遍
光看 API 不够,把整个链路串起来:
**第一步:Provider 包裹应用**
`// app/layout.tsx(Next.js 示例)“import { CopilotKit } from “@copilotkit/react-core”;“export default function RootLayout({ children }) {“return (“
**第二步:后端 runtime 路由**
`// app/api/copilotkit/route.ts“import { CopilotRuntime, GoogleGenerativeAIAdapter } from “@copilotkit/runtime”;“const runtime = new CopilotRuntime();“export const POST = async (req: Request) => {“const { handleRequest } = runtime.process({“serviceAdapter: new GoogleGenerativeAIAdapter({“model: “gemini-2.0-flash”,“}),“});“return handleRequest(req);“};`
CopilotKit 支持 OpenAI、Anthropic、Google 等主流模型,换 adapter 就行。
**第三步:注册工具 + 渲染聊天界面**
`// components/ChatPanel.tsx“import { CopilotChat } from “@copilotkit/react-ui”;“import “@copilotkit/react-ui/styles.css”;“export function ChatPanel() {“// 注册天气工具“useFrontendTool({ /* 上面的配置 */ });“return (“
就这三步。用户在聊天框问「北京今天天气怎么样」,AI 识别到意图 → 调 `get_weather` 工具 → `handler` 取数据 → `render` 拿到数据渲染 `
* * *
## render 的状态机值得重点理解
`render` 接收的 `status` 是整个体验质量的关键,很多人只用了 `complete` 就结束了,其实 `inProgress` 更重要。
`render: ({ status, args, result }) => {“// 工具调用中:args 已有,result 还没有“// 这时候 args.location 已经可以用了,可以先渲染 loading 态“if (status === “inProgress”) {“return
;“}“// 工具执行中(handler 在跑)“if (status === “executing”) {“return
`inProgress` 阶段,AI 已经决定要调这个工具、参数也知道了,但 `handler` 还没执行完。这时候你可以先把城市名展示出来,让用户感觉响应很快——这和普通 loading 转圈体验差很多。
* * *
## 和你现有组件库完全兼容
这是 `useFrontendTool` 被低估的优点:你现有的组件一行不用改。
你已经有 `
`// 你已有的组件,不用改“function SalesChart({ data, period, region }) { /* … */ }“// 只需要在 useFrontendTool 里引用它“useFrontendTool({“name: “show_sales_chart”,“description: “显示销售数据图表,支持按时间段和地区筛选”,“parameters: z.object({“period: z.enum([“day”, “week”, “month”]),“region: z.string().optional(),“}),“handler: async ({ period, region }) => fetchSalesData(period, region),“render: ({ status, result }) =>“status === “complete” ?
* * *
## 一个容易踩的坑
`handler` 运行在浏览器端,这是好事,但也意味着它能访问你的前端 state——你得想清楚哪些 state 该暴露、哪些不该。
如果你的 `handler` 里有 `const { user } = useAuthStore()` 这种调用,它读到的是当前登录用户的数据。这当然可以用,但如果你同时也在 `description` 里写了「可以查看任意用户的数据」,那就有问题了——AI 可能被诱导调用本不该调的逻辑。
**实践规则**:`handler` 里的逻辑跟普通 React 事件处理一样对待,该鉴权的鉴权,该边界检查的检查,不要因为「是 AI 调的」就放松警惕。
* * *
## 适合用 CopilotKit 的场景
说实话,不是所有 React 应用都需要 CopilotKit。
**适合:**
•数据密集型后台(报表、仪表盘),用户经常需要「帮我看看 XX 数据」•有大量表单的应用,AI 可以帮用户填写、校验•项目管理类工具,AI 可以直接创建、修改任务卡片•任何「用户用自然语言描述需求,系统操作 UI 响应」的场景
**不适合:**
•简单的问答类产品,文字返回就够了•UI 结构极简的工具,没有值得渲染的组件•对 bundle size 极敏感的场景(CopilotKit 有一定体积)
* * *
## 现在的生态位置
CopilotKit 在 2026年完成了 $2700万融资(据行业报道),AG-UI 协议也在 Vercel、LangChain 等生态里逐步被采用。它背后的 AG-UI 和 Google 主导的 A2UI 是同一个问题的不同解法:AI 如何和前端界面安全地双向通信。
目前来看,CopilotKit 的 Controlled 模式(useFrontendTool)是最成熟、最适合生产落地的方案,因为控制权在开发者手里。如果你想探索更开放的模式(AI 直接生成组件描述),可以看他们的 A2UI 集成——但那个还在早期,暂时不建议生产使用。
* * *
## 总结
一句话:**useFrontendTool 把你的 React 组件变成 AI 可以调用的工具,AI 控制触发时机,你控制渲染结果。**
核心三步:
1.用 `
如果你的 React 应用现在的 AI 能力还停在「聊天框里显示文字」,CopilotKit 值得认真评估一下。


