Files
aiagent/(红头)Agent搭建通用方法指南.md

752 lines
20 KiB
Markdown
Raw Permalink Normal View History

2026-03-06 22:31:41 +08:00
# Agent搭建通用方法指南
## 📖 概述
本文档提供了一套通用的Agent搭建方法适用于在平台上创建各种类型的智能Agent。无论是要创建聊天助手、数据分析Agent、工具调用Agent还是其他类型的智能体都可以参考本指南。
---
## 🎯 Agent搭建的核心原则
### 1. 明确Agent的目标和职责
-**单一职责原则**: 每个Agent应该专注于解决一个特定问题
-**清晰的功能边界**: 明确定义Agent能做什么、不能做什么
-**用户价值导向**: 确保Agent能够为用户提供实际价值
### 2. 设计合理的工作流
-**流程清晰**: 工作流应该逻辑清晰,易于理解和维护
-**节点职责明确**: 每个节点应该有明确的输入和输出
-**错误处理**: 考虑异常情况的处理流程
### 3. 充分利用平台能力
-**工具调用**: 合理使用内置工具和自定义工具
-**记忆管理**: 对于需要上下文记忆的场景,使用缓存节点
-**条件分支**: 使用Switch节点处理不同的业务逻辑
---
## 📋 Agent搭建标准流程
### 阶段1: 需求分析和设计
#### 1.1 明确需求
- **用户场景**: 谁将使用这个Agent在什么场景下使用
- **核心功能**: Agent需要完成什么任务
- **输入输出**: 用户输入什么Agent输出什么
- **性能要求**: 响应时间、准确性等要求
**示例**:
```
需求: 创建一个Android日志获取Agent
- 用户场景: 开发人员需要快速获取Android设备日志
- 核心功能: 通过ADB命令获取和分析日志
- 输入: 自然语言请求(如"获取错误日志"
- 输出: 格式化的日志内容和分析结果
- 性能要求: 响应时间<30秒支持100行日志
```
#### 1.2 设计工作流架构
- **节点规划**: 需要哪些类型的节点?
- **数据流**: 数据如何在节点间传递?
- **分支逻辑**: 是否需要条件分支?
- **工具需求**: 需要哪些工具支持?
**常见工作流模式**:
**模式1: 简单线性流程**
```
开始 → 处理 → 输出 → 结束
```
适用于: 简单的单步处理任务
**模式2: 意图识别+分支处理**
```
开始 → 意图识别 → Switch → [分支1/分支2/分支3] → 合并 → 结束
```
适用于: 需要根据用户意图执行不同操作
**模式3: 工具调用流程**
```
开始 → 参数提取 → 工具调用 → 结果分析 → 结束
```
适用于: 需要调用外部工具或API
**模式4: 记忆管理流程**
```
开始 → 查询记忆 → 合并上下文 → 处理 → 更新记忆 → 结束
```
适用于: 需要上下文记忆的多轮对话
**模式5: 复杂组合流程**
```
开始 → 意图识别 → Switch → [工具调用/记忆查询/数据处理] → 结果合并 → 格式化 → 结束
```
适用于: 复杂的多步骤任务
---
### 阶段2: 工具准备(如需要)
#### 2.1 评估工具需求
- **是否需要自定义工具?**
- 如果平台内置工具可以满足需求,直接使用
- 如果需要特殊功能,考虑创建自定义工具
#### 2.2 创建自定义工具(如需要)
**步骤1: 实现工具函数**
```python
# backend/app/services/builtin_tools.py
async def my_custom_tool(
param1: str,
param2: Optional[int] = None,
timeout: int = 10
) -> str:
"""
自定义工具函数
Args:
param1: 参数1说明
param2: 参数2说明可选
timeout: 超时时间(秒)
Returns:
JSON格式的执行结果
"""
try:
# 实现工具逻辑
result = {
"success": True,
"data": "...",
"timestamp": datetime.now().isoformat()
}
return json.dumps(result, ensure_ascii=False)
except Exception as e:
logger.error(f"工具执行失败: {str(e)}")
return json.dumps({"error": str(e)}, ensure_ascii=False)
```
**步骤2: 定义工具Schema**
```python
MY_CUSTOM_TOOL_SCHEMA = {
"type": "function",
"function": {
"name": "my_custom_tool",
"description": "工具功能描述",
"parameters": {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "参数1说明"
},
"param2": {
"type": "integer",
"description": "参数2说明可选"
},
"timeout": {
"type": "integer",
"description": "超时时间(秒)",
"default": 10
}
},
"required": ["param1"]
}
}
}
```
**步骤3: 注册工具**
```python
# backend/app/main.py
from app.services.builtin_tools import (
my_custom_tool,
MY_CUSTOM_TOOL_SCHEMA
)
tool_registry.register_builtin_tool("my_custom_tool", my_custom_tool, MY_CUSTOM_TOOL_SCHEMA)
```
**工具开发最佳实践**:
- ✅ 参数验证: 验证输入参数的合法性
- ✅ 超时控制: 设置合理的超时时间
- ✅ 错误处理: 完善的异常处理和错误信息
- ✅ 日志记录: 记录工具执行情况
- ✅ 安全考虑: 防止命令注入、SQL注入等安全问题
- ✅ 返回格式: 统一使用JSON格式返回
---
### 阶段3: 工作流节点设计
#### 3.1 开始节点
- **作用**: 接收用户输入
- **配置**: 通常不需要特殊配置
- **输出**: 用户输入数据
```json
{
"id": "start",
"type": "start",
"position": {"x": 100, "y": 200},
"data": {
"label": "开始"
}
}
```
#### 3.2 LLM节点意图识别/处理)
- **作用**: 理解用户意图、生成回复、调用工具
- **配置要点**:
- **Provider和Model**: 选择合适的LLM提供商和模型
- **Temperature**:
- 意图识别: 0.3(更确定)
- 生成回复: 0.7(更有创造性)
- **Max Tokens**: 根据输出长度需求设置
- **Prompt设计**: 清晰、具体、包含示例
**Prompt设计原则**:
-**明确任务**: 清楚说明需要做什么
-**提供上下文**: 包含必要的上下文信息
-**输出格式**: 明确指定输出格式JSON/文本)
-**示例引导**: 提供示例帮助理解
-**变量引用**: 使用 `{{变量名}}` 引用上游节点数据
**示例Prompt**:
```
你是一个专业的意图分析助手。请分析用户的输入,识别用户的意图。
用户输入:{{input.query}}
对话历史:{{memory.conversation_history}}
请以JSON格式输出分析结果
{
"intent": "意图类型",
"parameters": {
"key1": "value1",
"key2": "value2"
}
}
请确保输出是有效的JSON格式不要包含其他文字。
```
#### 3.3 JSON节点
- **作用**: 解析、提取、格式化JSON数据
- **常用操作**:
- `parse`: 解析JSON字符串
- `stringify`: 将对象转换为JSON字符串
- `extract`: 使用JSONPath提取数据
**示例配置**:
```json
{
"id": "json-parse",
"type": "json",
"position": {"x": 400, "y": 200},
"data": {
"label": "解析参数",
"operation": "parse",
"json_path": "$"
}
}
```
#### 3.4 缓存节点(记忆管理)
- **作用**: 存储和检索对话历史、用户信息等
- **操作类型**:
- `get`: 获取缓存数据
- `set`: 设置缓存数据
- `update`: 更新缓存数据
**示例配置**:
```json
{
"id": "cache-query",
"type": "cache",
"position": {"x": 300, "y": 200},
"data": {
"label": "查询记忆",
"operation": "get",
"key": "user_memory_{user_id}",
"default_value": "{\"conversation_history\": [], \"user_profile\": {}}"
}
}
```
#### 3.5 Transform节点数据转换
- **作用**: 合并、转换、映射数据
- **常用模式**:
- `merge`: 合并多个输入
- `map`: 数据映射
- `filter`: 数据过滤
**示例配置**:
```json
{
"id": "transform-merge",
"type": "transform",
"position": {"x": 500, "y": 200},
"data": {
"label": "合并上下文",
"mode": "merge",
"mapping": {
"user_input": "{{input.query}}",
"memory": "{{cache-query.output}}",
"timestamp": "{{timestamp}}"
}
}
}
```
#### 3.6 Switch节点条件分支
- **作用**: 根据条件路由到不同分支
- **配置要点**:
- 条件表达式要清晰
- 覆盖所有可能的情况
- 提供默认分支
**示例配置**:
```json
{
"id": "switch-intent",
"type": "switch",
"position": {"x": 600, "y": 200},
"data": {
"label": "意图分支",
"conditions": [
{
"condition": "{{intent-recognize.output.intent}} == 'question'",
"target": "llm-answer"
},
{
"condition": "{{intent-recognize.output.intent}} == 'request'",
"target": "tool-call"
},
{
"condition": "default",
"target": "llm-general"
}
]
}
}
```
#### 3.7 工具调用节点LLM + 工具)
- **作用**: 让LLM智能调用工具完成任务
- **配置要点**:
- 启用工具调用: `enable_tools: true`
- 选择工具: `selected_tools: ["tool1", "tool2"]`
- Prompt中说明如何使用工具
**示例配置**:
```json
{
"id": "llm-with-tools",
"type": "llm",
"position": {"x": 800, "y": 200},
"data": {
"label": "工具调用",
"provider": "deepseek",
"model": "deepseek-chat",
"temperature": 0.7,
"max_tokens": 2000,
"enable_tools": true,
"selected_tools": ["http_request", "file_read", "adb_log"],
"prompt": "根据用户需求,选择合适的工具执行任务。可以使用以下工具:\n- http_request: 发送HTTP请求\n- file_read: 读取文件\n- adb_log: 获取Android日志\n\n用户需求{{input.query}}\n\n请分析需求调用合适的工具然后分析结果并回复用户。"
}
}
```
#### 3.8 结束节点
- **作用**: 输出最终结果
- **配置**: 通常不需要特殊配置
```json
{
"id": "end",
"type": "end",
"position": {"x": 1000, "y": 200},
"data": {
"label": "结束"
}
}
```
---
### 阶段4: 节点连接和边配置
#### 4.1 边的配置
- **source**: 源节点ID
- **target**: 目标节点ID
- **sourceHandle**: 源节点输出端口(通常为"right"
- **targetHandle**: 目标节点输入端口(通常为"left"
**示例**:
```json
{
"id": "e1",
"source": "start",
"target": "intent-recognize",
"sourceHandle": "right",
"targetHandle": "left"
}
```
#### 4.2 数据传递规则
- **变量引用**: 使用 `{{节点ID.输出字段}}` 引用上游节点数据
- **特殊变量**:
- `{{input}}`: 开始节点的输入
- `{{timestamp}}`: 当前时间戳
- `{{user_id}}`: 用户ID如果可用
**示例**:
```
用户输入:{{input.query}}
记忆数据:{{cache-query.output.memory}}
意图分析:{{intent-recognize.output.intent}}
```
---
### 阶段5: Agent创建脚本
#### 5.1 脚本结构
```python
#!/usr/bin/env python3
"""
生成[Agent名称]Agent
"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app.core.database import SessionLocal
from app.models.agent import Agent
from app.models.workflow import Workflow
import uuid
from datetime import datetime
def generate_my_agent():
"""生成[Agent名称]Agent"""
db = SessionLocal()
try:
# 1. 检查是否已存在
existing = db.query(Agent).filter(Agent.name == "Agent名称").first()
if existing:
print(f"Agent 'Agent名称' 已存在ID: {existing.id}")
return existing.id
# 2. 定义节点
nodes = [
# 开始节点
{
"id": "start",
"type": "start",
"position": {"x": 100, "y": 200},
"data": {"label": "开始"}
},
# ... 其他节点
# 结束节点
{
"id": "end",
"type": "end",
"position": {"x": 1000, "y": 200},
"data": {"label": "结束"}
}
]
# 3. 定义边
edges = [
{
"id": "e1",
"source": "start",
"target": "node1",
"sourceHandle": "right",
"targetHandle": "left"
},
# ... 其他边
]
# 4. 创建工作流
workflow_id = str(uuid.uuid4())
workflow = Workflow(
id=workflow_id,
name="工作流名称",
description="工作流描述",
nodes=nodes,
edges=edges,
created_at=datetime.now(),
updated_at=datetime.now()
)
db.add(workflow)
db.commit()
db.refresh(workflow)
# 5. 创建Agent
agent_id = str(uuid.uuid4())
agent = Agent(
id=agent_id,
name="Agent名称",
description="Agent描述",
workflow_config={
"workflow_id": workflow_id,
"nodes": nodes,
"edges": edges
},
created_at=datetime.now(),
updated_at=datetime.now()
)
db.add(agent)
db.commit()
db.refresh(agent)
print(f"✅ Agent创建成功")
print(f" Agent ID: {agent_id}")
print(f" Agent名称: {agent.name}")
print(f" 工作流ID: {workflow_id}")
return agent_id
except Exception as e:
db.rollback()
print(f"❌ 创建Agent失败: {e}")
import traceback
traceback.print_exc()
return None
finally:
db.close()
if __name__ == "__main__":
generate_my_agent()
```
#### 5.2 脚本最佳实践
-**幂等性**: 检查Agent是否已存在避免重复创建
-**错误处理**: 完善的异常处理和回滚机制
-**日志输出**: 清晰的日志信息
-**代码注释**: 详细的注释说明
---
### 阶段6: 测试和优化
#### 6.1 单元测试
- **测试各个节点**: 确保每个节点正常工作
- **测试数据流**: 验证数据在节点间正确传递
- **测试边界情况**: 测试异常输入、空值等
#### 6.2 集成测试
```bash
# 使用测试工具
python3 test_workflow_tool.py -a "Agent名称" -i '{"query": "测试输入"}'
```
#### 6.3 性能优化
- **减少LLM调用**: 合理使用缓存,避免重复调用
- **优化Prompt**: 精简Prompt提高响应速度
- **并行处理**: 对于独立的任务,考虑并行处理
- **超时控制**: 设置合理的超时时间
#### 6.4 用户体验优化
- **响应时间**: 确保响应时间在可接受范围内
- **错误提示**: 提供友好的错误信息
- **结果格式**: 确保输出格式清晰易读
---
## 🎨 常见Agent模式模板
### 模板1: 简单问答Agent
```
开始 → LLM处理 → 结束
```
**适用场景**: 简单的问答、文本生成
### 模板2: 工具调用Agent
```
开始 → 意图识别 → JSON解析 → LLM工具调用 → 结果分析 → 结束
```
**适用场景**: 需要调用外部工具或API
### 模板3: 多轮对话Agent
```
开始 → 查询记忆 → 合并上下文 → LLM处理 → 更新记忆 → 结束
```
**适用场景**: 需要上下文记忆的对话
### 模板4: 条件分支Agent
```
开始 → 意图识别 → Switch → [分支1/分支2/分支3] → 合并 → 结束
```
**适用场景**: 需要根据条件执行不同操作
### 模板5: 复杂组合Agent
```
开始 → 意图识别 → Switch →
[工具调用分支] → 结果分析 →
[记忆查询分支] → 上下文合并 →
[数据处理分支] → 格式化 →
合并 → 结束
```
**适用场景**: 复杂的多步骤任务
---
## ⚠️ 常见问题和解决方案
### 问题1: 节点数据传递失败
**症状**: 下游节点无法获取上游节点数据
**原因**: 变量引用错误、节点ID不匹配
**解决**:
- 检查变量引用格式: `{{节点ID.字段}}`
- 确认节点ID正确
- 检查节点输出格式
### 问题2: LLM输出格式不正确
**症状**: LLM返回的JSON格式错误
**原因**: Prompt不够明确、没有示例
**解决**:
- 在Prompt中明确要求JSON格式
- 提供JSON示例
- 使用JSON节点验证和修复
### 问题3: 工具调用失败
**症状**: 工具执行失败或返回错误
**原因**: 参数错误、工具未注册、权限问题
**解决**:
- 检查工具参数是否正确
- 确认工具已注册
- 检查工具执行日志
### 问题4: 工作流执行超时
**症状**: 工作流执行时间过长
**原因**: LLM调用过多、工具执行慢、没有超时控制
**解决**:
- 优化工作流,减少不必要的节点
- 设置合理的超时时间
- 使用缓存避免重复计算
### 问题5: 记忆管理问题
**症状**: 对话历史丢失、记忆不准确
**原因**: 缓存key不正确、更新逻辑错误
**解决**:
- 使用唯一的缓存key
- 正确更新缓存数据
- 检查缓存节点的配置
---
## 📊 质量检查清单
### 功能完整性
- [ ] Agent能够完成预期任务
- [ ] 所有功能分支都经过测试
- [ ] 错误情况得到妥善处理
- [ ] 输出格式符合要求
### 性能指标
- [ ] 响应时间在可接受范围内
- [ ] 资源使用合理
- [ ] 没有内存泄漏
- [ ] 超时控制有效
### 代码质量
- [ ] 代码结构清晰
- [ ] 注释充分
- [ ] 错误处理完善
- [ ] 符合编码规范
### 用户体验
- [ ] 交互流程顺畅
- [ ] 错误提示友好
- [ ] 输出结果清晰
- [ ] 响应及时
### 安全性
- [ ] 输入验证充分
- [ ] 没有安全漏洞
- [ ] 权限控制合理
- [ ] 敏感信息保护
---
## 🚀 进阶技巧
### 1. Prompt工程
- **Few-shot Learning**: 在Prompt中提供示例
- **Chain of Thought**: 引导LLM逐步思考
- **角色设定**: 为LLM设定明确的角色
- **输出约束**: 明确指定输出格式和约束
### 2. 工作流优化
- **节点复用**: 将通用逻辑提取为可复用节点
- **并行处理**: 对于独立任务,考虑并行执行
- **缓存策略**: 合理使用缓存减少重复计算
- **错误恢复**: 设计错误恢复机制
### 3. 工具设计
- **工具组合**: 将复杂工具拆分为简单工具
- **工具链**: 设计工具调用链完成复杂任务
- **工具验证**: 在工具中验证输入参数
- **工具文档**: 为工具提供清晰的文档
### 4. 监控和调试
- **执行日志**: 记录详细的执行日志
- **性能监控**: 监控Agent执行性能
- **错误追踪**: 追踪和记录错误信息
- **用户反馈**: 收集用户反馈持续改进
---
## 📚 参考资源
### 内置工具列表
- `http_request`: HTTP请求工具
- `file_read`: 文件读取工具
- `file_write`: 文件写入工具
- `text_analyze`: 文本分析工具
- `datetime`: 日期时间工具
- `math_calculate`: 数学计算工具
- `system_info`: 系统信息工具
- `json_process`: JSON处理工具
- `database_query`: 数据库查询工具
- `adb_log`: ADB日志工具
### 示例Agent
- **智能聊天助手**: `backend/scripts/generate_chat_agent.py`
- **知识库问答助手**: `backend/scripts/generate_knowledge_base_qa_agent.py`
- **Android日志获取助手**: `backend/scripts/generate_android_log_agent.py`
### 相关文档
- 工具调用实现方案
- 节点配置页面增强方案
- ADB工具和Android日志Agent搭建总结
---
## 🎯 总结
搭建一个成功的Agent需要
1. **明确需求**: 清楚定义Agent的目标和功能
2. **合理设计**: 设计清晰的工作流架构
3. **工具准备**: 准备必要的工具支持
4. **节点配置**: 正确配置各个节点
5. **测试优化**: 充分测试和持续优化
6. **文档完善**: 提供清晰的使用文档
遵循本指南的方法和最佳实践可以高效地创建各种类型的Agent满足不同的业务需求。
---
**最后更新**: 2026-01-23
**文档版本**: v1.0
**状态**: 持续更新中 📝