# AI Agent 前端展示 - 完整实现文档 ## 一、概述 本文档描述了 AI Agent 对话系统的前端展示实现,包括: - 思考过程展示 - 工具调用与结果展示 - 最终回答流式渲染 - 人工介入确认显示 ## 二、后端 SSE 事件类型 ### 事件类型汇总 | 事件类型 | 说明 | 数据结构 | |---------|------|---------| | `node_start` | 节点开始执行 | `{ type: "node_start", node: string }` | | `node_end` | 节点执行结束 | `{ type: "node_end", node: string }` | | `reasoning` | 思考过程 token | `{ type: "reasoning", node: string, content: string }` | | `tool_call_start` | 工具调用开始 | `{ type: "tool_call_start", tool: string, args: any, id: string }` | | `tool_call_end` | 工具调用结束 | `{ type: "tool_call_end", tool: string, id: string, result: string }` | | `llm_token` | 最终回答 token | `{ type: "llm_token", node: string, content: string }` | | `human_review_request` | 人工审核请求 | `{ type: "human_review_request", review_id: string, content: string }` | | `state_update` | 状态更新 | `{ type: "state_update", data: any }` | | `custom` | 自定义事件 | `{ type: "custom", data: any }` | | `done` | 对话完成 | `{ type: "done" }` | ### 事件处理流程 ``` 用户消息 ↓ [node_start] llm_call ↓ [reasoning] 思考过程流式输出 ↓ [tool_call_start] 工具调用开始 ↓ [node_end] llm_call ↓ [node_start] tool_node ↓ [tool_call_end] 工具调用完成,返回结果 ↓ [node_end] tool_node ↓ [node_start] llm_call ↓ [llm_token] 最终回答流式输出 ↓ [node_end] llm_call ↓ [human_review_request] 人工审核请求(如有) ↓ [done] ``` ## 三、前端组件结构 ### 组件树 ``` ChatContainer (主容器) ├── useChat (自定义 Hook) │ ├── ApiClient (API 客户端) │ └── 状态管理 ├── UserMessage (用户消息) └── AssistantMessage (AI 消息) ├── ReasoningSection (思考过程) ├── ToolCallCard[] (工具调用卡片) ├── HumanReviewCard (人工审核卡片) └── 最终回答内容 ``` ## 四、视觉设计规范 ### 1. 思考区(Reasoning Section) ```tsx // 设计规范 { icon: '💭', style: { background: 'bg-gray-50', border: 'border-gray-200', text: 'text-gray-600 italic', }, interaction: { collapsible: true, streaming: true, } } ``` ### 2. 工具调用区(Tool Call Card) ```tsx // 设计规范 { icon: '⚙️', statusIcons: { pending: '⏳', running: '🔄', success: '✅', error: '❌', }, colors: { pending: 'border-gray-300 bg-gray-50', running: 'border-blue-300 bg-blue-50', success: 'border-green-300 bg-green-50', error: 'border-red-300 bg-red-50', }, features: { argsCollapsible: true, resultCollapsible: true, } } ``` ### 3. 最终回答区(Final Answer) ```tsx // 设计规范 { style: { background: 'bg-blue-50', border: 'border-blue-100', }, interaction: { streaming: true, cursorBlink: true, }, actions: { copy: true, feedback: true, } } ``` ### 4. 人工审核区(Human Review Card) ```tsx // 设计规范 { icon: '👤', style: { background: 'bg-yellow-50', border: 'border-yellow-300', }, actions: { approve: true, reject: true, modify: true, }, fields: { contentToReview: true, comment: true, modifiedContent: true, } } ``` ## 五、使用示例 ### 基本使用 ```tsx import React from 'react'; import ChatContainer from './components/ChatContainer'; function App() { return (
); } export default App; ``` ### 自定义 API 客户端 ```tsx import { ApiClient } from './components/useChat'; const customClient = new ApiClient('http://my-custom-backend:8080'); // 流式对话 async function streamChat() { for await (const event of customClient.chatStream( '你好', 'thread-1', 'zhipu' )) { console.log('Event:', event); } } // 审核操作 await customClient.approveReview('review-123', 'user@example.com', '内容正确'); await customClient.rejectReview('review-123', 'user@example.com', '内容有误'); await customClient.modifyReview( 'review-123', 'user@example.com', '修改后的内容', '调整了措辞' ); ``` ### 自定义样式 ```tsx import { AssistantMessage } from './components/ChatContainer'; // 自定义组件 const CustomAssistantMessage = ({ message }) => (
{/* 自定义思考区 */} {/* 自定义工具卡片 */} {message.toolCalls.map(tc => ( ))} {/* 自定义审核卡片 */} {message.humanReview && ( )} {/* 自定义回答 */}
{message.content}
); ``` ## 六、后端修改说明 ### 修改的文件 1. `backend/app/agent/service.py` - 补充完整 SSE 事件类型 ### 新增的事件处理逻辑 ```python # 节点开始/结束事件 if node_name != current_node: if current_node: yield { "type": "node_end", "node": current_node } yield { "type": "node_start", "node": node_name } current_node = node_name # 思考过程事件 if reasoning_token: yield { "type": "reasoning", "node": node_name, "content": reasoning_token } # 工具调用开始事件 if tool_call_id not in tool_calls_in_progress: yield { "type": "tool_call_start", "tool": tool_name, "args": tool_args, "id": tool_call_id } # 工具调用结束事件 if msg.get("role") == "tool": yield { "type": "tool_call_end", "tool": tool_name, "id": tool_call_id, "result": tool_output } # 人工审核请求事件 if "review_pending" in serialized_data and serialized_data["review_pending"]: yield { "type": "human_review_request", "review_id": review_id, "content": content_to_review } ``` ## 七、状态管理 ### Message 接口 ```typescript interface Message { id: string; role: 'user' | 'assistant'; content: string; reasoning: string; toolCalls: ToolCall[]; humanReview?: HumanReview; isLoading: boolean; timestamp: Date; } ``` ### ToolCall 接口 ```typescript interface ToolCall { id: string; tool: string; args: any; status: 'pending' | 'running' | 'success' | 'error'; result?: string; } ``` ### HumanReview 接口 ```typescript interface HumanReview { reviewId: string; content: string; status: 'pending' | 'approved' | 'rejected' | 'modified'; comment?: string; modifiedContent?: string; } ``` ## 八、文件清单 ### 后端文件 | 文件 | 说明 | |------|------| | `backend/app/agent/service.py` | 补充完整 SSE 事件类型 | | `backend/app/agent_subgraphs/common/human_review.py` | 人工审核功能(已有) | ### 前端文件 | 文件 | 说明 | |------|------| | `frontend/src/components/useChat.ts` | 自定义 Hook + API 客户端 | | `frontend/src/components/ChatContainer.tsx` | 完整 UI 组件 | ### 文档文件 | 文件 | 说明 | |------|------| | `backend/docs/RAG_EVALUATION_GUIDE.md` | RAG 评估指南 | | `frontend/FRONTEND_GUIDE.md` | 本文档 | ## 九、测试方法 ### 测试用例 1:简单对话 输入: ``` 你好,请介绍一下你自己 ``` 预期输出: ``` [思考过程] 我需要介绍自己... [最终回答] 你好!我是 AI Agent... ``` ### 测试用例 2:工具调用 输入: ``` 请帮我查询北京的天气 ``` 预期输出: ``` [思考过程] 用户要查询天气... [tool_call_start] get_weather { city: "北京" } [tool_call_end] 结果: "北京, 晴天, 25°C" [最终回答] 北京今天天气是晴,气温 25°C... ``` ### 测试用例 3:人工审核 输入: ``` 请生成一份重要邮件内容 ``` 预期输出: ``` [思考过程] 用户要生成邮件... [最终回答] 邮件内容... [human_review_request] 需要审核... [审核卡片] 通过 / 拒绝 / 修改 ``` ## 十、常见问题 ### Q: 如何自定义样式? A: 复制组件文件,修改 className 或样式对象即可。 ### Q: 如何添加新的事件类型? A: 1. 在后端添加 yield 语句,2. 在前端 useChat 中添加 case 分支,3. 在 UI 中添加展示组件。 ### Q: 如何处理多个工具调用? A: ToolCallCard 组件支持数组,每个工具调用独立显示。 ### Q: 如何集成现有项目? A: 1. 复制后端修改,2. 复制前端组件,3. 根据项目调整 API 端点。