第六章习题解答:智能体框架深度实践
本文是《Hello Agents》第六章的配套习题解答,涵盖AutoGen、AgentScope、CAMEL、LangGraph四大框架的深入分析与实践思考。
习题1:框架对比与设计哲学
1.1 框架深度对比:AutoGen vs LangGraph
选择AutoGen和LangGraph两个框架,从"协作模式"、"控制方式"、"适用场景"三个维度进行深入对比:
| 维度 | AutoGen | LangGraph |
|---|---|---|
| 协作模式 | 对话驱动的协作,智能体通过自然语言在"群聊"中交互,任务解决过程是对话的自然演进 | 图驱动的协作,智能体行为被建模为状态图中的节点,任务执行遵循预定义的路径 |
| 控制方式 | 涌现式控制,依赖系统消息和角色定义来引导行为,执行路径有一定不确定性 | 显式控制,通过节点和边精确定义每一步,执行路径完全可预测、可审计 |
| 适用场景 | 开放式协作任务,如创意写作、软件开发团队模拟、需要角色扮演的场景 | 确定性流程任务,如金融风控审批、数据ETL流水线、需要严格合规的应用 |
设计哲学深入理解:
涌现式协作的核心思想是:通过设定简单的交互规则和角色定义,让复杂的智能体行为从这些简单规则中"自然涌现"。这类似于人类社会------我们不需要为每个人的每一步行为编程,只需要设定角色、目标和基本的交互规范,复杂的社会协作就能自发形成。这种方式的优势在于灵活性和适应性,但代价是可预测性较低。
显式控制则相反:开发者需要为智能体的每一步行为明确定义逻辑,整个工作流是一张精确的"地图"。这种方式的优势在于完全可控、易于调试和审计,但灵活性较差,难以应对未预见的场景。
两种哲学没有绝对优劣,关键在于应用场景的需求。AutoGen适合需要创造性和灵活性的任务,LangGraph适合需要可靠性和可审计性的任务。
习题2:AutoGen扩展实践
2.1 设计支持"动态回退"的协作机制
当前RoundRobinGroupChat采用固定顺序发言。若要支持"工程师代码需要返回产品经理重新审核"的动态回退,可以设计以下机制:
python
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
# 方案一:在系统消息中嵌入流程控制指令
def create_engineer_with_feedback(model_client):
system_message = """你是一位资深的软件工程师。
... [原有职责描述] ...
**流程控制规则**:
- 如果你认为需求存在歧义或需要产品经理澄清,请在回复开头说"REQUIREMENT_CLARIFICATION: "
- 如果代码需要产品经理确认业务逻辑,请在回复开头说"NEED_PM_REVIEW: "
- 正常情况下完成后说"请代码审查员检查"
"""
return AssistantAgent(
name="Engineer",
model_client=model_client,
system_message=system_message,
)
# 方案二:自定义Team类,支持动态路由
from autogen_agentchat.teams import BaseTeam
from typing import List, Optional
class DynamicReviewTeam(BaseTeam):
"""支持动态回退的团队"""
def __init__(self, participants: List, max_turns: int = 20):
self.participants = participants
self.max_turns = max_turns
self.current_index = 0
async def run_stream(self, task: str):
current_speaker = self.participants[0] # 产品经理开始
for turn in range(self.max_turns):
# 获取当前发言者的回复
response = await current_speaker.generate_response()
# 检测流程控制标记
if "REQUIREMENT_CLARIFICATION:" in response.content:
# 跳回产品经理
current_speaker = self.participants[0] # 产品经理
elif "NEED_PM_REVIEW:" in response.content:
# 需要产品经理审核
current_speaker = self.participants[0] # 产品经理
elif "PASS_TO_REVIEWER" in response.content:
# 正常流转到代码审查员
current_speaker = self.participants[2] # 代码审查员
else:
# 按顺序推进
self.current_index = (self.current_index + 1) % len(self.participants)
current_speaker = self.participants[self.current_index]
# 输出当前回复
yield response
# 检查终止条件
if "TERMINATE" in response.content:
break
2.2 添加"测试工程师"角色
为软件开发团队添加QA角色,其系统消息设计如下:
python
def create_quality_assurance(model_client):
"""创建测试工程师智能体"""
system_message = """你是一位经验丰富的测试工程师(QA),专注于软件质量保证和自动化测试。
**核心职责**:
1. **测试用例设计**:根据需求文档和代码实现,设计全面的测试用例
2. **自动化测试**:编写和执行自动化测试脚本
3. **缺陷报告**:发现并详细记录潜在问题
4. **回归测试**:确保修改不影响已有功能
**测试覆盖重点**:
- 功能正确性:核心功能是否符合需求
- 边界条件:异常输入、极端值的处理
- 错误处理:错误提示的友好性和准确性
- 用户体验:界面交互、响应时间
**工作流程**:
1. 接收工程师的代码和产品经理的需求
2. 分析测试要点,设计测试用例
3. 编写自动化测试代码(使用pytest/unittest框架)
4. 执行测试并记录结果
5. 如果发现问题,说"QA_ISSUE: [问题描述]",否则说"QA_PASSED,请用户代理测试"
请提供完整的测试报告,包括测试用例、执行结果和改进建议。"""
return AssistantAgent(
name="QualityAssurance",
model_client=model_client,
system_message=system_message,
)
# 更新团队参与者列表
team_chat = RoundRobinGroupChat(
participants=[
product_manager,
engineer,
code_reviewer,
quality_assurance, # 新增的QA
user_proxy
],
termination_condition=TextMentionTermination("TERMINATE"),
max_turns=25,
)
2.3 "对话质量监控"机制设计
python
import re
from typing import List, Dict
from collections import deque
class ConversationMonitor:
"""对话质量监控器"""
def __init__(self, max_history: int = 10, similarity_threshold: float = 0.85):
self.history = deque(maxlen=max_history)
self.similarity_threshold = similarity_threshold
self.consecutive_similar_count = 0
def compute_similarity(self, text1: str, text2: str) -> float:
"""计算两段文本的相似度(简化版)"""
# 实际实现可使用TF-IDF、Sentence-BERT等
set1, set2 = set(text1.split()), set(text2.split())
if not set1 or not set2:
return 0.0
intersection = set1 & set2
return len(intersection) / max(len(set1), len(set2))
def check_quality(self, message: str) -> Dict:
"""检查消息质量,返回检测结果"""
alerts = []
# 1. 检测重复内容(可能陷入循环)
for hist_msg in self.history:
sim = self.compute_similarity(message, hist_msg)
if sim > self.similarity_threshold:
alerts.append(f"高相似度检测: {sim:.2%}")
self.consecutive_similar_count += 1
else:
self.consecutive_similar_count = 0
# 2. 检测偏离主题(检查关键词)
if "TERMINATE" not in message and len(message) < 20:
alerts.append("消息过短,可能缺乏实质内容")
# 3. 检测无意义的重复短语
repetitive_patterns = [
(r'(\w+)\s+\1\s+\1', "单词重复出现"),
(r'\.\s*\.\s*\.', "过多省略号"),
]
for pattern, description in repetitive_patterns:
if re.search(pattern, message):
alerts.append(description)
self.history.append(message)
return {
"quality_score": max(0, 1 - len(alerts) * 0.2),
"alerts": alerts,
"need_intervention": self.consecutive_similar_count >= 3 or len(alerts) >= 3
}
def get_intervention_message(self) -> str:
"""生成干预提示"""
return """⚠️ 系统检测到对话可能存在问题:
- 内容重复度过高,可能陷入循环
- 建议:请明确当前任务状态,或需要人类介入
- 如需终止,请回复 "TERMINATE" """
# 集成到AutoGen团队
class MonitoredTeam(RoundRobinGroupChat):
def __init__(self, participants, **kwargs):
super().__init__(participants, **kwargs)
self.monitor = ConversationMonitor()
async def run_stream(self, task: str):
async for response in super().run_stream(task):
# 监控每条消息
check_result = self.monitor.check_quality(response.content)
if check_result["need_intervention"]:
# 发送干预消息
yield self.monitor.get_intervention_message()
yield response
习题3:AgentScope深度分析
3.1 消息驱动架构 vs 传统函数调用
消息驱动架构的核心优势:
| 对比维度 | 传统函数调用 | 消息驱动架构 |
|---|---|---|
| 耦合度 | 调用方必须知道被调用方的具体接口,强耦合 | 发送方只需知道消息格式,与接收方解耦 |
| 并发性 | 同步调用会阻塞等待,难以扩展 | 异步消息天然支持高并发 |
| 容错性 | 调用失败可能导致整个链路中断 | 消息可持久化、可重试 |
| 可观测性 | 难以追踪跨模块调用链路 | 每条消息都有完整生命周期记录 |
| 分布式 | 需要额外RPC框架实现 | 消息中心原生支持跨节点通信 |
特别有价值的场景:
- 高并发场景:如智能客服系统,同时处理成千上万的用户请求
- 长时运行任务:如数据分析流水线,需要容错和状态恢复
- 复杂多智能体系统:如狼人杀游戏,需要灵活的路由和动态组网
- 分布式部署场景:智能体分布在不同服务器上,需要透明通信
3.2 设计"猎人"角色及其结构化输出
python
from pydantic import BaseModel, Field
from typing import Optional, Literal
class HunterActionModelCN(BaseModel):
"""猎人角色的行动输出格式"""
# 猎人特有技能:被投票出局时可开枪带走一人
use_skill: bool = Field(
description="是否使用猎人技能(被投票出局时可带走一名玩家)",
default=False
)
target_name: Optional[str] = Field(
description="技能目标玩家姓名,仅在use_skill=True时需要",
default=None
)
# 猎人身份自证
reveal_identity: bool = Field(
description="是否主动暴露猎人身份(通常用于威慑)",
default=False
)
# 推理与决策
reasoning: str = Field(
description="你的推理过程和决策依据",
max_length=200
)
# 投票决策
vote_target: str = Field(
description="白天投票阶段的目标玩家姓名"
)
# 对当前局势的判断
suspicious_players: list[str] = Field(
description="你认为可疑的玩家列表,按可疑程度排序",
default_factory=list
)
class HunterGameRules:
"""猎人角色的游戏规则约束"""
@staticmethod
def validate_hunter_action(action: HunterActionModelCN, is_eliminated: bool) -> bool:
"""验证猎人行为的合法性"""
# 规则1:只有被投票淘汰时才能开枪
if action.use_skill and not is_eliminated:
return False
# 规则2:开枪必须指定目标
if action.use_skill and not action.target_name:
return False
# 规则3:不能枪杀自己
if action.use_skill and action.target_name == "自己":
return False
# 规则4:枪杀目标必须在存活玩家中(由游戏主控验证)
return True
@staticmethod
def get_role_prompt(character: str) -> str:
"""获取猎人角色的系统提示"""
return f"""你是{character},在这场三国狼人杀游戏中扮演猎人。
**猎人技能说明**:
- 当你被投票淘汰时,可以开枪带走一名玩家(被视为立即生效的击杀)
- 如果被狼人击杀或女巫毒杀,不能开枪
- 开枪是强力的威慑手段,但也可能误伤好人
**你的角色特点**:
- 作为{character},你需要展现相应的性格特点
- 猎人通常观察力强、行动果断
- 请在对话中体现你的性格
**输出格式**:严格按照JSON格式回复
"""
3.3 分布式部署的挑战与解决方案
技术挑战:
| 挑战 | 描述 | 解决方案 |
|---|---|---|
| 消息顺序性 | 分布式环境下消息可能乱序到达 | 使用Lamport时间戳或向量时钟;在MsgHub层面实现FIFO队列 |
| 一致性 | 游戏状态在不同节点间可能不一致 | 引入分布式共识算法(如Raft);使用中心化状态存储(Redis/etcd) |
| 网络延迟 | 跨节点通信延迟影响实时性 | 智能体就近部署;使用UDP替代TCP;实现预测性预加载 |
| 故障恢复 | 单节点宕机导致游戏中断 | 消息持久化;智能体无状态设计;检查点与恢复机制 |
| 时钟同步 | 分布式环境下的时间戳不一致 | 使用NTP同步;采用逻辑时钟代替物理时钟 |
消息顺序性保证的设计:
python
# 伪代码:带序列号的消息
class OrderedMessage:
def __init__(self, content: str, sender: str):
self.content = content
self.sender = sender
self.sequence_number = self._get_next_seq(sender)
self.timestamp = time.time()
@staticmethod
def _get_next_seq(sender: str) -> int:
"""为每个发送者维护递增序列号"""
# 使用Redis INCR保证分布式环境下序列号唯一递增
return redis.incr(f"seq:{sender}")
# MsgHub层面的顺序保证
class OrderedMsgHub:
def __init__(self):
self.expected_seq = {} # 每个发送者期望的下一个序列号
async def receive(self, message: OrderedMessage):
sender = message.sender
expected = self.expected_seq.get(sender, 1)
if message.sequence_number == expected:
# 顺序正确,处理消息
await self.process(message)
self.expected_seq[sender] = expected + 1
else:
# 乱序,放入等待队列
self.pending_queue.append(message)
# 延迟处理或请求重传
习题4:CAMEL扩展思考
4.1 冲突解决机制设计
当两个智能体对任务完成状态意见不一致时,需要设计兼容的冲突解决机制:
python
from enum import Enum
from typing import List, Optional
class TaskStatus(Enum):
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
NEEDS_REVIEW = "needs_review"
DISAGREEMENT = "disagreement"
class ConflictResolver:
"""冲突解决器"""
def __init__(self, max_resolution_rounds: int = 3):
self.max_rounds = max_resolution_rounds
self.resolution_history = []
def detect_disagreement(self, user_msg: str, assistant_msg: str) -> bool:
"""检测是否存在完成状态的争议"""
task_done_indicators = ["<CAMEL_TASK_DONE>", "任务完成", "已完成"]
user_claims_done = any(ind in user_msg for ind in task_done_indicators)
assistant_claims_done = any(ind in assistant_msg for ind in task_done_indicators)
return user_claims_done != assistant_claims_done
def generate_resolution_prompt(self, user_msg: str, assistant_msg: str) -> str:
"""生成冲突解决提示"""
return f"""检测到任务完成状态争议:
AI用户(作家)认为:{user_msg}
AI助理(心理学家)认为:{assistant_msg}
请双方协商确认:
1. 任务是否真的完成?
2. 如果未完成,哪些部分还需要补充?
3. 如果已完成,请确认并输出 <CAMEL_TASK_DONE>
请提供你的判断和理由。"""
async def resolve(self, role_play_session, user_msg: str, assistant_msg: str) -> TaskStatus:
"""执行冲突解决"""
for round_num in range(self.max_rounds):
resolution_prompt = self.generate_resolution_prompt(user_msg, assistant_msg)
# 让一方(如用户方)作为仲裁者
response = await role_play_session.user_agent.generate_response(resolution_prompt)
if "<CAMEL_TASK_DONE>" in response:
return TaskStatus.COMPLETED
elif "继续" in response or "补充" in response:
return TaskStatus.NEEDS_REVIEW
elif "无法达成一致" in response:
if round_num == self.max_rounds - 1:
# 达到最大轮次,触发人工介入
return TaskStatus.DISAGREEMENT
else:
# 更新状态继续
user_msg = response
return TaskStatus.DISAGREEMENT
4.2 CAMEL Workforce vs AutoGen群聊模式
根据CAMEL官方文档,workforce模块的设计理念与AutoGen群聊模式有本质区别:
| 维度 | CAMEL Workforce | AutoGen GroupChat |
|---|---|---|
| 组织架构 | 层级化结构:有明确的"管理者"智能体协调各成员 | 扁平化结构:所有智能体平等参与对话 |
| 任务分配 | 管理者根据成员能力动态分配子任务 | 通过发言顺序或对话自然流转 |
| 协作模式 | 自上而下的任务分解与执行 | 自下而上的涌现式协作 |
| 通信模式 | 主要通过与管理者交互,成员间间接通信 | 成员间可直接对话,形成群聊 |
| 适用场景 | 复杂任务分解、需要明确职责分工的场景 | 创意协作、角色扮演等开放式场景 |
架构图理解:
- Workforce:类似公司组织架构,有一个"项目经理"智能体负责任务分解和分配,各"员工"智能体专注于自己的子任务,通过经理进行协调。
- AutoGen GroupChat:类似圆桌会议,所有参与者平等对话,通过自然语言协商推进任务。
习题5:LangGraph实践扩展
5.1 三步问答助手的图结构
┌─────────────────────────────────────────────────────────────────┐
│ LangGraph 工作流 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ START │────▶│ understand │────▶│ search │ │
│ │ (入口) │ │ (理解节点) │ │ (搜索节点) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ END │◀────│ answer │◀────│ (条件边) │ │
│ │ (出口) │ │ (回答节点) │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
状态转换条件:
- understand → search: 总是执行(常规边)
- search → answer: 总是执行(常规边)
- answer → END: 总是执行(常规边)
5.2 添加"反思"节点的循环机制
python
from langgraph.graph import StateGraph, START, END
from typing import Literal
class EnhancedState(SearchState):
iteration: int
quality_score: float
revision_attempts: int
# 新增反思节点
def reflect_on_answer_node(state: EnhancedState) -> dict:
"""评估答案质量,决定是否需要迭代"""
answer = state["final_answer"]
# 质量评估标准
criteria = {
"length": len(answer) >= 200, # 至少200字符
"specificity": any(kw in answer.lower() for kw in ["具体", "例如", "比如"]),
"completeness": "?" not in answer[-50:], # 不以问号结尾
}
quality_score = sum(criteria.values()) / len(criteria)
# 生成反思
if quality_score < 0.7 and state["revision_attempts"] < 3:
reflection = f"当前答案质量评分{quality_score:.1%},需要改进:"
if not criteria["length"]:
reflection += "答案不够详细;"
if not criteria["specificity"]:
reflection += "缺少具体例子;"
if not criteria["completeness"]:
reflection += "结尾不完整;"
should_continue = "revise"
else:
reflection = "答案质量合格,任务完成。"
should_continue = "end"
return {
"quality_score": quality_score,
"iteration": state.get("iteration", 0) + 1,
"revision_attempts": state.get("revision_attempts", 0) + (1 if should_continue == "revise" else 0),
"messages": state["messages"] + [reflection],
"step": "reflected"
}
# 修改后的搜索节点(支持优化查询)
def optimized_search_node(state: EnhancedState) -> dict:
"""优化后的搜索节点,支持查询优化"""
if state.get("iteration", 0) > 0:
# 迭代时优化搜索词
original_query = state["search_query"]
optimization_prompt = f"之前的搜索结果不够理想,请优化搜索词:{original_query}"
new_query = llm.invoke(optimization_prompt).content
state["search_query"] = new_query
return tavily_search_node(state)
# 构建带反思循环的图
def create_reflective_assistant():
workflow = StateGraph(EnhancedState)
# 添加节点
workflow.add_node("understand", understand_query_node)
workflow.add_node("search", optimized_search_node)
workflow.add_node("answer", generate_answer_node)
workflow.add_node("reflect", reflect_on_answer_node)
# 设置流程
workflow.add_edge(START, "understand")
workflow.add_edge("understand", "search")
workflow.add_edge("search", "answer")
workflow.add_edge("answer", "reflect")
# 条件边:根据反思结果决定下一步
def route_after_reflect(state: EnhancedState) -> Literal["search", "end"]:
if state.get("revision_attempts", 0) >= 3:
return "end" # 超过最大尝试次数
if state.get("quality_score", 0) >= 0.7:
return "end" # 质量合格
return "search" # 重新搜索
workflow.add_conditional_edges("reflect", route_after_reflect, {
"search": "search",
"end": END
})
return workflow.compile()
5.3 "代码生成-测试-修复"循环设计
python
from typing import TypedDict, List
class CodeGenState(TypedDict):
requirement: str
code: str
test_results: List[str]
test_passed: bool
error_feedback: str
iteration: int
final_code: str
# 节点定义
def code_generator_node(state: CodeGenState) -> dict:
"""根据需求生成代码"""
prompt = f"""根据以下需求编写Python代码:
{state['requirement']}
{state.get('error_feedback', '')}
请提供完整可运行的代码。"""
code = llm.invoke(prompt).content
return {"code": code, "iteration": state.get("iteration", 0) + 1}
def test_runner_node(state: CodeGenState) -> dict:
"""执行测试"""
import subprocess
import tempfile
# 写入临时文件并执行测试
with tempfile.NamedTemporaryFile(mode='w', suffix='.py') as f:
f.write(state['code'])
f.flush()
result = subprocess.run(['python', f.name], capture_output=True, text=True)
test_passed = result.returncode == 0
return {
"test_results": [result.stdout, result.stderr],
"test_passed": test_passed,
"error_feedback": result.stderr if not test_passed else ""
}
def code_fixer_node(state: CodeGenState) -> dict:
"""根据错误反馈修复代码"""
prompt = f"""修复以下代码中的错误:
原始代码:
{state['code']}
错误信息:
{state['error_feedback']}
请提供修复后的完整代码。"""
fixed_code = llm.invoke(prompt).content
return {"code": fixed_code}
# 构建循环图
def create_code_generation_workflow():
workflow = StateGraph(CodeGenState)
workflow.add_node("generate", code_generator_node)
workflow.add_node("test", test_runner_node)
workflow.add_node("fix", code_fixer_node)
workflow.add_edge(START, "generate")
workflow.add_edge("generate", "test")
# 条件路由
def route_after_test(state: CodeGenState) -> Literal["fix", "end"]:
if state["test_passed"]:
state["final_code"] = state["code"]
return "end"
if state.get("iteration", 0) >= 5:
state["final_code"] = state["code"]
return "end"
return "fix"
workflow.add_conditional_edges("test", route_after_test, {
"fix": "fix",
"end": END
})
workflow.add_edge("fix", "test") # 修复后重新测试
return workflow.compile()
图结构示意:
┌─────────────────────────────────────┐
│ │
▼ │
┌───────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐│
│ START │───▶│ generate │───▶│ test │───▶│ END ││
└───────┘ └──────────┘ └──────────┘ └──────────┘│
│ │
│ (test_passed=False) │
▼ │
┌──────────┐ │
│ fix │───────────────┘
└──────────┘ (回到test)
习题6:框架选型实战
作为技术架构师,为以下三个产品选择最合适的框架:
应用A:智能客服系统
选型建议 :AgentScope
理由:
- 高并发处理:AgentScope的消息驱动架构和异步设计天然支持高并发(1000+ QPS)
- 企业级可靠性:内置容错恢复、消息持久化、分布式部署支持,满足7×24小时稳定运行需求
- 水平扩展:分布式架构允许智能体部署在不同节点,轻松实现水平扩展
- 可观测性:内置监控和日志能力,便于运维和故障排查
应用B:科研论文辅助写作平台
选型建议 :CAMEL
理由:
- 深度协作需求:CAMEL的角色扮演模式最适合研究员+作家这类需要深度讨论的场景
- 自主推进:通过引导性提示(Inception Prompting),智能体可自主进行多轮迭代讨论
- 轻量级架构:不涉及复杂的并发和分布式需求,CAMEL简洁的设计降低了开发和维护成本
- 创造性任务:论文写作属于开放式创造性任务,CAMEL的涌现式协作比硬编码流程更灵活
应用C:金融风控审批系统
选型建议 :LangGraph
理由:
- 严格流程控制:金融审批有明确的合规要求,LangGraph的图结构可精确建模每个步骤
- 可追溯性:每个节点的输入输出可记录,满足审计需求
- 条件分支:支持复杂的决策逻辑(如不同额度走不同审批路径)
- 人机协作:可在关键节点(如人工复核)插入等待,天然支持Human-in-the-loop
- 确定性:LangGraph的显式控制确保每次执行路径可预测,这对金融应用至关重要
总结
本章通过对四大智能体框架的深入实践与对比分析,揭示了不同框架的设计哲学和适用场景:
| 框架 | 核心哲学 | 最佳实践场景 |
|---|---|---|
| AutoGen | 对话驱动协作 | 角色扮演、创意协作、团队模拟 |
| AgentScope | 工程化优先 | 高并发、分布式、生产级应用 |
| CAMEL | 角色扮演 | 双智能体深度协作、创造性任务 |
| LangGraph | 显式控制 | 确定性流程、合规审计、人机协作 |
理解这些框架的设计权衡,能够帮助开发者在实际项目中做出更明智的技术选型,构建更可靠、更高效的智能体应用。
利用其他不同于教程的框架
py
"""
使用 Dify 框架的 AI Agent Demo
Dify 是一个轻量级的 LLM 应用开发框架,对国内环境友好
"""
import os
import json
from typing import Dict, Any
from openai import OpenAI
# 设置环境变量
os.environ["LLM_MODEL_ID"] = "coding-glm-5.1-free"
os.environ["LLM_API_KEY"] = "sk-Q*****************************6"
os.environ["LLM_BASE_URL"] = "https://aihubmix.com/v1"
class SimpleAgent:
"""简单的Agent实现,类似Dify的工作流概念"""
def __init__(self):
"""初始化Agent,配置LLM客户端"""
self.model = os.getenv("LLM_MODEL_ID", "coding-glm-5.1-free")
self.client = OpenAI(
api_key=os.getenv("LLM_API_KEY"), base_url=os.getenv("LLM_BASE_URL")
)
self.messages = []
def add_system_prompt(self, prompt: str):
"""添加系统提示"""
self.messages.append({"role": "system", "content": prompt})
def add_user_message(self, message: str):
"""添加用户消息"""
self.messages.append({"role": "user", "content": message})
def call_llm(self, temperature: float = 0.7) -> str:
"""调用LLM获取响应"""
try:
response = self.client.chat.completions.create(
model=self.model,
messages=self.messages,
temperature=temperature,
max_tokens=1000,
)
return response.choices[0].message.content
except Exception as e:
return f"调用LLM时出错: {str(e)}"
def add_assistant_message(self, message: str):
"""添加助手消息到历史"""
self.messages.append({"role": "assistant", "content": message})
def clear_history(self):
"""清空对话历史"""
self.messages = []
class TaskExecutor:
"""任务执行器,实现简单的工作流"""
def __init__(self):
self.agent = SimpleAgent()
def analyze_task(self, task_description: str) -> Dict[str, Any]:
"""分析任务并生成执行计划"""
self.agent.add_system_prompt(
"你是一个任务分析专家。请分析用户给出的任务,并生成一个简单的执行计划。"
)
self.agent.add_user_message(
f"请分析以下任务并给出执行计划(用JSON格式):\n{task_description}"
)
response = self.agent.call_llm()
# 尝试解析JSON响应
try:
# 提取JSON部分
import re
json_match = re.search(r"\{.*\}", response, re.DOTALL)
if json_match:
plan = json.loads(json_match.group())
return plan
except:
pass
return {"plan": response, "steps": ["分析任务", "执行", "总结"]}
def execute_step(self, step: str, context: Dict) -> str:
"""执行单个步骤"""
self.agent.clear_history()
self.agent.add_system_prompt(
"你是一个任务执行助手,请根据上下文执行指定的步骤。"
)
prompt = f"""
当前步骤: {step}
上下文信息: {json.dumps(context, ensure_ascii=False)}
请执行这个步骤并返回结果。
"""
self.agent.add_user_message(prompt)
return self.agent.call_llm()
def run(self, task_description: str) -> str:
"""运行完整的工作流"""
print("=" * 50)
print(f"📋 接收任务: {task_description}")
print("=" * 50)
# 步骤1: 分析任务
print("\n🔍 步骤1: 分析任务...")
plan = self.analyze_task(task_description)
print(f"📊 分析结果: {json.dumps(plan, ensure_ascii=False, indent=2)}")
# 步骤2: 执行计划
print("\n🚀 步骤2: 执行任务...")
context = {"original_task": task_description, "plan": plan}
results = []
# 获取执行步骤
steps = plan.get("steps", ["分析", "执行", "输出"])
for i, step in enumerate(steps, 1):
print(f"\n 📝 执行步骤 {i}/{len(steps)}: {step}")
result = self.execute_step(step, context)
print(
f" ✅ 结果: {result[:100]}..."
if len(result) > 100
else f" ✅ 结果: {result}"
)
results.append({"step": step, "result": result})
context[f"step_{i}_result"] = result
# 步骤3: 生成最终输出
print("\n📝 步骤3: 生成最终输出...")
self.agent.clear_history()
self.agent.add_system_prompt("请根据执行结果,生成一个简洁、清晰的最终输出。")
summary_prompt = f"""
原始任务: {task_description}
执行结果: {json.dumps(results, ensure_ascii=False, indent=2)}
请生成最终的输出报告。
"""
self.agent.add_user_message(summary_prompt)
final_output = self.agent.call_llm()
print("\n" + "=" * 50)
print("✅ 任务完成!")
print("=" * 50)
return final_output
class DataProcessor:
"""数据处理器示例 - 展示特定功能"""
def __init__(self):
self.agent = SimpleAgent()
def process_text(self, text: str, operation: str) -> str:
"""处理文本数据"""
operations = {
"summarize": "请总结以下文本的主要内容:",
"analyze": "请分析以下文本的情感、主题和关键信息:",
"translate": "请将以下文本翻译成英文:",
"extract": "请从以下文本中提取关键信息:",
}
prompt = operations.get(operation, "请处理以下文本:")
self.agent.add_system_prompt("你是一个文本处理助手。")
self.agent.add_user_message(f"{prompt}\n\n{text}")
return self.agent.call_llm()
def main():
"""主函数 - 演示框架的使用"""
print("\n" + "=" * 60)
print("🚀 Dify风格AI Agent Demo - 任务执行示例")
print("=" * 60)
# 创建任务执行器
executor = TaskExecutor()
# 示例任务1: 简单的信息处理
task1 = "请帮我整理一份关于'人工智能在医疗领域的应用'的简短报告,包括3个主要应用场景和每个场景的简要说明。"
result1 = executor.run(task1)
print("\n📄 最终报告:")
print(result1)
print("\n" + "=" * 60)
print("📊 第二个示例: 数据处理")
print("=" * 60)
# 创建数据处理器
processor = DataProcessor()
# 示例文本
sample_text = """
人工智能正在彻底改变医疗行业。通过深度学习算法,AI可以帮助医生更准确地诊断疾病,
特别是通过分析医学影像来检测早期癌症。此外,AI还能加速新药研发过程,将研发周期
从传统的10-15年缩短到3-5年。个性化治疗方案也是AI的重要应用,通过分析患者的
基因数据和生活习惯,为每位患者定制最适合的治疗方案。
"""
# 处理文本
result2 = processor.process_text(sample_text, "summarize")
print("\n📝 文本摘要:")
print(result2)
print("\n" + "=" * 60)
print("✨ Demo执行完成!")
print("=" * 60)
# 展示配置信息
print("\n⚙️ 当前配置:")
print(f" 模型: {os.getenv('LLM_MODEL_ID')}")
print(f" API地址: {os.getenv('LLM_BASE_URL')}")
print(f" API Key: {os.getenv('LLM_API_KEY')[:20]}...")
if __name__ == "__main__":
main()
项目地址:hello-agents