20 KiB
20 KiB
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: 实现工具函数
# 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
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: 注册工具
# 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 开始节点
- 作用: 接收用户输入
- 配置: 通常不需要特殊配置
- 输出: 用户输入数据
{
"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提取数据
示例配置:
{
"id": "json-parse",
"type": "json",
"position": {"x": 400, "y": 200},
"data": {
"label": "解析参数",
"operation": "parse",
"json_path": "$"
}
}
3.4 缓存节点(记忆管理)
- 作用: 存储和检索对话历史、用户信息等
- 操作类型:
get: 获取缓存数据set: 设置缓存数据update: 更新缓存数据
示例配置:
{
"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: 数据过滤
示例配置:
{
"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节点(条件分支)
- 作用: 根据条件路由到不同分支
- 配置要点:
- 条件表达式要清晰
- 覆盖所有可能的情况
- 提供默认分支
示例配置:
{
"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中说明如何使用工具
- 启用工具调用:
示例配置:
{
"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 结束节点
- 作用: 输出最终结果
- 配置: 通常不需要特殊配置
{
"id": "end",
"type": "end",
"position": {"x": 1000, "y": 200},
"data": {
"label": "结束"
}
}
阶段4: 节点连接和边配置
4.1 边的配置
- source: 源节点ID
- target: 目标节点ID
- sourceHandle: 源节点输出端口(通常为"right")
- targetHandle: 目标节点输入端口(通常为"left")
示例:
{
"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 脚本结构
#!/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 集成测试
# 使用测试工具
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需要:
- 明确需求: 清楚定义Agent的目标和功能
- 合理设计: 设计清晰的工作流架构
- 工具准备: 准备必要的工具支持
- 节点配置: 正确配置各个节点
- 测试优化: 充分测试和持续优化
- 文档完善: 提供清晰的使用文档
遵循本指南的方法和最佳实践,可以高效地创建各种类型的Agent,满足不同的业务需求。
最后更新: 2026-01-23
文档版本: v1.0
状态: 持续更新中 📝