【实战教程】基于 React Flow 搭建智能体组件:从环境配置到核心节点开发指南
本文为《React Agent:从零开始构建 AI 智能体》专栏系列文章。 专栏地址:https://blog.csdn.net/suiyingy/category_12933485.html。项目地址:https://gitee.com/fgai/react-agent(含完整代码示例与实战源)。完整介绍:数据分析智能体构建实战:LLM 工具调用 + 记忆管理模块代码实现全解析(附 Qwen-Turbo 代码实现)-CSDN博客。
在大模型浪潮奔涌向前的当下,智能体技术的应用愈发广泛且深入,而高效搭建智能体组件成为开发者亟待解决的关键问题。React Flow 作为一款强大的可视化流程编辑库,凭借其灵活的布局与交互能力,为智能体组件的构建提供了新的思路与方法。本章将围绕基于 React Flow 搭建的智能体基本组件示例展开,从输入节点、输出节点等多个核心节点切入,逐步探索智能体组件搭建的奥秘。
本节主要介绍环境搭建,从下一节开始逐一介绍节点组件创建:输入节点、输出节点、网络节点、代码节点、工具节点以及大模型智能对话节点等。
1 创建 React Flow 项目
我们首先按照下面步骤创建一个 agent-nodes 项目:
# 创建项目
npx create-react-app agent-nodes
cd agent-nodes
# 考虑兼容性,安装18版本
npm install react@18 react-dom@18
npm install reactflow react-flow-renderer
# 安装 tailwindcss
npm install -D tailwindcss@3.4.17
npx tailwindcss init
# 安装 Font Awesome 图标库
npm install @fortawesome/react-fontawesome @fortawesome/free-solid-svg-icons
修改 agent-nodes/tailwind.config.js文件,添加 tailwindcss 样式。
module.exports = {content: ["./src/**/*.{js,jsx,ts,tsx}",// 包含所有组件文件路径],theme: { extend: {} },plugins: [// require('@tailwindcss/forms'), // 如果使用表单插件],
}
进一步在agent-nodes/src/index.css文件中引入样式。
@tailwind base;
@tailwind components;
@tailwind utilities;body {margin: 0;font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen','Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}code {font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',monospace;
}
创建成功后 agent-nodes/packge.json 中内容如下:
{"name": "agent-nodes","version": "0.1.0","private": true,"dependencies": {"@fortawesome/free-solid-svg-icons": "^6.7.2","@fortawesome/react-fontawesome": "^0.2.2","@testing-library/dom": "^10.4.0","@testing-library/jest-dom": "^6.6.3","@testing-library/react": "^16.3.0","@testing-library/user-event": "^13.5.0","react": "^18.3.1","react-dom": "^18.3.1","react-flow-renderer": "^10.3.17","react-scripts": "5.0.1","reactflow": "^11.11.4","web-vitals": "^2.1.4"},"scripts": {"start": "react-scripts start","build": "react-scripts build","test": "react-scripts test","eject": "react-scripts eject"},"eslintConfig": {"extends": ["react-app","react-app/jest"]},"browserslist": {"production": [">0.2%","not dead","not op_mini all"],"development": ["last 1 chrome version","last 1 firefox version","last 1 safari version"]},"devDependencies": {"tailwindcss": "^3.4.17"}
}
此时,我们可通过 npm start 启动项目,并且在浏览器看到 React 默认页面。
2 主页搭建
我们设计在 App.js 主页面用于展示后续不同类型的节点,程序如下所示。
// src/App.js
import React, { useState, useCallback, useEffect } from 'react';
import ReactFlow, {applyNodeChanges,applyEdgeChanges,addEdge,Background,useReactFlow,ReactFlowProvider
} from 'reactflow';
import 'reactflow/dist/style.css';const nodeTypes = {
};function App() {const { screenToFlowPosition } = useReactFlow();const [nodes, setNodes] = useState([]);const [edges, setEdges] = useState([]);const [contextMenu, setContextMenu] = useState(null);// 双击节点处理const onNodeDoubleClick = useCallback((_, node) => {}, []);// 右键菜单const handlePaneContextMenu = (event) => {event.preventDefault();const position = screenToFlowPosition({x: event.clientX,y: event.clientY,});setContextMenu({flowPosition: position,screenPosition: { x: event.clientX, y: event.clientY }});};// 关闭菜单const closeContextMenu = useCallback(() => {setContextMenu(null);}, []);useEffect(() => {if (contextMenu) {document.addEventListener('click', closeContextMenu);return () => document.removeEventListener('click', closeContextMenu);}}, [contextMenu, closeContextMenu]);// 运行按钮const handleRun = async () => {};const onNodesChange = useCallback((changes) => setNodes((nds) => applyNodeChanges(changes, nds)),[]);const onEdgesChange = useCallback((changes) => setEdges((eds) => applyEdgeChanges(changes, eds)),[]);const onConnect = useCallback((params) => setEdges((eds) => addEdge({ ...params, animated: true,style: { stroke: '#666' },}, eds)),[]);return (<div style={{ height: '100vh', position: 'relative' }}><buttononClick={handleRun}style={{position: 'absolute',top: 20,left: '50%',transform: 'translateX(-50%)',zIndex: 10,padding: '8px 20px',background: '#4CAF50',color: 'white',border: 'none',borderRadius: 20,cursor: 'pointer',boxShadow: '0 2px 4px rgba(0,0,0,0.2)',fontSize: 14,fontWeight: 'bold',}}>▶ 运行处理</button><ReactFlownodes={nodes}edges={edges}onNodesChange={onNodesChange}onEdgesChange={onEdgesChange}onConnect={onConnect}onPaneContextMenu={handlePaneContextMenu}onNodeDoubleClick={onNodeDoubleClick}nodeTypes={nodeTypes}fitViewconnectionRadius={20}snapToGrid={true}snapGrid={[15, 15]}defaultEdgeOptions={{type: 'smoothstep',style: {strokeWidth: 2,},}}><Background color="#ddd"gap={25}style={{ backgroundColor: '#f8f9fa' }}/></ReactFlow>{contextMenu && (<divstyle={{position: 'fixed',top: contextMenu.screenPosition.y,left: contextMenu.screenPosition.x,background: 'white',boxShadow: '0 2px 4px rgba(0,0,0,0.2)',borderRadius: 4,zIndex: 10,}}onClick={(e) => e.stopPropagation()}><divstyle={{padding: '8px 16px',cursor: 'pointer',transition: 'background 0.2s',':hover': {background: '#f5f5f5',},}}// onClick={createInputNode}>添加节点</div></div>)}</div>);
}export default function FlowWrapper() {return (<ReactFlowProvider><App /></ReactFlowProvider>);
}
将以上程序复制到 src/app.js 文件,npm start 运行程序后页面如下图所示。页面上方居中位置有一个“运行处理”按钮。此按钮样式为绿色背景、白色文字,有圆角和阴影效果,视觉上比较突出。
图1 主页基本页面
在初始化时,节点和边的数据为空,后续可以通过交互进行添加和修改。流程图具有一些实用的配置,如支持网格吸附,这使得节点移动时会自动对齐到网格,方便布局;边默认采用平滑曲线样式,线条宽度为 2px,并且连接时会有动画效果。此外,还添加了带有网格的背景,增强了视觉辨识度。
当在流程图空白处点击右键时,会弹出一个右键菜单,菜单中有“添加节点”的选项,可用于后续添加节点。如果在菜单以外的区域点击,菜单会自动关闭。同时,程序预留了节点双击处理和运行按钮点击处理的逻辑,可根据实际需求进一步完善。
立即关注获取最新动态
点击订阅《React Agent 开发专栏》,每周获取智能体开发深度教程。项目代码持续更新至React Agent 开源仓库,欢迎 Star 获取实时更新通知!FGAI 人工智能平台:FGAI 人工智能平台 https://www.botaigc.cn/