feat: add AI学习助手 agent (KG+RAG ideal) and renshenguo feishu bot
- Add AI学习助手 agent creation script with all 39 tools, 3-layer KG+RAG memory - Add renshenguo (人参果) feishu bot integration (app_service + ws_handler) - Register renshenguo WS client in main.py startup - Add RENSHENGUO_APP_ID / RENSHENGUO_APP_SECRET / RENSHENGUO_AGENT_ID config - Reorganize docs from root into docs/ subdirectories - Move startup scripts to scripts/startup/ - Various backend optimizations and tool improvements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
86
docs/chat-assistant/agent记忆实现方案.md
Normal file
86
docs/chat-assistant/agent记忆实现方案.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Agent 记忆实现方案(以「知你客服 13 号」为例)
|
||||
|
||||
本文说明「知你客服 13 号」所采用的**会话记忆**在平台上的实现方式、与 12 号的关系、持久化与性能边界,便于对接、运维与二次开发。
|
||||
|
||||
---
|
||||
|
||||
## 1. 与「知你客服 12 号」的关系
|
||||
|
||||
- **13 号在 12 号能力上增加**:工作流连线整理(去自环/重复边、分层布局、统一左右锚点)、工具调用纪律提示(避免同轮重复 `file_write`、勿刷屏 DSML 等)。
|
||||
- **记忆机制本身与 12 号一致**:仍依赖工作流中的 **Cache 节点**、键名 **`user_memory_*`**、Redis 热缓存与(可选)MySQL 持久化;引擎侧对占位符解析、`user_profile` 与末行 JSON 的处理对两条线通用。
|
||||
|
||||
---
|
||||
|
||||
## 2. 总体架构(分层)
|
||||
|
||||
| 层级 | 作用 |
|
||||
|------|------|
|
||||
| **工作流 Cache 节点** | 业务主路径:按配置的 **key**(如 `user_memory_{{user_id}}`)执行 `get` / `set`,读写一整包 JSON(通常含 `conversation_history`、`user_profile`、`context` 等)。 |
|
||||
| **Redis** | 热缓存;可配置 **TTL**(引擎侧 Cache 节点默认常见为 **3600 秒**,以节点 `ttl` 为准)。 |
|
||||
| **MySQL(`persistent_user_memories`)** | 与 **`user_memory_*`** 键对齐的持久化;在开关开启时,`get` 可合并 DB 与 Redis,`set` 后同步写入 DB。 |
|
||||
| **工作流引擎(`WorkflowEngine`)** | 合并输入、占位符解析、LLM 输出补全(如末行 JSON 中的 `user_profile`)、Cache 写入时的历史截断等。 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 会话隔离(`user_id`)
|
||||
|
||||
- Cache 键通常包含 **`{{user_id}}`**。请求执行时需携带稳定的 **`user_id`**(或引擎能从 Start 节点输入中解析到),否则会退化为 **`default`**,多用户会共用同一记忆键。
|
||||
- 持久化 scope:执行上下文中的 `workflow_id` 为 Agent 时形如 `agent_{uuid}`,用于将 DB 记录绑定到**具体 Agent**(见 `parse_memory_scope`)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据流(简版)
|
||||
|
||||
1. **开始**:用户输入进入工作流;若存在 **Cache `get`**,从 Redis(及必要时 MySQL)取出上一轮的 payload,合并进当轮输入。
|
||||
2. **LLM**:提示词中通过 `{{memory.user_profile}}`、`{{memory.conversation_history}}`、`{{memory.recent_turns}}` 等注入上下文;引擎支持 **`memory.*` 与 Cache 合并后的顶层字段**对齐,避免「只有顶层 `user_profile`、没有 `memory` 包裹」时画像为空。
|
||||
3. **模型输出**:约定**最后一行为单行 JSON**(含 `intent`、`reply`、`user_profile` 等)。若实际为「多行说明 + 末行 JSON」,引擎会解析**末行 JSON**以合并 `user_profile`、供后续 Cache 使用。
|
||||
4. **写回**:**Cache `set`**(及可能的代码节点)根据模板更新 `conversation_history` 等并写入 Redis;若满足条件则**同步 MySQL**。
|
||||
5. **截断**:写入时若存在 `conversation_history` 列表,按节点 **`max_history_length`** 保留最近若干条(引擎默认 **20**,可在 Cache 节点 `data` 中配置)。
|
||||
|
||||
---
|
||||
|
||||
## 5. MySQL 持久化的作用
|
||||
|
||||
- 配置项:**`MEMORY_PERSIST_DB_ENABLED`**(默认 **`True`**,见 `app.core.config`)。
|
||||
- **有用场景**:Redis **过期**、**重启/清空**、**冷启动**时,仍可从 DB 拉回与 Redis **合并**(对话历史取**更长**列表;`user_profile` / `context` 为**浅合并**)。
|
||||
- **不适用**:键名不是 `user_memory_*`、或 scope 无法解析为 Agent/工作流时,不会走该表。
|
||||
|
||||
---
|
||||
|
||||
## 6. 「能记住多少对话」
|
||||
|
||||
- **条数**:以 Cache 写入路径上的 **`max_history_length`** 为准,**默认保留最近 20 条**对话条目(多出的丢弃旧条目)。
|
||||
- **时间**:受 Redis **TTL** 影响热数据是否在内存;持久化打开时,**逻辑数据**仍可通过 DB + 下次合并恢复(以实际合并结果为准)。
|
||||
- **模型侧**:即使存储 20 条,提示词是否注入全文或摘要字段取决于**工作流模板**;过长时还受 **LLM 上下文长度**与成本约束。
|
||||
|
||||
---
|
||||
|
||||
## 7. 性能与瓶颈
|
||||
|
||||
- 单次对话:**主要耗时在 LLM 与工具调用**;记忆层一般为 **少量 Redis 读写**及(若开启)**单次 MySQL 读/写**,通常为毫秒~十毫秒量级,相对模型耗时可忽略。
|
||||
- **瓶颈**:高并发同一 `user_id` 串行执行工作流时的排队;超大 `conversation_history` 带来的序列化与提示词体积(已通过条数截断缓解)。
|
||||
|
||||
---
|
||||
|
||||
## 8. 排查要点
|
||||
|
||||
- **串用户 / 丢记忆**:检查执行入参是否带 **`user_id`**、Cache **key** 是否与预期一致。
|
||||
- **改代码不生效**:工作流在 **Celery Worker** 中执行,需**重启 API 与 Celery** 后再测。
|
||||
- **画像为空但上一轮已告知姓名**:检查末行 JSON 是否包含 `user_profile`、是否为空对象覆盖;并确认引擎已支持「末行 JSON」解析(见 `WorkflowEngine` 中 `_parse_zhini_final_json_dict`、`_enrich_llm_json_user_profile` 等)。
|
||||
- **画布预览/聊天发送报 500「数据库操作失败」**:① 浏览器访问 **`/health`**,响应中应有 **`checks` / `builtin_tools`**(否则 8037 可能不是当前仓库 API,或存在多实例);② 在 **`backend`** 目录执行 **`alembic upgrade head`**,保证 `executions` 等表含最新列(如 `parent_execution_id`、`depth`、`pause_state`);③ 前端预览请求需带稳定 **`user_id`**(`AgentChatPreview` 已按 Agent 维度写入 `localStorage`),否则记忆键会退化为 `default`。
|
||||
|
||||
---
|
||||
|
||||
## 9. 相关代码与脚本(索引)
|
||||
|
||||
| 说明 | 路径 |
|
||||
|------|------|
|
||||
| 引擎 Cache、合并、截断 | `backend/app/services/workflow_engine.py` |
|
||||
| DB 读写与合并 | `backend/app/services/persistent_memory_service.py` |
|
||||
| 持久化开关 | `backend/app/core/config.py`(`MEMORY_PERSIST_DB_ENABLED`) |
|
||||
| 13 号工作流/提示更新脚本 | `backend/scripts/create_zhini_kefu_13.py` |
|
||||
| 12 号基线提示与工具 | `backend/scripts/create_zhini_kefu_12.py` |
|
||||
|
||||
---
|
||||
|
||||
*文档随实现迭代可能变化,以仓库内代码与平台工作流配置为准。*
|
||||
447
docs/chat-assistant/智能体聊天助手性能优化方案.md
Normal file
447
docs/chat-assistant/智能体聊天助手性能优化方案.md
Normal file
@@ -0,0 +1,447 @@
|
||||
# 智能体聊天助手性能优化方案
|
||||
|
||||
## 一、当前性能瓶颈分析
|
||||
|
||||
### 1. 主要瓶颈识别
|
||||
|
||||
#### 🔴 **最大瓶颈:LLM API 调用(串行执行)**
|
||||
|
||||
当前工作流包含多个 LLM 节点,**串行执行**:
|
||||
1. **意图理解节点** (`llm-intent`) - 约 1-2 秒
|
||||
2. **问题回答节点** (`llm-question`) - 约 2-5 秒
|
||||
3. **格式化回复节点** (`llm-format`) - 约 1-2 秒
|
||||
|
||||
**总耗时**:约 **4-9 秒**(取决于 LLM API 响应速度)
|
||||
|
||||
#### 🟡 **次要瓶颈:前端轮询机制**
|
||||
|
||||
- 当前轮询间隔:**500ms**
|
||||
- 每次轮询需要 2 个 API 请求(状态 + 详情)
|
||||
- 在 5 秒的执行时间内,会产生 **20 次请求**
|
||||
|
||||
#### 🟢 **较小瓶颈:Redis 查询和数据库写入**
|
||||
|
||||
- Redis 查询:通常 < 10ms(可忽略)
|
||||
- 数据库日志写入:可能影响性能(但已在 Celery 中异步处理)
|
||||
|
||||
### 2. 性能测试数据
|
||||
|
||||
```
|
||||
单次对话执行时间分解:
|
||||
├─ 开始节点: ~1ms
|
||||
├─ 查询记忆: ~5ms (Redis)
|
||||
├─ 合并上下文: ~1ms
|
||||
├─ 意图理解: ~1500ms (LLM API)
|
||||
├─ 意图路由: ~1ms
|
||||
├─ 问题回答: ~3000ms (LLM API)
|
||||
├─ 合并回复: ~1ms
|
||||
├─ 更新记忆: ~5ms (Redis)
|
||||
├─ 格式化回复: ~1500ms (LLM API)
|
||||
└─ 结束节点: ~1ms
|
||||
总计: ~6015ms (约6秒)
|
||||
```
|
||||
|
||||
## 二、优化方案
|
||||
|
||||
### 方案 1:LLM 调用优化 ⭐⭐⭐⭐⭐
|
||||
|
||||
#### 1.1 并行执行可并行的 LLM 节点
|
||||
|
||||
**问题**:当前 `llm-format` 节点必须等待 `llm-question` 完成,但实际上可以优化。
|
||||
|
||||
**优化方案**:合并 `llm-question` 和 `llm-format` 节点
|
||||
|
||||
```python
|
||||
# 修改 llm-question 节点的 prompt,直接生成格式化好的回复
|
||||
prompt = """你是一个知识渊博、乐于助人的AI助手。请回答用户的问题。
|
||||
|
||||
用户问题:{{user_input}}
|
||||
对话历史:{{memory.conversation_history}}
|
||||
意图分析:{{output}}
|
||||
|
||||
请提供:
|
||||
1. 直接、准确的答案
|
||||
2. 必要的解释和说明
|
||||
3. 如果问题不明确,友好地询问更多信息
|
||||
|
||||
请以自然、易懂的方式回答,长度控制在200字以内。直接输出回答内容,确保回复自然、流畅,无需额外格式化。"""
|
||||
```
|
||||
|
||||
**效果**:减少 1 个 LLM 调用,节省 **1-2 秒**
|
||||
|
||||
#### 1.2 使用流式响应(Streaming)
|
||||
|
||||
**当前**:等待完整响应后才返回
|
||||
|
||||
**优化**:使用流式响应,边生成边返回
|
||||
|
||||
```python
|
||||
# backend/app/services/llm_service.py
|
||||
async def call_llm_stream(
|
||||
self,
|
||||
prompt: str,
|
||||
provider: str = "openai",
|
||||
model: Optional[str] = None,
|
||||
**kwargs
|
||||
) -> AsyncIterator[str]:
|
||||
"""流式调用LLM"""
|
||||
if provider == "deepseek":
|
||||
client = self.deepseek_client
|
||||
response = await client.chat.completions.create(
|
||||
model=model or "deepseek-chat",
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
stream=True, # 启用流式
|
||||
**kwargs
|
||||
)
|
||||
async for chunk in response:
|
||||
if chunk.choices[0].delta.content:
|
||||
yield chunk.choices[0].delta.content
|
||||
```
|
||||
|
||||
**效果**:
|
||||
- 用户感知延迟降低 **50-70%**
|
||||
- 首字响应时间从 3 秒降至 **0.5-1 秒**
|
||||
|
||||
#### 1.3 LLM 响应缓存
|
||||
|
||||
**场景**:相同或相似的问题可以复用之前的回答
|
||||
|
||||
```python
|
||||
# 在 cache-query 节点后添加缓存检查
|
||||
# 使用问题的 hash 作为缓存 key
|
||||
import hashlib
|
||||
|
||||
question_hash = hashlib.md5(user_input.encode()).hexdigest()
|
||||
cache_key = f"llm_response_{question_hash}"
|
||||
|
||||
# 检查缓存
|
||||
cached_response = redis_client.get(cache_key)
|
||||
if cached_response:
|
||||
return cached_response # 直接返回,节省 LLM 调用
|
||||
```
|
||||
|
||||
**效果**:重复问题响应时间从 5 秒降至 **< 100ms**
|
||||
|
||||
#### 1.4 减少 max_tokens 限制
|
||||
|
||||
**当前配置**:
|
||||
- `llm-intent`: max_tokens=1000
|
||||
- `llm-question`: max_tokens=2000
|
||||
- `llm-format`: max_tokens=500
|
||||
|
||||
**优化**:
|
||||
- `llm-intent`: max_tokens=200(意图识别不需要太长)
|
||||
- `llm-question`: max_tokens=1000(200字约500 tokens)
|
||||
- 删除 `llm-format` 节点
|
||||
|
||||
**效果**:减少 token 生成时间,节省 **0.5-1 秒**
|
||||
|
||||
### 方案 2:前端优化 ⭐⭐⭐⭐
|
||||
|
||||
#### 2.1 使用 WebSocket 替代轮询
|
||||
|
||||
**当前**:每 500ms 轮询一次,产生大量请求
|
||||
|
||||
**优化**:使用 WebSocket 实时推送执行状态
|
||||
|
||||
```typescript
|
||||
// frontend/src/composables/useWebSocket.ts
|
||||
// 已有 WebSocket 实现,但未在聊天组件中使用
|
||||
|
||||
// 修改 AgentChatPreview.vue
|
||||
import { useWebSocket } from '@/composables/useWebSocket'
|
||||
|
||||
const { status, result, connect, disconnect } = useWebSocket(execution.id)
|
||||
|
||||
watch(result, (newResult) => {
|
||||
if (newResult && !replyAdded) {
|
||||
replyAdded = true
|
||||
messages.value.push({
|
||||
role: 'agent',
|
||||
content: extractReply(newResult),
|
||||
timestamp: Date.now()
|
||||
})
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
**效果**:
|
||||
- 减少 90% 的 HTTP 请求
|
||||
- 实时性提升(延迟从 500ms 降至 < 100ms)
|
||||
- 服务器负载降低
|
||||
|
||||
#### 2.2 智能轮询(自适应间隔)
|
||||
|
||||
如果无法使用 WebSocket,可以优化轮询策略:
|
||||
|
||||
```typescript
|
||||
// 动态调整轮询间隔
|
||||
let pollingInterval = 500 // 初始 500ms
|
||||
let consecutiveNoChange = 0
|
||||
|
||||
const checkStatus = async () => {
|
||||
const oldStatus = lastStatus
|
||||
const newStatus = await getStatus()
|
||||
|
||||
if (oldStatus === newStatus) {
|
||||
consecutiveNoChange++
|
||||
// 如果连续3次状态未变化,增加轮询间隔
|
||||
if (consecutiveNoChange >= 3) {
|
||||
pollingInterval = Math.min(pollingInterval * 1.5, 2000) // 最大2秒
|
||||
}
|
||||
} else {
|
||||
consecutiveNoChange = 0
|
||||
pollingInterval = 500 // 重置为初始值
|
||||
}
|
||||
|
||||
setTimeout(checkStatus, pollingInterval)
|
||||
}
|
||||
```
|
||||
|
||||
**效果**:减少 30-50% 的无效请求
|
||||
|
||||
### 方案 3:工作流优化 ⭐⭐⭐
|
||||
|
||||
#### 3.1 简化工作流结构
|
||||
|
||||
**当前流程**:
|
||||
```
|
||||
开始 → 查询记忆 → 合并上下文 → 意图理解 → 意图路由 →
|
||||
[5个分支] → 合并回复 → 更新记忆 → 格式化回复 → 结束
|
||||
```
|
||||
|
||||
**优化流程**:
|
||||
```
|
||||
开始 → 查询记忆 → 合并上下文 → 意图理解 → 意图路由 →
|
||||
[5个分支,直接生成最终回复] → 更新记忆 → 结束
|
||||
```
|
||||
|
||||
**关键修改**:
|
||||
- 删除 `llm-format` 节点
|
||||
- 在各个分支节点中直接生成格式化好的回复
|
||||
- 删除 `merge-response` 节点(如果只有一个分支被激活)
|
||||
|
||||
**效果**:减少 1-2 个节点执行,节省 **1-2 秒**
|
||||
|
||||
#### 3.2 条件优化:跳过不必要的节点
|
||||
|
||||
**场景**:如果用户只是简单问候,不需要完整的问题回答流程
|
||||
|
||||
```python
|
||||
# 在 switch-intent 节点后,对于 greeting 意图
|
||||
# 可以直接使用模板回复,跳过 LLM 调用
|
||||
|
||||
if intent == "greeting":
|
||||
# 使用预定义模板
|
||||
response = "你好!很高兴见到你,有什么我可以帮助你的吗?"
|
||||
# 跳过 llm-greeting 节点
|
||||
else:
|
||||
# 正常执行 LLM 节点
|
||||
response = await llm_question(...)
|
||||
```
|
||||
|
||||
**效果**:简单场景响应时间从 5 秒降至 **< 1 秒**
|
||||
|
||||
### 方案 4:缓存优化 ⭐⭐⭐
|
||||
|
||||
#### 4.1 对话历史截断
|
||||
|
||||
**问题**:对话历史过长会增加 LLM prompt 长度,影响响应速度
|
||||
|
||||
**优化**:只保留最近 N 条对话
|
||||
|
||||
```python
|
||||
# 在 cache-update 节点中
|
||||
conversation_history = memory.conversation_history[-20:] # 只保留最近20条
|
||||
```
|
||||
|
||||
**效果**:
|
||||
- 减少 prompt 长度,节省 **0.2-0.5 秒**
|
||||
- 降低 token 消耗
|
||||
|
||||
#### 4.2 智能摘要
|
||||
|
||||
**更高级的方案**:将旧对话压缩为摘要
|
||||
|
||||
```python
|
||||
# 如果对话历史超过50条,生成摘要
|
||||
if len(conversation_history) > 50:
|
||||
# 保留最近20条
|
||||
recent_history = conversation_history[-20:]
|
||||
# 将前面的对话压缩为摘要
|
||||
old_history = conversation_history[:-20]
|
||||
summary = await llm_summarize(old_history) # 异步生成摘要
|
||||
conversation_history = [{"role": "system", "content": summary}] + recent_history
|
||||
```
|
||||
|
||||
**效果**:在保持上下文的同时,减少 prompt 长度
|
||||
|
||||
### 方案 5:数据库优化 ⭐⭐
|
||||
|
||||
#### 5.1 异步日志写入
|
||||
|
||||
**当前**:每个节点执行后立即写入日志
|
||||
|
||||
**优化**:批量写入日志
|
||||
|
||||
```python
|
||||
# 收集日志,定期批量写入
|
||||
log_buffer = []
|
||||
async def flush_logs():
|
||||
if log_buffer:
|
||||
db.bulk_insert_mappings(ExecutionLog, log_buffer)
|
||||
db.commit()
|
||||
log_buffer.clear()
|
||||
|
||||
# 每100ms或每10条日志刷新一次
|
||||
```
|
||||
|
||||
**效果**:减少数据库写入次数,提升 **5-10%** 性能
|
||||
|
||||
#### 5.2 减少日志详细程度
|
||||
|
||||
**生产环境**:只记录关键日志(错误、警告)
|
||||
|
||||
```python
|
||||
# 根据环境变量控制日志级别
|
||||
if settings.DEBUG:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
else:
|
||||
logger.setLevel(logging.WARNING) # 只记录警告和错误
|
||||
```
|
||||
|
||||
**效果**:减少日志 I/O,提升 **2-5%** 性能
|
||||
|
||||
## 三、实施优先级
|
||||
|
||||
### 🔥 **高优先级(立即实施)**
|
||||
|
||||
1. **删除 llm-format 节点** ⭐⭐⭐⭐⭐
|
||||
- 实施难度:低
|
||||
- 效果:节省 1-2 秒
|
||||
- 预计时间:30 分钟
|
||||
|
||||
2. **优化 max_tokens 配置** ⭐⭐⭐⭐
|
||||
- 实施难度:低
|
||||
- 效果:节省 0.5-1 秒
|
||||
- 预计时间:15 分钟
|
||||
|
||||
3. **对话历史截断** ⭐⭐⭐⭐
|
||||
- 实施难度:低
|
||||
- 效果:节省 0.2-0.5 秒 + 降低 token 消耗
|
||||
- 预计时间:30 分钟
|
||||
|
||||
### 🟡 **中优先级(近期实施)**
|
||||
|
||||
4. **使用 WebSocket 替代轮询** ⭐⭐⭐⭐
|
||||
- 实施难度:中
|
||||
- 效果:提升实时性,减少服务器负载
|
||||
- 预计时间:2-3 小时
|
||||
|
||||
5. **简化工作流结构** ⭐⭐⭐
|
||||
- 实施难度:中
|
||||
- 效果:节省 1-2 秒
|
||||
- 预计时间:1-2 小时
|
||||
|
||||
6. **智能轮询(如果不用 WebSocket)** ⭐⭐⭐
|
||||
- 实施难度:低
|
||||
- 效果:减少 30-50% 无效请求
|
||||
- 预计时间:1 小时
|
||||
|
||||
### 🟢 **低优先级(长期优化)**
|
||||
|
||||
7. **流式响应** ⭐⭐⭐⭐⭐
|
||||
- 实施难度:高
|
||||
- 效果:显著提升用户体验(首字响应时间降低 50-70%)
|
||||
- 预计时间:4-6 小时
|
||||
|
||||
8. **LLM 响应缓存** ⭐⭐⭐
|
||||
- 实施难度:中
|
||||
- 效果:重复问题响应时间 < 100ms
|
||||
- 预计时间:2-3 小时
|
||||
|
||||
9. **条件优化(跳过不必要节点)** ⭐⭐⭐
|
||||
- 实施难度:中
|
||||
- 效果:简单场景响应时间 < 1 秒
|
||||
- 预计时间:2-3 小时
|
||||
|
||||
## 四、预期效果
|
||||
|
||||
### 优化前
|
||||
- **平均响应时间**:5-6 秒
|
||||
- **首字响应时间**:3-4 秒
|
||||
- **HTTP 请求数**:20+ 次/对话
|
||||
|
||||
### 优化后(实施高优先级方案)
|
||||
|
||||
- **平均响应时间**:**3-4 秒**(提升 40%)
|
||||
- **首字响应时间**:**2-3 秒**(提升 25%)
|
||||
- **HTTP 请求数**:**2-5 次/对话**(减少 75%)
|
||||
|
||||
### 优化后(实施所有方案)
|
||||
|
||||
- **平均响应时间**:**1.5-2.5 秒**(提升 60%)
|
||||
- **首字响应时间**:**0.5-1 秒**(提升 75%,使用流式响应)
|
||||
- **HTTP 请求数**:**1-2 次/对话**(使用 WebSocket)
|
||||
|
||||
## 五、具体实施步骤
|
||||
|
||||
### 步骤 1:快速优化(30 分钟)
|
||||
|
||||
```bash
|
||||
# 1. 修改工作流配置,删除 llm-format 节点
|
||||
# 2. 优化各 LLM 节点的 max_tokens
|
||||
# 3. 添加对话历史截断逻辑
|
||||
```
|
||||
|
||||
### 步骤 2:前端优化(2-3 小时)
|
||||
|
||||
```bash
|
||||
# 1. 在 AgentChatPreview.vue 中集成 WebSocket
|
||||
# 2. 替换轮询逻辑
|
||||
# 3. 测试实时性
|
||||
```
|
||||
|
||||
### 步骤 3:高级优化(可选,4-6 小时)
|
||||
|
||||
```bash
|
||||
# 1. 实现流式响应
|
||||
# 2. 添加 LLM 响应缓存
|
||||
# 3. 优化工作流结构
|
||||
```
|
||||
|
||||
## 六、监控指标
|
||||
|
||||
实施优化后,建议监控以下指标:
|
||||
|
||||
1. **响应时间分布**
|
||||
- P50(中位数)
|
||||
- P95(95% 分位数)
|
||||
- P99(99% 分位数)
|
||||
|
||||
2. **LLM 调用时间**
|
||||
- 各节点的平均调用时间
|
||||
- Token 消耗
|
||||
|
||||
3. **前端指标**
|
||||
- 首字响应时间(TTFB)
|
||||
- 完整响应时间
|
||||
- HTTP 请求数量
|
||||
|
||||
4. **服务器负载**
|
||||
- CPU 使用率
|
||||
- 内存使用率
|
||||
- 数据库连接数
|
||||
|
||||
## 七、注意事项
|
||||
|
||||
1. **流式响应**:需要修改前端 UI,支持逐步显示文本
|
||||
2. **缓存策略**:需要考虑缓存失效和更新机制
|
||||
3. **向后兼容**:优化不应破坏现有功能
|
||||
4. **测试覆盖**:每个优化都需要充分测试
|
||||
|
||||
---
|
||||
|
||||
**文档版本**:v1.0
|
||||
**创建时间**:2024年
|
||||
**维护人员**:AI Assistant
|
||||
296
docs/chat-assistant/智能体聊天助手记忆存储说明.md
Normal file
296
docs/chat-assistant/智能体聊天助手记忆存储说明.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# 智能体聊天助手记忆存储说明
|
||||
|
||||
## 一、数据存储位置
|
||||
|
||||
### 1. 主要存储:Redis
|
||||
|
||||
智能体聊天助手使用 **Redis** 作为记忆数据的持久化存储后端。
|
||||
|
||||
- **存储键名格式**:`user_memory_{user_id}`
|
||||
- 例如:`user_memory_default`、`user_memory_12345`
|
||||
- **存储位置**:Redis 数据库(默认 DB 0)
|
||||
- **数据格式**:JSON 字符串
|
||||
|
||||
### 2. 备用存储:内存缓存
|
||||
|
||||
如果 Redis 不可用,系统会回退到**内存缓存**(Memory Cache)。
|
||||
|
||||
⚠️ **重要提示**:内存缓存只在**单次执行会话内有效**,执行结束后数据会丢失,无法跨会话保留。
|
||||
|
||||
### 3. 存储结构
|
||||
|
||||
每个用户的记忆数据包含以下字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"conversation_history": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "我的名字叫老七",
|
||||
"timestamp": "2024-01-01T10:00:00"
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "好的,我记住了你的名字是老七。",
|
||||
"timestamp": "2024-01-01T10:00:01"
|
||||
}
|
||||
],
|
||||
"user_profile": {
|
||||
// 用户画像信息(可扩展)
|
||||
},
|
||||
"context": {
|
||||
// 上下文信息(可扩展)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 二、数据大小限制
|
||||
|
||||
### 1. Redis 存储限制
|
||||
|
||||
- **单条记录大小**:
|
||||
- Redis 理论上单个 key 的值最大可达 **512MB**(默认配置)
|
||||
- 实际使用中,受 Redis 服务器配置的 `maxmemory` 限制
|
||||
- 当前系统:**无硬编码限制**(取决于 Redis 服务器配置)
|
||||
|
||||
- **对话历史累积**:
|
||||
- 对话历史会**不断累积**,没有自动截断机制
|
||||
- 每次对话会添加 2 条记录(用户消息 + 助手回复)
|
||||
- 假设每条消息平均 200 字(约 600 字节),1000 轮对话约 1.2MB
|
||||
|
||||
### 2. 实际使用情况
|
||||
|
||||
根据当前系统检查:
|
||||
- 当前用户记忆 key 数量:**1 个**
|
||||
- 示例 key 大小:**约 5.73 KB**(20 条对话历史)
|
||||
- Redis 已使用内存:**2.52 MB**
|
||||
- Redis 最大内存限制:**无限制**(取决于服务器配置)
|
||||
|
||||
### 3. 建议的容量规划
|
||||
|
||||
| 对话轮数 | 预估大小 | 说明 |
|
||||
|---------|---------|------|
|
||||
| 100 轮 | ~120 KB | 适合短期对话 |
|
||||
| 500 轮 | ~600 KB | 适合中期对话 |
|
||||
| 1000 轮 | ~1.2 MB | 适合长期对话 |
|
||||
| 5000 轮 | ~6 MB | 需要监控内存使用 |
|
||||
| 10000 轮 | ~12 MB | 建议实施截断策略 |
|
||||
|
||||
## 三、数据持久化与丢失风险
|
||||
|
||||
### 1. 数据持久化机制
|
||||
|
||||
#### Redis 持久化(推荐)
|
||||
|
||||
- **持久化方式**:取决于 Redis 配置
|
||||
- **RDB**:定期快照,默认开启
|
||||
- **AOF**:追加日志,可选开启
|
||||
- **Docker 卷持久化**:
|
||||
- 使用 `redis_data` 卷存储数据
|
||||
- 即使容器重启,数据也会保留
|
||||
- 数据存储在 Docker 卷中,位置:`/var/lib/docker/volumes/redis_data`
|
||||
|
||||
#### 内存缓存(不持久化)
|
||||
|
||||
- 数据仅存在于进程内存中
|
||||
- 进程重启后数据丢失
|
||||
- 仅用于 Redis 不可用时的临时回退
|
||||
|
||||
### 2. 数据丢失风险分析
|
||||
|
||||
| 场景 | 数据是否丢失 | 说明 |
|
||||
|------|------------|------|
|
||||
| Redis 正常重启 | ❌ 不丢失 | 数据已持久化到磁盘 |
|
||||
| Docker 容器重启 | ❌ 不丢失 | 数据存储在 Docker 卷中 |
|
||||
| Redis 数据卷被删除 | ✅ **会丢失** | 需要重新创建卷 |
|
||||
| 超过 TTL 时间 | ✅ **会过期** | 默认 24 小时后过期 |
|
||||
| Redis 服务器故障 | ⚠️ 取决于持久化配置 | 如果持久化配置不当可能丢失 |
|
||||
| 使用内存缓存时 | ✅ **会丢失** | 每次执行后丢失 |
|
||||
|
||||
### 3. TTL(生存时间)设置
|
||||
|
||||
当前配置:
|
||||
- **TTL**:**86400 秒**(24 小时)
|
||||
- **位置**:`cache-update` 节点的 `ttl` 配置
|
||||
- **默认值**:如果未配置,默认 3600 秒(1 小时)
|
||||
|
||||
⚠️ **重要**:如果用户在 24 小时内没有新的对话,记忆数据会**自动过期删除**。
|
||||
|
||||
## 四、配置说明
|
||||
|
||||
### 1. Redis 配置
|
||||
|
||||
**环境变量**(`docker-compose.dev.yml`):
|
||||
```yaml
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
```
|
||||
|
||||
**配置文件**(`backend/.env`):
|
||||
```env
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
```
|
||||
|
||||
### 2. Cache 节点配置
|
||||
|
||||
**查询记忆节点**(`cache-query`):
|
||||
```python
|
||||
{
|
||||
"id": "cache-query",
|
||||
"type": "cache",
|
||||
"data": {
|
||||
"operation": "get",
|
||||
"key": "user_memory_{user_id}",
|
||||
"default_value": '{"conversation_history": [], "user_profile": {}, "context": {}}'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**更新记忆节点**(`cache-update`):
|
||||
```python
|
||||
{
|
||||
"id": "cache-update",
|
||||
"type": "cache",
|
||||
"data": {
|
||||
"operation": "set",
|
||||
"key": "user_memory_{user_id}",
|
||||
"value": '{"conversation_history": {{memory.conversation_history}} + [...], ...}',
|
||||
"ttl": 86400 # 24小时
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 五、优化建议
|
||||
|
||||
### 1. 对话历史截断策略
|
||||
|
||||
如果对话历史过长,建议实施截断策略:
|
||||
|
||||
**方案 A:保留最近 N 条**
|
||||
```python
|
||||
# 在 cache-update 节点中,限制 conversation_history 长度
|
||||
conversation_history = memory.conversation_history[-100:] # 只保留最近100条
|
||||
```
|
||||
|
||||
**方案 B:按时间截断**
|
||||
```python
|
||||
# 只保留最近7天的对话
|
||||
from datetime import datetime, timedelta
|
||||
cutoff_date = (datetime.now() - timedelta(days=7)).isoformat()
|
||||
conversation_history = [
|
||||
msg for msg in memory.conversation_history
|
||||
if msg.get('timestamp', '') > cutoff_date
|
||||
]
|
||||
```
|
||||
|
||||
**方案 C:智能摘要**
|
||||
```python
|
||||
# 将旧对话历史压缩为摘要
|
||||
# 使用 LLM 节点生成摘要,保留关键信息
|
||||
```
|
||||
|
||||
### 2. 增加 TTL 时间
|
||||
|
||||
如果需要更长的记忆保留时间,可以修改 TTL:
|
||||
|
||||
```python
|
||||
"ttl": 604800 # 7天
|
||||
"ttl": 2592000 # 30天
|
||||
"ttl": 0 # 永不过期(不推荐,可能导致内存溢出)
|
||||
```
|
||||
|
||||
### 3. 监控 Redis 内存使用
|
||||
|
||||
定期检查 Redis 内存使用情况:
|
||||
|
||||
```bash
|
||||
# 进入 Redis 容器
|
||||
docker exec -it aiagent-redis-1 redis-cli
|
||||
|
||||
# 查看内存信息
|
||||
INFO memory
|
||||
|
||||
# 查看所有用户记忆 key
|
||||
KEYS user_memory_*
|
||||
|
||||
# 查看特定 key 的大小
|
||||
MEMORY USAGE user_memory_default
|
||||
```
|
||||
|
||||
### 4. 数据备份策略
|
||||
|
||||
**定期备份 Redis 数据**:
|
||||
|
||||
```bash
|
||||
# 备份 Redis 数据
|
||||
docker exec aiagent-redis-1 redis-cli SAVE
|
||||
docker cp aiagent-redis-1:/data/dump.rdb ./backup/dump_$(date +%Y%m%d).rdb
|
||||
```
|
||||
|
||||
**恢复 Redis 数据**:
|
||||
|
||||
```bash
|
||||
# 恢复 Redis 数据
|
||||
docker cp ./backup/dump_20240101.rdb aiagent-redis-1:/data/dump.rdb
|
||||
docker restart aiagent-redis-1
|
||||
```
|
||||
|
||||
## 六、常见问题
|
||||
|
||||
### Q1: 数据会丢失吗?
|
||||
|
||||
**A**:
|
||||
- 如果使用 Redis 且配置了持久化:**不会丢失**(除非数据卷被删除或超过 TTL)
|
||||
- 如果使用内存缓存:**会丢失**(每次执行后丢失)
|
||||
|
||||
### Q2: 可以存储多少对话?
|
||||
|
||||
**A**:
|
||||
- 理论上:取决于 Redis 服务器内存限制
|
||||
- 实际建议:**1000-5000 轮对话**(约 1-6 MB)
|
||||
- 超过 10000 轮建议实施截断策略
|
||||
|
||||
### Q3: 如何延长记忆保留时间?
|
||||
|
||||
**A**:
|
||||
- 修改 `cache-update` 节点的 `ttl` 配置
|
||||
- 设置为更大的值(如 2592000 = 30 天)
|
||||
- 或设置为 0(永不过期,需谨慎)
|
||||
|
||||
### Q4: 如何清理特定用户的记忆?
|
||||
|
||||
**A**:
|
||||
```bash
|
||||
# 通过 Redis CLI
|
||||
docker exec -it aiagent-redis-1 redis-cli DEL user_memory_{user_id}
|
||||
|
||||
# 或通过工作流添加 delete 操作节点
|
||||
```
|
||||
|
||||
### Q5: 多个用户的数据会互相影响吗?
|
||||
|
||||
**A**:
|
||||
- **不会**,每个用户使用独立的 key:`user_memory_{user_id}`
|
||||
- 数据完全隔离
|
||||
|
||||
## 七、总结
|
||||
|
||||
### 当前配置
|
||||
|
||||
- ✅ **存储位置**:Redis(持久化)
|
||||
- ✅ **TTL**:24 小时
|
||||
- ✅ **数据格式**:JSON(包含对话历史、用户画像、上下文)
|
||||
- ✅ **大小限制**:无硬编码限制(取决于 Redis 配置)
|
||||
- ⚠️ **数据丢失风险**:低(除非数据卷被删除或超过 TTL)
|
||||
|
||||
### 建议
|
||||
|
||||
1. **短期使用**(< 1000 轮对话):当前配置足够
|
||||
2. **长期使用**(> 5000 轮对话):建议实施对话历史截断策略
|
||||
3. **生产环境**:建议定期备份 Redis 数据,监控内存使用
|
||||
4. **高可用场景**:考虑 Redis 主从复制或集群模式
|
||||
|
||||
---
|
||||
|
||||
**文档版本**:v1.0
|
||||
**最后更新**:2024年
|
||||
**维护人员**:AI Assistant
|
||||
344
docs/chat-assistant/智能体聊天助手记忆问题修复.md
Normal file
344
docs/chat-assistant/智能体聊天助手记忆问题修复.md
Normal file
@@ -0,0 +1,344 @@
|
||||
# 智能体聊天助手记忆问题修复文档
|
||||
|
||||
## 问题描述
|
||||
|
||||
智能聊天助手无法记住用户信息,具体表现为:
|
||||
1. 第一次对话:用户输入 "我的名字叫老七"
|
||||
2. 第二次对话:用户输入 "你还记得我的名字吗?"
|
||||
3. **预期结果**:助手应该回答 "是的,我记得你叫老七"
|
||||
4. **实际结果**:助手无法记住用户名字,或者回答错误
|
||||
|
||||
**额外问题**:助手有时会回复两次相同的消息。
|
||||
|
||||
## 问题分析
|
||||
|
||||
### 工作流结构
|
||||
|
||||
智能聊天助手的工作流包含以下关键节点:
|
||||
1. **开始节点** (`start-1`) - 接收用户输入
|
||||
2. **查询记忆节点** (`cache-query`) - 从Redis查询对话历史
|
||||
3. **合并上下文节点** (`transform-merge`) - 合并用户输入和记忆
|
||||
4. **意图理解节点** (`llm-intent`) - 分析用户意图
|
||||
5. **意图路由节点** (`switch-intent`) - 根据意图分发到不同分支
|
||||
6. **问题回答节点** (`llm-question`) - 生成回答
|
||||
7. **合并回复节点** (`merge-response`) - 合并各分支结果
|
||||
8. **更新记忆节点** (`cache-update`) - 更新对话历史到Redis
|
||||
9. **格式化回复节点** (`llm-format`) - 格式化最终回复
|
||||
10. **结束节点** (`end-1`) - 返回最终结果
|
||||
|
||||
### 根本原因
|
||||
|
||||
经过深入调试,发现以下问题:
|
||||
|
||||
#### 1. Cache节点数据存储问题
|
||||
- **问题**:`cache-update` 节点的 `value_template` 中,`{{user_input}}`、`{{output}}`、`{{timestamp}}` 等变量在Python表达式执行时被当作字符串 `"null"` 处理
|
||||
- **原因**:变量替换逻辑在Python表达式执行之后,导致变量未正确替换
|
||||
|
||||
#### 2. Cache节点数据读取问题
|
||||
- **问题**:`cache-query` 节点的 `default_value` 中,`conversation_history` 初始化为 `null`,导致后续 `null + [...]` 操作失败
|
||||
- **原因**:JSON解析后,空值被解析为 `None`,而不是空列表 `[]`
|
||||
|
||||
#### 3. Transform节点数据丢失问题
|
||||
- **问题**:`transform-merge` 节点的 `mapping` 中,`{{output}}` 映射到 `memory` 字段,但 `cache-query` 的输出结构不包含完整的 `memory` 对象
|
||||
- **原因**:`cache-query` 返回的数据结构是 `{"right": {...}}`,而 `transform-merge` 期望的是完整的 `memory` 对象
|
||||
|
||||
#### 4. 边连接导致的数据丢失问题
|
||||
- **问题**:`cache-query → transform-merge` 的边设置了 `sourceHandle='right'`,导致只有 `right` 字段被传递,其他内存相关字段丢失
|
||||
- **原因**:`get_node_input` 方法在处理 `sourceHandle` 时,只传递了指定字段,没有保留内存相关字段
|
||||
|
||||
#### 5. LLM节点变量替换问题
|
||||
- **问题1**:LLM节点的prompt模板中,`{{user_input}}` 和 `{{memory.conversation_history}}` 无法正确替换
|
||||
- **原因**:变量替换逻辑不支持嵌套路径(如 `{{memory.conversation_history}}`)
|
||||
- **问题2**:`{{output}}` 变量无法从嵌套的 `right.right.right` 结构中提取
|
||||
- **原因**:变量提取逻辑只检查顶层字段,没有递归查找
|
||||
|
||||
#### 6. 前端重复回复问题
|
||||
- **问题**:助手有时会回复两次相同的消息
|
||||
- **原因**:轮询逻辑中,`checkStatus` 函数在状态为 `completed` 时可能被多次调用,导致重复添加消息
|
||||
|
||||
## 修复方案
|
||||
|
||||
### 1. 修复Cache节点的变量替换逻辑
|
||||
|
||||
**文件**:`backend/app/services/workflow_engine.py`
|
||||
|
||||
**修改位置**:`execute_node` 方法中的 `cache` 节点处理逻辑
|
||||
|
||||
**关键修改**:
|
||||
```python
|
||||
# 在Python表达式执行之前,先替换变量
|
||||
if '{{user_input}}' in value_template:
|
||||
user_input_value = input_data.get('user_input') or input_data.get('query') or input_data.get('input') or input_data.get('USER_INPUT') or ''
|
||||
user_input_escaped = json_module.dumps(user_input_value, ensure_ascii=False)[1:-1] # 移除外层引号
|
||||
value_template = value_template.replace('{{user_input}}', user_input_escaped)
|
||||
|
||||
if '{{output}}' in value_template:
|
||||
output_value = self._extract_output_value(input_data)
|
||||
output_escaped = json_module.dumps(output_value, ensure_ascii=False)[1:-1] # 移除外层引号
|
||||
value_template = value_template.replace('{{output}}', output_escaped)
|
||||
|
||||
if '{{timestamp}}' in value_template:
|
||||
timestamp_value = input_data.get('timestamp') or datetime.now().isoformat()
|
||||
timestamp_escaped = json_module.dumps(timestamp_value, ensure_ascii=False)[1:-1] # 移除外层引号
|
||||
value_template = value_template.replace('{{timestamp}}', timestamp_escaped)
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- 使用 `json.dumps()[1:-1]` 来正确转义字符串,同时移除外层引号
|
||||
- 在Python表达式执行之前完成变量替换
|
||||
|
||||
### 2. 修复Cache节点的默认值初始化
|
||||
|
||||
**文件**:`backend/app/services/workflow_engine.py`
|
||||
|
||||
**修改位置**:`execute_node` 方法中的 `cache-query` 处理逻辑
|
||||
|
||||
**关键修改**:
|
||||
```python
|
||||
# 确保default_value中的conversation_history初始化为空列表
|
||||
default_value_str = node_data.get('default_value', '{}')
|
||||
try:
|
||||
default_value = json_module.loads(default_value_str)
|
||||
# 确保conversation_history是列表而不是null
|
||||
if 'conversation_history' not in default_value or default_value.get('conversation_history') is None:
|
||||
default_value['conversation_history'] = []
|
||||
except:
|
||||
default_value = {"conversation_history": [], "user_profile": {}, "context": {}}
|
||||
```
|
||||
|
||||
### 3. 修复Transform节点的Memory字段构建
|
||||
|
||||
**文件**:`backend/app/services/workflow_engine.py`
|
||||
|
||||
**修改位置**:`execute_node` 方法中的 `transform` 节点处理逻辑(`merge` 模式)
|
||||
|
||||
**关键修改**:
|
||||
```python
|
||||
# 如果memory字段为空,尝试从顶层字段构建
|
||||
if key == 'memory' and (value is None or value == '' or value == '{{output}}'):
|
||||
# 尝试从expanded_input中构建memory对象
|
||||
memory = {}
|
||||
for field in ['conversation_history', 'user_profile', 'context']:
|
||||
if field in expanded_input:
|
||||
memory[field] = expanded_input[field]
|
||||
if memory:
|
||||
result[key] = memory
|
||||
else:
|
||||
# 如果还是找不到,保留原有的memory字段(如果有)
|
||||
if 'memory' in expanded_input:
|
||||
result[key] = expanded_input['memory']
|
||||
else:
|
||||
result[key] = value
|
||||
```
|
||||
|
||||
### 4. 修复边连接导致的数据丢失
|
||||
|
||||
**文件**:`backend/app/services/workflow_engine.py`
|
||||
|
||||
**修改位置**:`get_node_input` 方法
|
||||
|
||||
**关键修改**:
|
||||
```python
|
||||
# 即使有sourceHandle,也要保留内存相关字段
|
||||
if edge.get('sourceHandle'):
|
||||
input_data[edge['sourceHandle']] = source_output
|
||||
# 显式保留内存相关字段
|
||||
if isinstance(source_output, dict):
|
||||
for field in ['conversation_history', 'user_profile', 'context', 'memory']:
|
||||
if field in source_output:
|
||||
input_data[field] = source_output[field]
|
||||
else:
|
||||
# ... 原有逻辑
|
||||
```
|
||||
|
||||
### 5. 修复LLM节点的嵌套路径变量支持
|
||||
|
||||
**文件**:`backend/app/services/workflow_engine.py`
|
||||
|
||||
**修改位置**:`execute_node` 方法中的 `llm` 节点处理逻辑(变量替换部分)
|
||||
|
||||
**关键修改**:
|
||||
```python
|
||||
# 支持嵌套路径,如 {{memory.conversation_history}}
|
||||
if '.' in var_name:
|
||||
value = self._get_nested_value(input_data, var_name)
|
||||
else:
|
||||
# 原有逻辑:检查别名和直接字段
|
||||
value = input_data.get(var_name)
|
||||
if value is None:
|
||||
# 检查别名
|
||||
aliases = {
|
||||
'user_input': ['query', 'input', 'USER_INPUT', 'user_input'],
|
||||
'output': ['result', 'response', 'text', 'content']
|
||||
}
|
||||
for alias_key, alias_list in aliases.items():
|
||||
if var_name == alias_key:
|
||||
for alias in alias_list:
|
||||
value = input_data.get(alias)
|
||||
if value is not None:
|
||||
break
|
||||
```
|
||||
|
||||
**特殊处理**:`{{memory.conversation_history}}` 格式化
|
||||
```python
|
||||
# 如果是conversation_history,格式化为可读格式
|
||||
if var_name == 'memory.conversation_history' and isinstance(value, list):
|
||||
formatted_history = []
|
||||
for msg in value:
|
||||
role = msg.get('role', 'unknown')
|
||||
content = msg.get('content', '')
|
||||
if role == 'user':
|
||||
formatted_history.append(f"用户: {content}")
|
||||
elif role == 'assistant':
|
||||
formatted_history.append(f"助手: {content}")
|
||||
value = '\n'.join(formatted_history) if formatted_history else '无对话历史'
|
||||
```
|
||||
|
||||
### 6. 修复{{output}}变量的递归提取
|
||||
|
||||
**文件**:`backend/app/services/workflow_engine.py`
|
||||
|
||||
**修改位置**:`execute_node` 方法中的 `llm` 节点处理逻辑(`{{output}}` 变量处理)
|
||||
|
||||
**关键修改**:
|
||||
```python
|
||||
# 特殊处理output变量:递归查找right字段
|
||||
if var_path == 'output':
|
||||
right_value = input_data.get('right')
|
||||
if right_value:
|
||||
# 递归查找字符串值
|
||||
def extract_string_from_right(obj, depth=0):
|
||||
if isinstance(obj, str):
|
||||
return obj
|
||||
elif isinstance(obj, dict):
|
||||
# 优先检查常见字段
|
||||
for key in ['content', 'text', 'message', 'output']:
|
||||
if key in obj and isinstance(obj[key], str):
|
||||
return obj[key]
|
||||
# 递归查找right字段
|
||||
if 'right' in obj:
|
||||
return extract_string_from_right(obj['right'], depth + 1)
|
||||
return None
|
||||
|
||||
value = extract_string_from_right(right_value)
|
||||
if value:
|
||||
logger.info(f"[rjb] LLM节点从right字段提取output: {value[:100]}")
|
||||
```
|
||||
|
||||
### 7. 修复前端重复回复问题
|
||||
|
||||
**文件**:`frontend/src/components/AgentChatPreview.vue`
|
||||
|
||||
**修改位置**:`handleSendMessage` 方法中的 `checkStatus` 函数
|
||||
|
||||
**关键修改**:
|
||||
```typescript
|
||||
// 添加标志位,防止重复添加回复
|
||||
let replyAdded = false
|
||||
|
||||
const checkStatus = async () => {
|
||||
try {
|
||||
// 如果已经添加过回复,直接返回
|
||||
if (replyAdded) {
|
||||
return
|
||||
}
|
||||
|
||||
// ... 获取执行状态 ...
|
||||
|
||||
if (exec.status === 'completed') {
|
||||
// 防止重复添加
|
||||
if (replyAdded) {
|
||||
return
|
||||
}
|
||||
|
||||
// 标记已添加回复
|
||||
replyAdded = true
|
||||
|
||||
// 添加回复消息
|
||||
messages.value.push({
|
||||
role: 'agent',
|
||||
content: agentReply || '执行完成',
|
||||
timestamp: Date.now()
|
||||
})
|
||||
|
||||
// ... 其他逻辑 ...
|
||||
}
|
||||
} catch (error) {
|
||||
// 同样添加防重复逻辑
|
||||
if (replyAdded) {
|
||||
return
|
||||
}
|
||||
replyAdded = true
|
||||
// ... 错误处理 ...
|
||||
}
|
||||
}
|
||||
|
||||
// 每次发送新消息时重置标志位
|
||||
replyAdded = false
|
||||
```
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 测试步骤
|
||||
|
||||
1. **第一次对话**:
|
||||
- 输入:`我的名字叫老七`
|
||||
- 预期:助手正常回复,并将信息存储到记忆
|
||||
|
||||
2. **第二次对话**:
|
||||
- 输入:`你还记得我的名字吗?`
|
||||
- 预期:助手回答 `是的,我记得你叫老七`
|
||||
|
||||
3. **验证重复回复**:
|
||||
- 观察是否只收到一次回复
|
||||
|
||||
### 测试结果
|
||||
|
||||
✅ **记忆功能**:正常工作,能正确记住用户名字
|
||||
✅ **重复回复**:已修复,每次对话只回复一次
|
||||
|
||||
## 关键代码文件
|
||||
|
||||
1. **后端核心逻辑**:
|
||||
- `backend/app/services/workflow_engine.py` - 工作流执行引擎
|
||||
- `backend/scripts/generate_chat_agent.py` - 智能聊天助手工作流定义
|
||||
|
||||
2. **前端组件**:
|
||||
- `frontend/src/components/AgentChatPreview.vue` - 聊天预览组件
|
||||
|
||||
3. **测试脚本**:
|
||||
- `test_memory_functionality.py` - 记忆功能测试脚本
|
||||
- `test_output_variable_extraction.py` - 输出变量提取测试脚本
|
||||
|
||||
## 修复时间线
|
||||
|
||||
1. **问题发现**:用户报告无法记住名字
|
||||
2. **初步分析**:检查工作流定义和节点配置
|
||||
3. **深入调试**:添加详细日志,追踪数据流
|
||||
4. **修复Cache节点**:修复数据存储和读取逻辑
|
||||
5. **修复Transform节点**:修复数据合并逻辑
|
||||
6. **修复LLM节点**:修复变量替换和嵌套路径支持
|
||||
7. **修复前端**:修复重复回复问题
|
||||
8. **测试验证**:确认所有问题已解决
|
||||
|
||||
## 经验总结
|
||||
|
||||
1. **数据流追踪**:在复杂工作流中,需要仔细追踪数据在每个节点之间的传递
|
||||
2. **变量替换时机**:变量替换必须在表达式执行之前完成
|
||||
3. **数据结构一致性**:确保上下游节点对数据结构的期望一致
|
||||
4. **边界情况处理**:注意处理 `null`、空值、嵌套结构等边界情况
|
||||
5. **前端防重复**:轮询逻辑中需要添加防重复机制
|
||||
|
||||
## 后续优化建议
|
||||
|
||||
1. **统一数据结构**:定义统一的数据结构规范,避免节点间数据格式不一致
|
||||
2. **增强日志**:添加更详细的调试日志,方便问题排查
|
||||
3. **单元测试**:为关键节点添加单元测试,确保修复的稳定性
|
||||
4. **性能优化**:优化轮询频率,减少不必要的API调用
|
||||
5. **错误处理**:增强错误处理机制,提供更友好的错误提示
|
||||
|
||||
---
|
||||
|
||||
**修复完成时间**:2024年(根据实际时间填写)
|
||||
**修复人员**:AI Assistant
|
||||
**文档版本**:v1.0
|
||||
167
docs/chat-assistant/智能聊天助手性能优化实施报告.md
Normal file
167
docs/chat-assistant/智能聊天助手性能优化实施报告.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# 智能聊天助手性能优化实施报告
|
||||
|
||||
## 📊 优化完成情况
|
||||
|
||||
### ✅ 已完成的优化
|
||||
|
||||
#### 1. 删除 llm-format 节点 ⭐⭐⭐⭐⭐
|
||||
- **状态**:✅ 已完成
|
||||
- **优化内容**:
|
||||
- 删除了 `llm-format` 节点(原第14个节点)
|
||||
- 优化了 `llm-question` 节点的 prompt,直接生成格式化好的回复
|
||||
- 更新了工作流边连接:`cache-update` 直接连接到 `end-1`
|
||||
- **效果**:减少 1 个 LLM 调用,节省 **1-2 秒**
|
||||
|
||||
#### 2. 优化 max_tokens 配置 ⭐⭐⭐⭐
|
||||
- **状态**:✅ 已完成
|
||||
- **优化内容**:
|
||||
- `llm-intent`: 1000 → **200** (减少 80%)
|
||||
- `llm-greeting`: 500 → **200** (减少 60%)
|
||||
- `llm-question`: 2000 → **1000** (减少 50%)
|
||||
- `llm-emotion`: 1000 → **500** (减少 50%)
|
||||
- `llm-request`: 1500 → **800** (减少 47%)
|
||||
- `llm-goodbye`: 300 → **150** (减少 50%)
|
||||
- `llm-general`: 1000 → **500** (减少 50%)
|
||||
- **效果**:减少 token 生成时间,节省 **0.5-1 秒**,降低 **30-40%** token 消耗
|
||||
|
||||
#### 3. 对话历史截断 ⭐⭐⭐⭐
|
||||
- **状态**:✅ 已完成
|
||||
- **优化内容**:
|
||||
- 在 `workflow_engine.py` 中添加了对话历史截断逻辑
|
||||
- 自动保留最近 **20 条**对话记录
|
||||
- 在 `cache-update` 节点执行后自动截断
|
||||
- **效果**:
|
||||
- 减少 prompt 长度,节省 **0.2-0.5 秒**
|
||||
- 降低 token 消耗
|
||||
- 提升 LLM 响应速度
|
||||
|
||||
## 📈 性能提升预期
|
||||
|
||||
### 优化前
|
||||
- **平均响应时间**:5-6 秒
|
||||
- **LLM 调用次数**:3 次(意图理解 + 问题回答 + 格式化)
|
||||
- **Token 消耗**:约 3500-4500 tokens/对话
|
||||
- **节点数量**:15 个
|
||||
|
||||
### 优化后
|
||||
- **平均响应时间**:**3-4 秒**(提升 **40%**)
|
||||
- **LLM 调用次数**:**2 次**(意图理解 + 问题回答)
|
||||
- **Token 消耗**:约 **2000-2800 tokens/对话**(减少 **30-40%**)
|
||||
- **节点数量**:**14 个**(减少 1 个)
|
||||
|
||||
## 🔧 技术实现细节
|
||||
|
||||
### 1. 工作流结构优化
|
||||
|
||||
**优化前流程**:
|
||||
```
|
||||
开始 → 查询记忆 → 合并上下文 → 意图理解 → 意图路由 →
|
||||
[5个分支] → 合并回复 → 更新记忆 → 格式化回复 → 结束
|
||||
```
|
||||
|
||||
**优化后流程**:
|
||||
```
|
||||
开始 → 查询记忆 → 合并上下文 → 意图理解 → 意图路由 →
|
||||
[5个分支,直接生成最终回复] → 合并回复 → 更新记忆 → 结束
|
||||
```
|
||||
|
||||
### 2. LLM 节点 Prompt 优化
|
||||
|
||||
**llm-question 节点优化**:
|
||||
- 添加了"确保回复格式自然、完整,无需额外格式化"的指令
|
||||
- 让 LLM 直接生成最终格式的回复,避免二次格式化
|
||||
|
||||
### 3. 对话历史截断实现
|
||||
|
||||
**位置**:`backend/app/services/workflow_engine.py`
|
||||
|
||||
**实现逻辑**:
|
||||
```python
|
||||
# 确保conversation_history只保留最近的20条(性能优化)
|
||||
if isinstance(value, dict) and 'conversation_history' in value:
|
||||
if isinstance(value['conversation_history'], list):
|
||||
max_history_length = 20
|
||||
if len(value['conversation_history']) > max_history_length:
|
||||
value['conversation_history'] = value['conversation_history'][-max_history_length:]
|
||||
logger.info(f"[rjb] 对话历史已截断,保留最近 {max_history_length} 条")
|
||||
```
|
||||
|
||||
## 📋 优化清单
|
||||
|
||||
| 优化项 | 状态 | 预期效果 | 实际效果 |
|
||||
|--------|------|----------|----------|
|
||||
| 删除 llm-format 节点 | ✅ 完成 | 节省 1-2 秒 | 待测试 |
|
||||
| 优化 max_tokens | ✅ 完成 | 节省 0.5-1 秒 | 待测试 |
|
||||
| 对话历史截断 | ✅ 完成 | 节省 0.2-0.5 秒 | 待测试 |
|
||||
|
||||
## 🚀 下一步建议
|
||||
|
||||
### 中优先级优化(可选)
|
||||
|
||||
1. **使用 WebSocket 替代轮询** ⭐⭐⭐⭐
|
||||
- 实施难度:中
|
||||
- 效果:提升实时性,减少服务器负载
|
||||
- 预计时间:2-3 小时
|
||||
|
||||
2. **智能轮询(如果不用 WebSocket)** ⭐⭐⭐
|
||||
- 实施难度:低
|
||||
- 效果:减少 30-50% 无效请求
|
||||
- 预计时间:1 小时
|
||||
|
||||
### 高级优化(可选)
|
||||
|
||||
3. **流式响应** ⭐⭐⭐⭐⭐
|
||||
- 实施难度:高
|
||||
- 效果:首字响应时间降低 50-70%
|
||||
- 预计时间:4-6 小时
|
||||
|
||||
4. **LLM 响应缓存** ⭐⭐⭐
|
||||
- 实施难度:中
|
||||
- 效果:重复问题响应时间 < 100ms
|
||||
- 预计时间:2-3 小时
|
||||
|
||||
## 📝 测试建议
|
||||
|
||||
1. **性能测试**:
|
||||
- 测试优化前后的响应时间对比
|
||||
- 监控 LLM API 调用次数和耗时
|
||||
- 检查对话历史是否正确截断
|
||||
|
||||
2. **功能测试**:
|
||||
- 验证删除 llm-format 节点后,回复格式是否正常
|
||||
- 验证各分支节点的回复质量
|
||||
- 验证记忆功能是否正常
|
||||
|
||||
3. **压力测试**:
|
||||
- 测试长时间对话(超过20条)时的性能
|
||||
- 测试并发请求的处理能力
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **向后兼容**:优化后的配置已更新到数据库,现有对话会使用新配置
|
||||
2. **对话历史**:超过20条的旧对话历史会被自动截断
|
||||
3. **回复格式**:由于删除了格式化节点,需要确保各分支节点生成的回复格式正确
|
||||
|
||||
## 📊 监控指标
|
||||
|
||||
建议监控以下指标以验证优化效果:
|
||||
|
||||
1. **响应时间**:
|
||||
- P50(中位数)
|
||||
- P95(95% 分位数)
|
||||
- P99(99% 分位数)
|
||||
|
||||
2. **LLM 调用**:
|
||||
- 各节点的平均调用时间
|
||||
- Token 消耗统计
|
||||
|
||||
3. **系统资源**:
|
||||
- CPU 使用率
|
||||
- 内存使用率
|
||||
- 数据库连接数
|
||||
|
||||
---
|
||||
|
||||
**优化完成时间**:2024年
|
||||
**优化版本**:v1.0
|
||||
**维护人员**:AI Assistant
|
||||
270
docs/chat-assistant/智能需求分析与解决方案生成器_使用说明.md
Normal file
270
docs/chat-assistant/智能需求分析与解决方案生成器_使用说明.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# 智能需求分析与解决方案生成器 - 使用说明
|
||||
|
||||
## 📋 Agent 基本信息
|
||||
|
||||
- **名称**: 智能需求分析与解决方案生成器
|
||||
- **状态**: 已发布(可直接使用)
|
||||
- **节点数量**: 8个节点
|
||||
- **连接数量**: 8条连接
|
||||
- **Agent ID**: `9195f8df-3340-46a0-b761-b955a57acc6c`
|
||||
|
||||
## 🎯 功能概述
|
||||
|
||||
这是一个智能的多节点Agent,能够:
|
||||
1. **自动理解用户需求** - 分析用户输入,提取关键信息
|
||||
2. **智能需求分类** - 根据需求类型自动分类(技术方案/业务流程/数据分析等)
|
||||
3. **专业方案生成** - 调用专业模板或LLM生成针对性解决方案
|
||||
4. **方案整合优化** - 整合各分支结果,优化输出格式
|
||||
5. **专业文档输出** - 生成结构化的Markdown文档
|
||||
|
||||
## 🔄 工作流结构
|
||||
|
||||
```
|
||||
开始节点
|
||||
↓
|
||||
需求理解与分析节点(LLM)
|
||||
↓
|
||||
需求分类节点(条件判断)
|
||||
├─→ [技术方案分支] → 技术方案设计节点(Template/LLM)
|
||||
└─→ [业务流程分支] → 业务流程设计节点(Template/LLM)
|
||||
↓ ↓
|
||||
└────→ 方案整合节点(Transform)
|
||||
↓
|
||||
输出优化与格式化节点(LLM)
|
||||
↓
|
||||
结束节点
|
||||
```
|
||||
|
||||
## 📊 节点详细说明
|
||||
|
||||
### 1. 开始节点(start-1)
|
||||
- **功能**: 接收用户输入
|
||||
- **输入格式**: JSON格式
|
||||
- **输出**: 将用户输入传递给需求理解节点
|
||||
|
||||
### 2. 需求理解与分析节点(llm-requirement-analysis)
|
||||
- **类型**: LLM节点
|
||||
- **模型**: DeepSeek Chat
|
||||
- **功能**:
|
||||
- 分析用户需求
|
||||
- 提取关键信息
|
||||
- 识别需求类型、复杂度、领域等
|
||||
- **输出格式**: JSON
|
||||
```json
|
||||
{
|
||||
"requirement_type": "技术方案|业务流程|数据分析|工作流设计|其他",
|
||||
"key_points": ["关键点1", "关键点2", ...],
|
||||
"complexity": "简单|中等|复杂",
|
||||
"domain": "领域(如:电商、金融、教育等)",
|
||||
"summary": "需求摘要"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 需求分类节点(condition-classify)
|
||||
- **类型**: 条件节点
|
||||
- **功能**: 根据需求类型进行分支
|
||||
- **判断条件**:
|
||||
- 如果需求类型是"技术方案"或"API集成" → 走技术方案分支
|
||||
- 否则 → 走业务流程分支
|
||||
|
||||
### 4. 技术方案设计节点
|
||||
- **类型**: Template节点(优先)或LLM节点(备用)
|
||||
- **功能**: 生成技术方案
|
||||
- **输出内容**:
|
||||
- 技术选型建议
|
||||
- 架构设计
|
||||
- 实施步骤
|
||||
- 风险评估
|
||||
- 最佳实践建议
|
||||
|
||||
### 5. 业务流程设计节点
|
||||
- **类型**: Template节点(优先)或LLM节点(备用)
|
||||
- **功能**: 生成业务流程方案
|
||||
- **输出内容**:
|
||||
- 流程概述
|
||||
- 关键步骤
|
||||
- 角色与职责
|
||||
- 流程优化建议
|
||||
- 实施路线图
|
||||
|
||||
### 6. 方案整合节点(transform-integration)
|
||||
- **类型**: Transform节点
|
||||
- **功能**: 整合各分支的结果
|
||||
- **模式**: 合并模式
|
||||
- **输出**: 包含解决方案、需求分析、时间戳的整合数据
|
||||
|
||||
### 7. 输出优化与格式化节点(llm-optimization)
|
||||
- **类型**: LLM节点
|
||||
- **模型**: DeepSeek Chat
|
||||
- **功能**:
|
||||
- 优化文档结构
|
||||
- 补充关键细节
|
||||
- 添加实施建议
|
||||
- 统一格式
|
||||
- **输出**: 完整的Markdown文档
|
||||
|
||||
### 8. 结束节点(end-1)
|
||||
- **功能**: 返回最终结果
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 方法一:通过Agent管理界面测试
|
||||
|
||||
1. **进入Agent管理页面**
|
||||
- 在左侧菜单选择"Agent管理"
|
||||
- 找到"智能需求分析与解决方案生成器"
|
||||
|
||||
2. **测试Agent**
|
||||
- 点击Agent名称进入详情页
|
||||
- 点击"测试"按钮
|
||||
- 在输入框中输入你的需求
|
||||
|
||||
3. **输入示例**:
|
||||
```json
|
||||
{
|
||||
"query": "我需要设计一个电商系统的用户订单处理流程,包括下单、支付、发货、售后等环节"
|
||||
}
|
||||
```
|
||||
或者简单输入:
|
||||
```json
|
||||
{
|
||||
"query": "设计一个微服务架构的在线教育平台"
|
||||
}
|
||||
```
|
||||
|
||||
4. **查看结果**
|
||||
- 等待Agent执行完成(通常需要30-60秒)
|
||||
- 查看生成的解决方案文档
|
||||
|
||||
### 方法二:通过API调用
|
||||
|
||||
```bash
|
||||
POST /api/v1/executions
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <your_token>
|
||||
|
||||
{
|
||||
"agent_id": "9195f8df-3340-46a0-b761-b955a57acc6c",
|
||||
"input_data": {
|
||||
"query": "你的需求描述"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 💡 使用场景示例
|
||||
|
||||
### 场景1:技术方案设计
|
||||
**输入**:
|
||||
```
|
||||
设计一个高并发的实时推荐系统,需要支持千万级用户,毫秒级响应
|
||||
```
|
||||
|
||||
**输出**:
|
||||
- 技术选型(Redis、Kafka、Spark等)
|
||||
- 架构设计图
|
||||
- 实施步骤
|
||||
- 性能优化建议
|
||||
|
||||
### 场景2:业务流程优化
|
||||
**输入**:
|
||||
```
|
||||
优化我们公司的客户服务流程,提高客户满意度
|
||||
```
|
||||
|
||||
**输出**:
|
||||
- 当前流程分析
|
||||
- 优化建议
|
||||
- 新流程设计
|
||||
- 实施路线图
|
||||
|
||||
### 场景3:系统架构设计
|
||||
**输入**:
|
||||
```
|
||||
设计一个微服务架构的电商平台,包括用户、商品、订单、支付等模块
|
||||
```
|
||||
|
||||
**输出**:
|
||||
- 微服务拆分方案
|
||||
- 服务间通信设计
|
||||
- 数据一致性方案
|
||||
- 部署架构
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### 节点配置参数
|
||||
|
||||
- **LLM节点温度**: 0.5-0.7(平衡创造性和准确性)
|
||||
- **最大Token数**: 2000-3000(确保输出完整)
|
||||
- **模型**: DeepSeek Chat(默认)
|
||||
|
||||
### 自定义配置
|
||||
|
||||
如果需要修改Agent配置:
|
||||
1. 进入Agent管理页面
|
||||
2. 点击"设计"按钮
|
||||
3. 在可视化编辑器中修改节点配置
|
||||
4. 保存并发布
|
||||
|
||||
## 📝 输出格式
|
||||
|
||||
Agent最终输出为结构化的Markdown文档,包含:
|
||||
|
||||
1. **需求摘要**
|
||||
2. **需求分析结果**
|
||||
- 需求类型
|
||||
- 关键点
|
||||
- 复杂度评估
|
||||
- 领域识别
|
||||
3. **解决方案**
|
||||
- 详细方案内容
|
||||
- 实施建议
|
||||
- 最佳实践
|
||||
4. **附录**
|
||||
- 相关资源
|
||||
- 注意事项
|
||||
|
||||
## 🔍 注意事项
|
||||
|
||||
1. **输入格式**: 建议使用JSON格式,包含`query`字段
|
||||
2. **执行时间**: 复杂需求可能需要60-120秒
|
||||
3. **Token限制**: 如果输出被截断,可以增加`max_tokens`参数
|
||||
4. **需求描述**: 越详细的需求描述,生成的方案越准确
|
||||
|
||||
## 🛠️ 故障排查
|
||||
|
||||
### 问题1:Agent执行超时
|
||||
**解决方案**:
|
||||
- 检查网络连接
|
||||
- 确认LLM服务正常
|
||||
- 简化需求描述
|
||||
|
||||
### 问题2:输出不完整
|
||||
**解决方案**:
|
||||
- 增加`max_tokens`参数
|
||||
- 分段处理复杂需求
|
||||
|
||||
### 问题3:分类不准确
|
||||
**解决方案**:
|
||||
- 在需求描述中明确说明需求类型
|
||||
- 例如:"我需要一个技术方案..."或"请帮我设计业务流程..."
|
||||
|
||||
## 📈 性能优化建议
|
||||
|
||||
1. **缓存机制**: 对于相似需求,可以复用之前的分析结果
|
||||
2. **并行处理**: 对于多个独立需求,可以并行执行
|
||||
3. **模板优化**: 根据使用频率优化模板选择逻辑
|
||||
|
||||
## 🔄 更新日志
|
||||
|
||||
- **v1.0** (2026-01-19): 初始版本
|
||||
- 支持需求理解和分类
|
||||
- 支持技术方案和业务流程生成
|
||||
- 支持输出优化和格式化
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如有问题或建议,请联系系统管理员或查看系统日志。
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-01-19
|
||||
374
docs/chat-assistant/聊天智能体示例.json
Normal file
374
docs/chat-assistant/聊天智能体示例.json
Normal file
@@ -0,0 +1,374 @@
|
||||
{
|
||||
"name": "智能聊天助手(完整示例)",
|
||||
"description": "一个完整的聊天智能体示例,展示平台的核心能力:\n- ✅ 记忆管理:使用缓存节点存储和查询对话历史\n- ✅ 意图识别:使用LLM节点分析用户意图\n- ✅ 多分支路由:使用Switch节点根据意图分发到不同处理分支\n- ✅ 上下文传递:使用Transform节点合并数据\n- ✅ 多轮对话:支持上下文记忆和连贯对话\n- ✅ 个性化回复:根据不同意图生成针对性回复\n\n适用场景:情感陪聊、客服助手、智能问答等聊天场景。",
|
||||
"workflow_config": {
|
||||
"nodes": [
|
||||
{
|
||||
"id": "start-1",
|
||||
"type": "start",
|
||||
"position": {
|
||||
"x": 50,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "开始",
|
||||
"output_format": "json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cache-query",
|
||||
"type": "cache",
|
||||
"position": {
|
||||
"x": 250,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "查询记忆",
|
||||
"operation": "get",
|
||||
"key": "user_memory_{user_id}",
|
||||
"default_value": "{\"conversation_history\": [], \"user_profile\": {}, \"context\": {}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "transform-merge",
|
||||
"type": "transform",
|
||||
"position": {
|
||||
"x": 450,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "合并上下文",
|
||||
"mode": "merge",
|
||||
"mapping": {
|
||||
"user_input": "{{query}}",
|
||||
"memory": "{{output}}",
|
||||
"timestamp": "{{timestamp}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "llm-intent",
|
||||
"type": "llm",
|
||||
"position": {
|
||||
"x": 650,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "意图理解",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"temperature": "0.3",
|
||||
"max_tokens": "1000",
|
||||
"prompt": "你是一个专业的对话意图分析助手。请分析用户的输入,识别用户的意图和情感。\n\n用户输入:{{user_input}}\n对话历史:{{memory.conversation_history}}\n用户画像:{{memory.user_profile}}\n\n请以JSON格式输出分析结果:\n{\n \"intent\": \"意图类型(greeting/question/emotion/request/goodbye/other)\",\n \"emotion\": \"情感状态(positive/neutral/negative)\",\n \"keywords\": [\"关键词1\", \"关键词2\"],\n \"topic\": \"话题主题\",\n \"needs_response\": true\n}\n\n请确保输出是有效的JSON格式,不要包含其他文字。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "switch-intent",
|
||||
"type": "switch",
|
||||
"position": {
|
||||
"x": 850,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "意图路由",
|
||||
"field": "intent",
|
||||
"cases": {
|
||||
"greeting": "greeting-handle",
|
||||
"question": "question-handle",
|
||||
"emotion": "emotion-handle",
|
||||
"request": "request-handle",
|
||||
"goodbye": "goodbye-handle"
|
||||
},
|
||||
"default": "general-handle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "llm-greeting",
|
||||
"type": "llm",
|
||||
"position": {
|
||||
"x": 1050,
|
||||
"y": 200
|
||||
},
|
||||
"data": {
|
||||
"label": "问候回复",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"temperature": "0.7",
|
||||
"max_tokens": "500",
|
||||
"prompt": "你是一个温暖、友好的AI助手。用户向你打招呼,请用自然、亲切的方式回应。\n\n用户输入:{{user_input}}\n对话历史:{{memory.conversation_history}}\n\n请生成一个友好、自然的问候回复,长度控制在50字以内。直接输出回复内容,不要包含其他说明。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "llm-question",
|
||||
"type": "llm",
|
||||
"position": {
|
||||
"x": 1050,
|
||||
"y": 300
|
||||
},
|
||||
"data": {
|
||||
"label": "问题回答",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"temperature": "0.5",
|
||||
"max_tokens": "2000",
|
||||
"prompt": "你是一个知识渊博、乐于助人的AI助手。请回答用户的问题。\n\n用户问题:{{user_input}}\n对话历史:{{memory.conversation_history}}\n意图分析:{{output}}\n\n请提供:\n1. 直接、准确的答案\n2. 必要的解释和说明\n3. 如果问题不明确,友好地询问更多信息\n\n请以自然、易懂的方式回答,长度控制在200字以内。直接输出回答内容。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "llm-emotion",
|
||||
"type": "llm",
|
||||
"position": {
|
||||
"x": 1050,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "情感回应",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"temperature": "0.8",
|
||||
"max_tokens": "1000",
|
||||
"prompt": "你是一个善解人意的AI助手。请根据用户的情感状态,给予适当的回应。\n\n用户输入:{{user_input}}\n情感状态:{{output.emotion}}\n对话历史:{{memory.conversation_history}}\n\n请根据用户的情感:\n- 如果是积极情感:给予鼓励和共鸣\n- 如果是消极情感:给予理解、安慰和支持\n- 如果是中性情感:给予关注和陪伴\n\n请生成一个温暖、共情的回复,长度控制在150字以内。直接输出回复内容。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "llm-request",
|
||||
"type": "llm",
|
||||
"position": {
|
||||
"x": 1050,
|
||||
"y": 500
|
||||
},
|
||||
"data": {
|
||||
"label": "请求处理",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"temperature": "0.4",
|
||||
"max_tokens": "1500",
|
||||
"prompt": "你是一个专业的AI助手。用户提出了一个请求,请分析并回应。\n\n用户请求:{{user_input}}\n意图分析:{{output}}\n对话历史:{{memory.conversation_history}}\n\n请:\n1. 理解用户的请求内容\n2. 如果可以满足,说明如何满足\n3. 如果无法满足,友好地说明原因并提供替代方案\n\n请以清晰、友好的方式回应,长度控制在200字以内。直接输出回复内容。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "llm-goodbye",
|
||||
"type": "llm",
|
||||
"position": {
|
||||
"x": 1050,
|
||||
"y": 600
|
||||
},
|
||||
"data": {
|
||||
"label": "告别回复",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"temperature": "0.6",
|
||||
"max_tokens": "300",
|
||||
"prompt": "你是一个友好的AI助手。用户要结束对话,请给予温暖的告别。\n\n用户输入:{{user_input}}\n对话历史:{{memory.conversation_history}}\n\n请生成一个温暖、友好的告别回复,表达期待下次交流。长度控制在50字以内。直接输出回复内容。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "llm-general",
|
||||
"type": "llm",
|
||||
"position": {
|
||||
"x": 1050,
|
||||
"y": 700
|
||||
},
|
||||
"data": {
|
||||
"label": "通用回复",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"temperature": "0.6",
|
||||
"max_tokens": "1000",
|
||||
"prompt": "你是一个友好、专业的AI助手。请回应用户的输入。\n\n用户输入:{{user_input}}\n对话历史:{{memory.conversation_history}}\n意图分析:{{output}}\n\n请生成一个自然、有意义的回复,保持对话的连贯性。长度控制在150字以内。直接输出回复内容。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "merge-response",
|
||||
"type": "merge",
|
||||
"position": {
|
||||
"x": 1250,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "合并回复",
|
||||
"mode": "merge_first",
|
||||
"strategy": "object"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cache-update",
|
||||
"type": "cache",
|
||||
"position": {
|
||||
"x": 1450,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "更新记忆",
|
||||
"operation": "set",
|
||||
"key": "user_memory_{user_id}",
|
||||
"value": "{\"conversation_history\": {{memory.conversation_history}} + [{\"role\": \"user\", \"content\": \"{{user_input}}\", \"timestamp\": \"{{timestamp}}\"}, {\"role\": \"assistant\", \"content\": \"{{output}}\", \"timestamp\": \"{{timestamp}}\"}], \"user_profile\": {{memory.user_profile}}, \"context\": {{memory.context}}}",
|
||||
"ttl": 86400
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "llm-format",
|
||||
"type": "llm",
|
||||
"position": {
|
||||
"x": 1650,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "格式化回复",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"temperature": "0.3",
|
||||
"max_tokens": "500",
|
||||
"prompt": "请将以下回复内容格式化为最终输出。确保回复自然、流畅。\n\n原始回复:{{output}}\n\n请直接输出格式化后的回复内容,不要包含其他说明或标记。如果原始回复已经是合适的格式,直接输出即可。"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "end-1",
|
||||
"type": "end",
|
||||
"position": {
|
||||
"x": 1850,
|
||||
"y": 400
|
||||
},
|
||||
"data": {
|
||||
"label": "结束",
|
||||
"output_format": "text"
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "e1",
|
||||
"source": "start-1",
|
||||
"target": "cache-query",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e2",
|
||||
"source": "cache-query",
|
||||
"target": "transform-merge",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e3",
|
||||
"source": "transform-merge",
|
||||
"target": "llm-intent",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e4",
|
||||
"source": "llm-intent",
|
||||
"target": "switch-intent",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e5-greeting",
|
||||
"source": "switch-intent",
|
||||
"target": "llm-greeting",
|
||||
"sourceHandle": "greeting-handle",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e5-question",
|
||||
"source": "switch-intent",
|
||||
"target": "llm-question",
|
||||
"sourceHandle": "question-handle",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e5-emotion",
|
||||
"source": "switch-intent",
|
||||
"target": "llm-emotion",
|
||||
"sourceHandle": "emotion-handle",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e5-request",
|
||||
"source": "switch-intent",
|
||||
"target": "llm-request",
|
||||
"sourceHandle": "request-handle",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e5-goodbye",
|
||||
"source": "switch-intent",
|
||||
"target": "llm-goodbye",
|
||||
"sourceHandle": "goodbye-handle",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e5-general",
|
||||
"source": "switch-intent",
|
||||
"target": "llm-general",
|
||||
"sourceHandle": "default",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e6-greeting",
|
||||
"source": "llm-greeting",
|
||||
"target": "merge-response",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e6-question",
|
||||
"source": "llm-question",
|
||||
"target": "merge-response",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e6-emotion",
|
||||
"source": "llm-emotion",
|
||||
"target": "merge-response",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e6-request",
|
||||
"source": "llm-request",
|
||||
"target": "merge-response",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e6-goodbye",
|
||||
"source": "llm-goodbye",
|
||||
"target": "merge-response",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e6-general",
|
||||
"source": "llm-general",
|
||||
"target": "merge-response",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e7",
|
||||
"source": "merge-response",
|
||||
"target": "cache-update",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e8",
|
||||
"source": "cache-update",
|
||||
"target": "llm-format",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
},
|
||||
{
|
||||
"id": "e9",
|
||||
"source": "llm-format",
|
||||
"target": "end-1",
|
||||
"sourceHandle": "right",
|
||||
"targetHandle": "left"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
337
docs/chat-assistant/聊天智能体示例说明.md
Normal file
337
docs/chat-assistant/聊天智能体示例说明.md
Normal file
@@ -0,0 +1,337 @@
|
||||
# 智能聊天Agent完整示例说明
|
||||
|
||||
## 📋 概述
|
||||
|
||||
这是一个完整的聊天智能体示例,展示了如何使用平台的核心能力构建一个功能完善的聊天助手。该示例包含了记忆管理、意图识别、多分支路由、上下文传递等核心功能。
|
||||
|
||||
## 🎯 功能特性
|
||||
|
||||
### ✅ 核心能力展示
|
||||
|
||||
1. **记忆管理**
|
||||
- 使用缓存节点存储对话历史
|
||||
- 支持用户画像和上下文信息
|
||||
- 自动更新记忆内容
|
||||
|
||||
2. **意图识别**
|
||||
- 使用LLM节点分析用户意图
|
||||
- 识别情感状态
|
||||
- 提取关键词和话题
|
||||
|
||||
3. **多分支路由**
|
||||
- 使用Switch节点根据意图分发
|
||||
- 支持6种不同场景的处理分支
|
||||
- 默认分支处理未知意图
|
||||
|
||||
4. **上下文传递**
|
||||
- 使用Transform节点合并数据
|
||||
- 保持对话历史的连贯性
|
||||
- 支持多轮对话
|
||||
|
||||
5. **个性化回复**
|
||||
- 根据不同意图生成针对性回复
|
||||
- 考虑用户情感状态
|
||||
- 保持对话风格一致
|
||||
|
||||
## 🔄 工作流结构
|
||||
|
||||
```
|
||||
开始节点
|
||||
↓
|
||||
查询记忆(Cache节点)
|
||||
↓
|
||||
合并上下文(Transform节点)
|
||||
↓
|
||||
意图理解(LLM节点)
|
||||
↓
|
||||
意图路由(Switch节点)
|
||||
├─→ 问候处理(greeting)
|
||||
├─→ 问题回答(question)
|
||||
├─→ 情感回应(emotion)
|
||||
├─→ 请求处理(request)
|
||||
├─→ 告别回复(goodbye)
|
||||
└─→ 通用回复(default)
|
||||
↓
|
||||
合并回复(Merge节点)
|
||||
↓
|
||||
更新记忆(Cache节点)
|
||||
↓
|
||||
格式化回复(LLM节点)
|
||||
↓
|
||||
结束节点
|
||||
```
|
||||
|
||||
## 📊 节点详细说明
|
||||
|
||||
### 1. 开始节点(start-1)
|
||||
- **功能**: 接收用户输入
|
||||
- **输入格式**: JSON格式,包含 `query` 字段
|
||||
- **输出**: 将用户输入传递给后续节点
|
||||
|
||||
### 2. 查询记忆节点(cache-query)
|
||||
- **类型**: Cache节点
|
||||
- **操作**: `get` - 获取用户记忆
|
||||
- **Key**: `user_memory_{user_id}`
|
||||
- **默认值**: 空记忆结构
|
||||
- **功能**: 从缓存中读取用户的对话历史和画像信息
|
||||
|
||||
### 3. 合并上下文节点(transform-merge)
|
||||
- **类型**: Transform节点
|
||||
- **模式**: `merge` - 合并模式
|
||||
- **功能**: 将用户输入、记忆数据、时间戳合并为完整上下文
|
||||
|
||||
### 4. 意图理解节点(llm-intent)
|
||||
- **类型**: LLM节点
|
||||
- **模型**: DeepSeek Chat
|
||||
- **功能**:
|
||||
- 分析用户输入
|
||||
- 识别意图类型(greeting/question/emotion/request/goodbye/other)
|
||||
- 识别情感状态(positive/neutral/negative)
|
||||
- 提取关键词和话题
|
||||
- **输出格式**: JSON
|
||||
```json
|
||||
{
|
||||
"intent": "意图类型",
|
||||
"emotion": "情感状态",
|
||||
"keywords": ["关键词"],
|
||||
"topic": "话题主题",
|
||||
"needs_response": true
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 意图路由节点(switch-intent)
|
||||
- **类型**: Switch节点
|
||||
- **功能**: 根据意图类型路由到不同的处理分支
|
||||
- **分支**:
|
||||
- `greeting` → 问候处理
|
||||
- `question` → 问题回答
|
||||
- `emotion` → 情感回应
|
||||
- `request` → 请求处理
|
||||
- `goodbye` → 告别回复
|
||||
- `default` → 通用回复
|
||||
|
||||
### 6. 各分支处理节点(llm-*)
|
||||
- **类型**: LLM节点
|
||||
- **功能**: 根据不同意图生成针对性的回复
|
||||
- **特点**:
|
||||
- 问候分支:友好、亲切
|
||||
- 问题分支:准确、详细
|
||||
- 情感分支:共情、温暖
|
||||
- 请求分支:专业、清晰
|
||||
- 告别分支:温暖、期待
|
||||
- 通用分支:自然、连贯
|
||||
|
||||
### 7. 合并回复节点(merge-response)
|
||||
- **类型**: Merge节点
|
||||
- **模式**: `merge_first` - 合并第一个结果
|
||||
- **功能**: 将各分支的回复结果合并
|
||||
|
||||
### 8. 更新记忆节点(cache-update)
|
||||
- **类型**: Cache节点
|
||||
- **操作**: `set` - 设置记忆
|
||||
- **功能**:
|
||||
- 将本次对话添加到历史记录
|
||||
- 更新用户画像(如需要)
|
||||
- 保存上下文信息
|
||||
- **TTL**: 86400秒(24小时)
|
||||
|
||||
### 9. 格式化回复节点(llm-format)
|
||||
- **类型**: LLM节点
|
||||
- **功能**: 对最终回复进行格式化和优化
|
||||
- **输出**: 自然、流畅的文本回复
|
||||
|
||||
### 10. 结束节点(end-1)
|
||||
- **功能**: 返回最终回复
|
||||
- **输出格式**: 纯文本
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 方法一:使用生成脚本(推荐)
|
||||
|
||||
```bash
|
||||
cd backend/scripts
|
||||
python3 generate_chat_agent.py
|
||||
```
|
||||
|
||||
脚本会自动创建Agent,包含完整的工作流配置。
|
||||
|
||||
### 方法二:手动创建
|
||||
|
||||
1. **进入Agent管理页面**
|
||||
- 点击"创建Agent"按钮
|
||||
- 填写名称和描述
|
||||
|
||||
2. **进入工作流编辑器**
|
||||
- 点击"设计"按钮
|
||||
- 使用节点工具箱添加节点
|
||||
- 按照工作流结构连接节点
|
||||
|
||||
3. **配置节点**
|
||||
- **LLM节点**: 配置API密钥、模型、Prompt
|
||||
- **Cache节点**: 配置缓存Key和操作
|
||||
- **Switch节点**: 配置路由规则
|
||||
- **Transform节点**: 配置数据映射
|
||||
|
||||
4. **测试Agent**
|
||||
- 点击"测试"按钮
|
||||
- 输入测试消息
|
||||
- 查看执行结果
|
||||
|
||||
5. **发布Agent**
|
||||
- 点击"发布"按钮
|
||||
- Agent状态变为"已发布"
|
||||
- 可以开始使用
|
||||
|
||||
## 📝 配置要点
|
||||
|
||||
### 1. LLM节点配置
|
||||
|
||||
- **Provider**: 选择AI模型提供商(如DeepSeek、OpenAI)
|
||||
- **Model**: 选择具体模型(如deepseek-chat、gpt-3.5-turbo)
|
||||
- **Temperature**:
|
||||
- 意图识别:0.3(需要准确性)
|
||||
- 情感回应:0.8(需要创造性)
|
||||
- 问题回答:0.5(平衡准确性和灵活性)
|
||||
- **Max Tokens**: 根据回复长度需求设置
|
||||
- **Prompt**: 明确角色、任务、输出格式要求
|
||||
|
||||
### 2. Cache节点配置
|
||||
|
||||
- **Operation**:
|
||||
- `get`: 查询记忆
|
||||
- `set`: 更新记忆
|
||||
- **Key**: 使用用户ID确保记忆隔离
|
||||
- **TTL**: 设置合适的过期时间(如24小时)
|
||||
|
||||
### 3. Switch节点配置
|
||||
|
||||
- **Field**: 指定用于路由的字段(如`intent`)
|
||||
- **Cases**: 配置各分支的路由规则
|
||||
- **Default**: 配置默认分支
|
||||
|
||||
### 4. Transform节点配置
|
||||
|
||||
- **Mode**: 选择合并模式(`merge`)
|
||||
- **Mapping**: 配置数据映射规则
|
||||
- **变量引用**: 使用`{{variable}}`引用上游数据
|
||||
|
||||
## 🎨 自定义扩展
|
||||
|
||||
### 1. 添加新的意图分支
|
||||
|
||||
1. 在Switch节点中添加新的case
|
||||
2. 创建对应的LLM处理节点
|
||||
3. 连接Switch节点和处理节点
|
||||
4. 连接处理节点到Merge节点
|
||||
|
||||
### 2. 增强记忆功能
|
||||
|
||||
- 添加用户画像更新逻辑
|
||||
- 实现长期记忆和短期记忆分离
|
||||
- 添加记忆检索和总结功能
|
||||
|
||||
### 3. 添加外部工具
|
||||
|
||||
- 集成知识库查询
|
||||
- 添加天气、新闻等外部API
|
||||
- 实现文件处理功能
|
||||
|
||||
### 4. 优化回复质量
|
||||
|
||||
- 添加回复质量评估节点
|
||||
- 实现多候选回复生成和选择
|
||||
- 添加回复风格控制
|
||||
|
||||
## 🔍 测试示例
|
||||
|
||||
### 测试用例1:问候
|
||||
```
|
||||
输入: "你好"
|
||||
预期: 友好的问候回复
|
||||
```
|
||||
|
||||
### 测试用例2:问题
|
||||
```
|
||||
输入: "今天天气怎么样?"
|
||||
预期: 尝试回答问题或说明无法获取天气信息
|
||||
```
|
||||
|
||||
### 测试用例3:情感表达
|
||||
```
|
||||
输入: "我今天心情不太好"
|
||||
预期: 共情、安慰的回复
|
||||
```
|
||||
|
||||
### 测试用例4:请求
|
||||
```
|
||||
输入: "帮我写一首诗"
|
||||
预期: 生成诗歌或说明能力范围
|
||||
```
|
||||
|
||||
### 测试用例5:告别
|
||||
```
|
||||
输入: "再见"
|
||||
预期: 温暖的告别回复
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **API密钥配置**
|
||||
- 确保所有LLM节点都配置了有效的API密钥
|
||||
- 检查API配额和限制
|
||||
|
||||
2. **记忆管理**
|
||||
- Cache节点使用内存缓存,重启后会丢失
|
||||
- 生产环境建议使用Redis等持久化缓存
|
||||
|
||||
3. **性能优化**
|
||||
- 减少不必要的LLM调用
|
||||
- 优化Prompt长度
|
||||
- 合理设置Token限制
|
||||
|
||||
4. **错误处理**
|
||||
- 添加错误处理节点
|
||||
- 配置重试机制
|
||||
- 提供友好的错误提示
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [创建Agent经验总结](./创建Agent经验.md)
|
||||
- [工作流节点类型说明](./可新增节点类型建议.md)
|
||||
- [Agent使用说明](./Agent使用说明.md)
|
||||
|
||||
## 🎯 适用场景
|
||||
|
||||
- ✅ 情感陪聊助手
|
||||
- ✅ 客服机器人
|
||||
- ✅ 智能问答系统
|
||||
- ✅ 对话式AI应用
|
||||
- ✅ 个性化聊天助手
|
||||
|
||||
## 💡 最佳实践
|
||||
|
||||
1. **Prompt设计**
|
||||
- 明确角色定位
|
||||
- 明确输出格式
|
||||
- 提供示例和上下文
|
||||
|
||||
2. **工作流设计**
|
||||
- 保持流程清晰
|
||||
- 合理使用分支
|
||||
- 避免过度复杂
|
||||
|
||||
3. **记忆管理**
|
||||
- 定期清理过期记忆
|
||||
- 控制记忆大小
|
||||
- 保护用户隐私
|
||||
|
||||
4. **测试验证**
|
||||
- 覆盖各种场景
|
||||
- 测试边界情况
|
||||
- 验证回复质量
|
||||
|
||||
---
|
||||
|
||||
**创建时间**: 2024年
|
||||
**版本**: 1.0
|
||||
**作者**: AI Agent Platform
|
||||
Reference in New Issue
Block a user