Files
ailine/frontend/FRONTEND_GUIDE.md
root 7a769fab14
Some checks failed
构建并部署 AI Agent 服务 / deploy (push) Failing after 6m9s
feat: 完善 SSE 事件类型,添加完整 React 组件支持思考过程、工具调用、人工审核
2026-04-26 16:05:44 +08:00

413 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 (
<div className="app">
<ChatContainer
model="zhipu"
threadId="my-thread-123"
/>
</div>
);
}
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 }) => (
<div className="my-custom-style">
{/* 自定义思考区 */}
<MyCustomReasoning content={message.reasoning} />
{/* 自定义工具卡片 */}
{message.toolCalls.map(tc => (
<MyCustomToolCall key={tc.id} toolCall={tc} />
))}
{/* 自定义审核卡片 */}
{message.humanReview && (
<MyCustomReview review={message.humanReview} />
)}
{/* 自定义回答 */}
<div className="my-answer">{message.content}</div>
</div>
);
```
## 六、后端修改说明
### 修改的文件
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 端点。