122 lines
3.6 KiB
Markdown
122 lines
3.6 KiB
Markdown
|
|
# 工作流数据流转测试方案
|
|||
|
|
|
|||
|
|
## 问题描述
|
|||
|
|
工作流能执行完成,但LLM节点输出"答非所问",可能是数据在节点间传递时被错误处理。
|
|||
|
|
|
|||
|
|
## 测试步骤
|
|||
|
|
|
|||
|
|
### 方法1: 使用测试脚本(推荐)
|
|||
|
|
|
|||
|
|
1. **运行测试脚本**:
|
|||
|
|
```bash
|
|||
|
|
cd /home/renjianbo/aiagent
|
|||
|
|
python3 test_workflow_data_flow.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **观察输出**:
|
|||
|
|
- 查看每个节点的输入数据
|
|||
|
|
- 特别关注LLM节点的输入数据格式
|
|||
|
|
- 检查是否有嵌套的`{"input": {...}}`结构
|
|||
|
|
|
|||
|
|
### 方法2: 查看执行日志数据库
|
|||
|
|
|
|||
|
|
1. **查询最近的执行记录**:
|
|||
|
|
```sql
|
|||
|
|
SELECT id, input_data, output_data, status, execution_time
|
|||
|
|
FROM executions
|
|||
|
|
WHERE agent_id IS NOT NULL
|
|||
|
|
ORDER BY created_at DESC
|
|||
|
|
LIMIT 1;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **查询节点执行日志**:
|
|||
|
|
```sql
|
|||
|
|
SELECT node_id, node_type, level, message, data, timestamp
|
|||
|
|
FROM execution_logs
|
|||
|
|
WHERE execution_id = 'YOUR_EXECUTION_ID'
|
|||
|
|
ORDER BY timestamp ASC;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方法3: 添加临时调试代码
|
|||
|
|
|
|||
|
|
在 `backend/app/services/workflow_engine.py` 的 `get_node_input` 方法中添加:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 在方法开始处
|
|||
|
|
if node_id == 'llm-1': # 你的LLM节点ID
|
|||
|
|
import json
|
|||
|
|
print(f"[DEBUG] get_node_input for {node_id}")
|
|||
|
|
print(f"[DEBUG] node_outputs: {json.dumps(node_outputs, ensure_ascii=False, indent=2)}")
|
|||
|
|
print(f"[DEBUG] source_output: {json.dumps(node_outputs.get('start-1', {}), ensure_ascii=False, indent=2)}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
在 `execute_node` 方法的LLM节点处理部分添加:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 在格式化prompt之前
|
|||
|
|
if node_type == 'llm':
|
|||
|
|
import json
|
|||
|
|
print(f"[DEBUG] LLM节点输入: {json.dumps(input_data, ensure_ascii=False, indent=2)}")
|
|||
|
|
print(f"[DEBUG] 原始prompt: {prompt}")
|
|||
|
|
print(f"[DEBUG] user_query提取结果: {user_query}")
|
|||
|
|
print(f"[DEBUG] 最终formatted_prompt: {formatted_prompt}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
然后重启后端并测试:
|
|||
|
|
```bash
|
|||
|
|
docker-compose -f docker-compose.dev.yml restart backend
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方法4: 使用浏览器开发者工具
|
|||
|
|
|
|||
|
|
1. 打开浏览器开发者工具(F12)
|
|||
|
|
2. 切换到 Network 标签
|
|||
|
|
3. 执行一次测试
|
|||
|
|
4. 查看请求:
|
|||
|
|
- `POST /api/v1/executions` - 查看发送的 `input_data`
|
|||
|
|
5. 查看响应:
|
|||
|
|
- `GET /api/v1/executions/{id}/status` - 查看执行状态
|
|||
|
|
- `GET /api/v1/executions/{id}` - 查看执行结果
|
|||
|
|
|
|||
|
|
## 关键检查点
|
|||
|
|
|
|||
|
|
### 1. Start节点输出
|
|||
|
|
- **期望**: `{"query": "苹果英语怎么讲?", "USER_INPUT": "苹果英语怎么讲?"}`
|
|||
|
|
- **实际**: 检查是否被包装成 `{"input": {...}}` 或其他格式
|
|||
|
|
|
|||
|
|
### 2. LLM节点输入
|
|||
|
|
- **期望**: 直接从start节点获取,格式为 `{"query": "...", "USER_INPUT": "..."}`
|
|||
|
|
- **实际**: 检查 `get_node_input` 返回的数据格式
|
|||
|
|
|
|||
|
|
### 3. user_query提取
|
|||
|
|
- **期望**: 能正确提取到 "苹果英语怎么讲?"
|
|||
|
|
- **实际**: 检查提取逻辑是否正确处理嵌套结构
|
|||
|
|
|
|||
|
|
### 4. Prompt格式化
|
|||
|
|
- **期望**: 如果是通用指令"请处理用户请求。",应该直接使用user_query作为prompt
|
|||
|
|
- **实际**: 检查最终的formatted_prompt内容
|
|||
|
|
|
|||
|
|
## 预期问题位置
|
|||
|
|
|
|||
|
|
根据图片分析,输入数据可能是:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"input": {
|
|||
|
|
"query": "苹果英语怎么讲?",
|
|||
|
|
"USER_INPUT": "苹果英语怎么讲?"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这可能是以下原因导致的:
|
|||
|
|
1. `get_node_input` 方法在某个分支将数据包装成了 `{"input": ...}`
|
|||
|
|
2. `start` 节点的输出被错误保存
|
|||
|
|
3. 数据在节点间传递时被错误处理
|
|||
|
|
|
|||
|
|
## 修复建议
|
|||
|
|
|
|||
|
|
如果发现数据被包装成 `{"input": {...}}`,需要:
|
|||
|
|
1. 在 `get_node_input` 中正确处理嵌套的 `input` 字段
|
|||
|
|
2. 确保 `user_query` 提取逻辑能处理这种嵌套结构
|
|||
|
|
3. 确保prompt格式化逻辑能正确使用提取的 `user_query`
|