内容
# React 智能代理钩子
| 智能计数器演示 | 智能待办事项演示 |
| :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [](https://stackblitz.com/edit/react-agentic-counter?file=src%2Fmain.jsx) | [](https://stackblitz.com/github/chuanqisun/react-agent-hooks?file=src%2Fmain.jsx) |
将 React Hooks 转化为大型语言模型工具
- 🪝 熟悉:与 React Hooks 具有相同的语义
- 🤝 共生:人类接口和智能接口源自同一状态
- 🛡️ 安全:开发者控制智能状态更改的模式
- ➕ 增量采用:根据需要使用任意多或少的代码
- 📦 可组合:与经典 React Hooks 完全互操作
- 🔮 未来准备就绪:与 MCP 和 llms.txt 向后兼容
**之前**
```jsx
import { useCallback, useState } from "react";
function MyComponent() {
const [name, setName] = useState("John Doe");
const [age, setAge] = useState(30);
const adjust = useCallback((delta) => setAge((prev) => prev + delta), []);
return (
<div>
<h1>{name}</h1>
<p>{age}</p>
<button onClick={() => adjust(-1)}>变得更年轻</button>
<button onClick={() => adjust(1)}>变得更老</button>
</div>
);
}
```
**之后**
```jsx
import { useAgent, useAgentState, useAgentTool } from "react-agent-hooks";
export function MyComponent() {
const agent = useAgent({ apiKey: "******" });
const [name, setName] = useAgentState("姓名", "John Doe");
const [age, setAge] = useAgentState("年龄", 30);
const adjust = useCallback((delta) => setAge((prev) => prev + delta), []);
useAgentTool("更改年龄", z.number().describe("年龄变化的增量"), adjust);
return (
<div>
<h1>{name}</h1>
<p>{age}</p>
<button onClick={() => agent.run("变得更年轻")}>变得更年轻</button>
<button onClick={() => agent.run("变得更老")}>变得更老</button>
</div>
);
}
```
[](https://stackblitz.com/edit/react-agentic-counter?file=src%2Fmain.jsx)
## 开始使用
```sh
npm install react-agent-hooks
```
## 用法
### 给智能代理“眼睛” 👀
```tsx
import { useAgentMemo } from "react-agent-hooks";
function MyComponent() {
const [name, setName] = useState("John Doe");
const [age, setAge] = useState(30);
// 向智能代理描述一个可读状态
useAgentMemo("用户的个人资料", () => ({ name, age }), [name, age]);
return (
<div>
<h1>{name}</h1>
<p>{age}</p>
</div>
);
}
```
### 给智能代理“手” 👏
```tsx
import {z} from "zod";
import { useAgentState, useAgentTool } from "react-agent-hooks";
function MyComponent() {
// 向智能代理描述一个可读状态,同时向开发者公开一个设置函数
const [foodPreferences, setFoodPreferences] = useAgentState("食物偏好", ["披萨", "寿司"]);
// 将设置函数包装为一个工具,并向智能代理描述它
const addFoodPreference = useAgentTool("添加食物偏好", z.object({ foodItems: z.array(z.string()) }), (foodItems) => {
setFoodPreferences((prev) => [...prev, ...foodItems]);
});
const removeFoodPreference = useAgentTool("删除食物偏好", z.object({ foodItems: z.array(z.string()) }), (foodItems) => {
setFoodPreferences((prev) => prev.filter((item) => !foodItems.includes(item)));
});
return <ul>
{foodPreferences.map(item => <li key={item}>{item}</li>)}
</ul>
}
```
### 运行智能代理
```tsx
import { useAgent } from "react-agent-hooks";
function MyApp() {
// 使用提示运行智能代理
// 智能代理始终可以看到来自 `useAgentState`、`useAgentMemo` 的最新状态,并且可以使用来自 `useAgentTool` 的最新工具
const agent = useAgent({ apiKey: "******" });
// 调用智能代理
const handleFormSubmit = (e) => {
e.preventDefault();
const input = e.target.elements[0].value;
agent.run(input);
};
return (
<form onSubmit={handleFormSubmit}>
<input type="text" placeholder="您的请求" />
<button onClick={handleRunAgent}>询问智能代理</button>
</form>
);
}
```
### 构建智能应用
在组件内,使用 `enabled` 选项动态显示/隐藏智能代理的状态和工具。
```tsx
const shouldShowFeature = true; // 您可以动态决定这个值
useAgentMemo("用户的个人资料", () => ({ name, age }), [name, age], { enabled: shouldShowFeature });
useAgentState("某些状态", { name: "某些状态" }, { enabled: shouldShowFeature });
useAgentTool(
"更新状态",
z.object({ name: z.string() }),
(newState) => {
setSomeState(newState);
},
{ enabled: shouldShowFeature },
);
```
在组件树中,使用 JSX 动态显示/隐藏智能代理的状态和工具。
```tsx
function ParentComponent() {
// 更高的级别组件可以动态决定较低级别的状态/工具是否可用
const [shouldShowFeature, setShouldShowFeature] = useAgentState("切换功能", z.boolean(), true);
useAgentTool("切换功能", z.object({}), () => setShouldShowFeature(prev => !prev));
return <AppRoot>{shouldShowFeature ? <ChildComponent /> : null}</AppRoot>;
}
function ChildComponent() {
// 只有当子组件被渲染时,智能代理才会看到此状态和工具
useAgentState("某些状态", { name: "某些状态" });
useAgentTool("更新状态", z.object({ name: z.string() }), (newState) => {
setSomeState(newState);
});
return <div>...</div>;
}
```
### 构建自定义智能代理
使用 `useAgentContext` 钩子访问当前活动的智能代理状态和工具。以下是构建您自己的智能代理的示例。
```tsx
export function useMyAgent() {
const openai = new OpenAI({ dangerouslyAllowBrowser: true, apiKey: "******" });
const agentContext = useAgentContext();
const run = async (prompt: string) => {
const task = openai.chat.completions.runTools({
stream: true,
model: "gpt-4.1",
messages: [
{
role: "system",
content: `
用户正在与 Web 应用程序交互,状态如下:
\`\`\`yaml
${agentContext.stringifyStates()}
\`\`\`
根据用户的指示或目标,要么根据应用程序状态回答用户的问题,要么使用提供的工具更新状态。
简短的语言确认。
`.trim(),
},
{
role: "user",
content: prompt,
},
],
tools: agentContext.getTools(),
});
return task;
};
return {
run,
};
}
```
### 使用上下文扩展
`AgentContext` 是一个可选的 React 上下文,帮助您分层组织状态和工具。
这可以防止命名冲突,并减少由于相似的状态和工具过多而导致的智能代理混淆。
```tsx
import { AgentContext } from "react-agent-hooks";
function MyApp() {
return (
<AgentContext name="应用程序根目录">
<AgentContext name="导航">
<Nav />
</AgentContext>
<AgentContext name="内容">
<header>
<AgentContext name="头部">
<HeaderContent />
</AgentContext>
</header>
<main>
<AgentContext name="主体">
<MainContent />
</AgentContext>
</main>
</AgentContext>
</AgentContext>
);
}
function HeaderContent() {
// 智能代理将在“应用程序根目录 > 导航 > 头部”的上下文中看到此状态
const [someState, setSomeState] = useAgentState("某些状态", { name: "某些状态" });
return <div>...</div>;
}
```
## 未来的工作
渲染到 MCP 服务器
```tsx
import { renderToMCPServer } from "react-agent-hooks";
function main() {
// 在端口 3000 上启动 MCP 服务器。
// React 智能代理状态 -> MCP 资源和提示
// React 智能代理工具 -> MCP 工具
const server = renderToMCPServer(<App />).listen(3000);
}
```
渲染到 llms.txt
```tsx
import { renderToLlmsTxt } from "react-agent-hooks";
function main() {
server.get("/llms.txt", (req, res) => {
const userContext = req.query.userContext;
const llmsTxtContent = renderToLlmsTxt(<App context={userContext} />);
res.send(llmsTxtContent);
});
}
```
## 参考
博客文章:[React(钩子)就是你需要的全部](https://stackdiver.com/posts/react-hooks-is-all-you-need/)
连接信息
猜你喜欢
暂无推荐服务器