hello_agent_ch6_answer
第六章课后问题解答
1. 四大智能体框架深入对比
1.1 AutoGen vs LangGraph 对比分析
协作模式:
- AutoGen:基于多角色对话的自然协作模式。智能体在"群聊"环境中通过对话交流,协作行为从对话规则中"涌现"出来,更贴近人类团队合作方式。
- LangGraph:基于状态机的精确协作模式。将整个流程分解为节点和边构成的图,每个步骤都有明确的输入输出,协作过程严格按图执行。
控制方式:
- AutoGen:隐式控制,通过系统消息定义角色,通过对话规则间接控制流程。控制粒度较粗,依赖于LLM的对话能力。
- LangGraph:显式控制,通过图的节点和边直接控制每个步骤。可以精确控制条件分支、循环和状态转换。
适用场景:
- AutoGen:适合需要自然语言交互、角色分工明确、流程相对灵活的场景,如创意讨论、需求分析、团队协作等。
- LangGraph:适合流程明确、需要严格步骤控制、可追溯可审计的场景,如审批流程、数据处理管道、自动化工作流等。
1.2 "涌现式协作" vs "显式控制"的理解
涌现式协作(Emergent Collaboration):
- 特点:通过简单的局部规则产生复杂的全局行为。智能体只遵循自身角色的行为准则,协作行为从对话中自然产生。
- 优势:更贴近人类协作方式,具有灵活性和创造性,能够处理未预见的场景。
- 劣势:难以预测和控制,可能产生意外行为,调试困难。
显式控制(Explicit Control):
- 特点:通过明确的状态机或工作流定义整个协作过程。每个步骤都有精确的输入输出和跳转条件。
- 优势:高度可控、可预测、可调试,适合需要高可靠性的场景。
- 劣势:灵活性较差,难以处理超出预定义流程的情况。
设计权衡:选择哪种设计取决于应用需求。需要创造性、灵活性的场景适合涌现式协作;需要可靠性、可审计性的场景适合显式控制。
2. AutoGen案例扩展
2.1 支持动态回退的机制设计
在AutoGen中,可以通过修改RoundRobinGroupChat的发言顺序逻辑或使用更灵活的群聊管理器来实现动态回退。以下是两种实现方案:
方案一:使用条件发言权转移
from autogen_agentchat.teams import GroupChat
class DynamicGroupChat(GroupChat):
def select_next_speaker(self, current_speaker, messages):
# 分析最近的消息内容
last_message = messages[-1].content if messages else ""
# 如果代码审查员要求重新设计
if current_speaker.name == "CodeReviewer" and "需要重新设计" in last_message:
# 回退到产品经理
for agent in self.participants:
if agent.name == "ProductManager":
return agent
# 默认轮询逻辑
current_index = self.participants.index(current_speaker)
next_index = (current_index + 1) % len(self.participants)
return self.participants[next_index]
方案二:使用消息标记触发回退
# 在代码审查员的系统消息中添加回退触发
code_reviewer_system_message += """
当你发现代码需要重大修改时,请在回复中包含"建议回退到产品经理重新设计"。
"""
# 在产品经理的系统消息中添加处理逻辑
product_manager_system_message += """
当你看到"建议回退到产品经理重新设计"的请求时,你需要:
1. 重新评估需求
2. 提供更详细的技术要求
3. 再次交给工程师实现
"""
2.2 添加测试工程师角色
测试工程师系统消息设计:
def create_qa_engineer(model_client):
"""创建测试工程师智能体"""
system_message = """你是一位经验丰富的测试工程师(QA),专门负责软件质量保证和自动化测试。
你的核心职责包括:
1. **测试用例设计**:基于需求文档编写全面的测试用例
2. **自动化测试**:使用合适的框架(如pytest, unittest)实现自动化测试
3. **缺陷管理**:发现、报告和跟踪缺陷,确保问题得到解决
4. **质量评估**:评估代码质量,给出质量评分和改进建议
测试流程:
1. 接收代码审查通过的代码
2. 分析代码逻辑,设计测试用例(边界测试、异常测试、性能测试)
3. 执行测试并记录结果
4. 生成测试报告,包括通过率、缺陷统计等
5. 如果发现严重缺陷,要求返回修复;如果通过,给出质量认证
请提供详细的测试报告,完成后说"测试完成,质量认证通过"。"""
return AssistantAgent(
name="QualityAssurance",
model_client=model_client,
system_message=system_message,
)
修改团队协作流程:
team_chat = RoundRobinGroupChat(
participants=[
product_manager,
engineer,
code_reviewer,
qa_engineer, # 新增测试工程师
user_proxy
],
# ... 其他参数不变
)
2.3 对话质量监控机制设计
监控机制实现方案:
class ConversationMonitor:
def __init__(self):
self.message_history = []
self.topic_keywords = ["比特币", "价格", "显示", "Streamlit", "API"] # 任务相关关键词
def monitor_conversation(self, messages):
"""监控对话质量"""
issues = []
# 检查对话长度
if len(messages) > 50:
issues.append("对话轮次过多,可能陷入循环")
# 检查话题偏离
recent_messages = messages[-5:] if len(messages) >= 5 else messages
topic_relevance = self.check_topic_relevance(recent_messages)
if topic_relevance < 0.3: # 30%相关性阈值
issues.append("对话偏离主题")
# 检查重复内容
if self.check_repetition(messages, threshold=3):
issues.append("检测到重复内容")
return issues
def check_topic_relevance(self, messages):
"""检查话题相关性"""
relevant_count = 0
for msg in messages:
content = msg.content if hasattr(msg, 'content') else str(msg)
for keyword in self.topic_keywords:
if keyword in content:
relevant_count += 1
break
return relevant_count / len(messages) if messages else 0
def check_repetition(self, messages, threshold=3):
"""检查内容重复"""
if len(messages) < threshold * 2:
return False
recent_contents = [m.content for m in messages[-threshold:]]
previous_contents = [m.content for m in messages[-(threshold*2):-threshold]]
# 简单重复检测:检查相似内容
for recent in recent_contents:
for previous in previous_contents:
similarity = self.calculate_similarity(recent, previous)
if similarity > 0.8: # 80%相似度阈值
return True
return False
def calculate_similarity(self, text1, text2):
"""计算文本相似度(简化版)"""
# 这里可以使用更复杂的相似度算法
words1 = set(text1.lower().split())
words2 = set(text2.lower().split())
intersection = words1.intersection(words2)
union = words1.union(words2)
return len(intersection) / len(union) if union else 0
# 在团队协作中集成监控
class MonitoredTeamChat(RoundRobinGroupChat):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.monitor = ConversationMonitor()
async def run_stream(self, task=None):
messages = []
async for msg in super().run_stream(task):
messages.append(msg)
issues = self.monitor.monitor_conversation(messages)
if issues:
print(f"⚠️ 对话质量警告: {issues}")
# 可以选择性干预:发送纠正消息或终止对话
yield msg
3. AgentScope案例分析
3.1 消息驱动架构的优势
消息驱动架构的优势:
- 解耦性:智能体之间不直接依赖,通过消息中心通信,降低耦合度
- 异步性:支持并行处理和异步通信,提高系统吞吐量
- 可扩展性:易于添加新智能体或分布式部署
- 可观测性:所有交互都有消息记录,便于调试和监控
- 容错性:消息可以持久化和重试,提高系统可靠性
适用场景:
- 实时交互系统(如游戏、聊天)
- 分布式多智能体系统
- 需要高并发处理的场景
- 需要详细审计日志的系统
3.2 猎人角色结构化输出模型
from pydantic import BaseModel, Field, validator
from typing import Optional
class HunterActionModelCN(BaseModel):
"""猎人行动的结构化输出模型"""
is_dead: bool = Field(
description="猎人是否已经死亡",
default=False
)
use_gun: bool = Field(
description="是否使用枪械(死亡时是否开枪)",
default=False
)
target_name: Optional[str] = Field(
description="开枪目标玩家姓名(如果开枪)",
default=None
)
reason: Optional[str] = Field(
description="开枪理由",
default=None
)
@validator('use_gun')
def check_gun_usage(cls, v, values):
"""验证枪械使用逻辑"""
if v and not values.get('is_dead'):
raise ValueError('猎人只有在死亡时才能开枪')
return v
@validator('target_name')
def check_target_if_using_gun(cls, v, values):
"""验证开枪时必须有目标"""
if values.get('use_gun') and not v:
raise ValueError('使用枪械时必须指定目标')
return v
@validator('reason')
def check_reason_if_using_gun(cls, v, values):
"""验证开枪时必须有理由"""
if values.get('use_gun') and not v:
raise ValueError('使用枪械时必须提供理由')
return v
3.3 分布式部署的挑战与解决方案
技术挑战:
- 网络延迟:不同服务器间通信延迟影响游戏实时性
- 消息顺序:保证消息的正确顺序传递
- 状态一致性:确保所有节点状态同步
- 容错处理:部分节点故障时的系统恢复
- 负载均衡:合理分配计算资源
解决方案:
1. 消息顺序性保证:
# 使用序列号确保消息顺序
class SequencedMessage(Msg):
def __init__(self, sequence_num: int, **kwargs):
super().__init__(**kwargs)
self.sequence_num = sequence_num
# 在消息中心实现顺序处理
class OrderedMsgHub(MsgHub):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.expected_sequence = 0
self.buffer = {} # 缓存乱序到达的消息
async def receive(self, msg):
if msg.sequence_num == self.expected_sequence:
# 处理当前消息
await self.process_message(msg)
self.expected_sequence += 1
# 检查缓冲中是否有下一个消息
while self.expected_sequence in self.buffer:
buffered_msg = self.buffer.pop(self.expected_sequence)
await self.process_message(buffered_msg)
self.expected_sequence += 1
else:
# 缓存乱序消息
self.buffer[msg.sequence_num] = msg
2. 状态一致性方案:
# 使用分布式共识算法(简化版)
class DistributedGameState:
def __init__(self):
self.state = {}
self.version = 0
self.quorum = 3 # 需要多数节点确认
async def update_state(self, key, value, nodes):
"""分布式更新状态"""
# 阶段1:准备阶段
prepare_votes = 0
for node in nodes:
if await node.prepare_update(self.version + 1):
prepare_votes += 1
# 阶段2:提交阶段(获得多数同意)
if prepare_votes >= self.quorum:
self.state[key] = value
self.version += 1
# 通知所有节点提交
for node in nodes:
await node.commit_update(key, value, self.version)
4. CAMEL案例分析
4.1 冲突解决机制设计
冲突解决方案:
方案一:引入仲裁者智能体
class ArbiterAgent:
"""仲裁者智能体,解决任务终止冲突"""
def __init__(self, threshold=0.7):
self.threshold = threshold # 置信度阈值
def resolve_termination_conflict(self, agent1_opinion, agent2_opinion, conversation_history):
"""解决终止冲突"""
# 分析对话质量
quality_score = self.assess_conversation_quality(conversation_history)
# 分析任务完成度
completion_score = self.assess_task_completion(conversation_history)
# 分析智能体置信度
confidence1 = self.extract_confidence(agent1_opinion)
confidence2 = self.extract_confidence(agent2_opinion)
# 综合决策
if quality_score > self.threshold and completion_score > self.threshold:
return "TERMINATE", "任务已高质量完成"
elif quality_score < 0.3 or completion_score < 0.3:
return "CONTINUE", "任务完成度不足,需要继续"
else:
# 置信度高的智能体决定
if confidence1 > confidence2:
return agent1_opinion, f"基于置信度决策: Agent1({confidence1:.2f}) > Agent2({confidence2:.2f})"
else:
return agent2_opinion, f"基于置信度决策: Agent2({confidence2:.2f}) > Agent1({confidence1:.2f})"
def assess_conversation_quality(self, history):
"""评估对话质量"""
# 实现质量评估逻辑
pass
方案二:多轮投票机制
def enhanced_collaboration_with_voting():
"""增强版协作流程,包含投票机制"""
termination_votes = {"yes": 0, "no": 0}
max_voting_rounds = 3
for round_num in range(max_voting_rounds):
print(f"\n第{round_num + 1}轮终止投票...")
# 收集双方意见
opinions = []
for agent in [psychologist, writer]:
opinion = agent.vote_on_termination(conversation_history)
opinions.append(opinion)
termination_votes[opinion] += 1
# 检查是否达成共识
if termination_votes["yes"] >= 2:
return "TERMINATE", "达成终止共识"
elif termination_votes["no"] >= 2:
return "CONTINUE", "达成继续共识"
# 未达成共识,进行讨论
if round_num < max_voting_rounds - 1:
discussion_result = mediate_discussion(opinions, conversation_history)
if discussion_result == "consensus_reached":
continue
# 投票轮次用完,由任务复杂度决定
task_complexity = assess_task_complexity(task_prompt)
if task_complexity > 0.8:
return "CONTINUE", "复杂任务需要更多讨论"
else:
return "TERMINATE", "投票未决,基于任务复杂度终止"
4.2 CAMEL Workforce与AutoGen群聊对比
CAMEL Workforce架构特点:
任务管理器
↓
┌─────┴─────┐
↓ ↓
工作分解 智能体池
↓ ↓
子任务分配 → 执行监控
↓
结果聚合
与AutoGen群聊的主要区别:
-
协作模式不同:
- CAMEL Workforce:基于任务分解的层级协作。任务被分解为子任务,分配给合适的智能体。
- AutoGen群聊:基于对话的平面协作。所有智能体在同一层级通过对话协作。
-
控制方式不同:
- CAMEL Workforce:集中式任务管理,由任务管理器统一调度。
- AutoGen群聊:分散式对话管理,智能体相对自主。
-
适用场景不同:
- CAMEL Workforce:适合复杂任务分解、需要明确分工的场景。
- AutoGen群聊:适合需要创意碰撞、多方讨论的场景。
-
可扩展性:
- CAMEL Workforce:易于添加新的智能体类型和工作节点。
- AutoGen群聊:对话复杂度随智能体数量指数增长。
5. LangGraph案例分析
5.1 三步问答助手图结构
START
↓
┌─────┴─────┐
↓ ↓
理解节点 状态: {messages, user_query}
↓
┌─────┴─────┐
↓ ↓
搜索节点 状态: {search_query, search_results}
↓
┌─────┴─────┐
↓ ↓
回答节点 状态: {final_answer, step}
↓
END
状态转换条件:
START → 理解节点:无条件跳转理解节点 → 搜索节点:成功解析用户查询搜索节点 → 回答节点:搜索完成(无论成功或失败)回答节点 → END:生成最终答案
5.2 添加反思节点的条件边逻辑
from typing import Literal
def check_answer_quality(state: SearchState) -> Literal["re_search", "re_generate", "end"]:
"""检查答案质量并决定下一步"""
answer = state.get("final_answer", "")
search_results = state.get("search_results", "")
# 质量评估标准
quality_issues = []
# 1. 长度检查
if len(answer) < 50:
quality_issues.append("答案过短")
# 2. 内容检查
if not any(marker in answer.lower() for marker in ["首先", "其次", "另外", "建议", "总结"]):
quality_issues.append("缺乏结构化")
# 3. 搜索结果利用检查
if search_results and not any(keyword in answer for keyword in extract_keywords(search_results)):
quality_issues.append("未充分利用搜索结果")
# 4. 不确定性检查
uncertainty_words = ["不确定", "不知道", "可能", "大概", "或许"]
if any(word in answer for word in uncertainty_words):
quality_issues.append("答案不确定性高")
# 决策逻辑
if not quality_issues:
return "end" # 质量合格,结束
elif "未充分利用搜索结果" in quality_issues and search_results:
return "re_search" # 重新搜索
else:
return "re_generate" # 重新生成答案
# 修改图结构,添加反思循环
def create_enhanced_search_assistant():
workflow = StateGraph(SearchState)
# 添加节点
workflow.add_node("understand", understand_query_node)
workflow.add_node("search", tavily_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_conditional_edges(
"answer",
check_answer_quality,
{
"re_search": "search", # 重新搜索
"re_generate": "answer", # 重新生成
"end": END # 结束
}
)
# 编译图
return workflow.compile()
# 反思节点实现
def reflect_on_answer_node(state: SearchState) -> dict:
"""反思答案质量,提供改进方向"""
answer = state.get("final_answer", "")
issues = analyze_answer_issues(answer)
reflection_prompt = f"""分析以下答案的质量问题,并提供改进建议:
答案:{answer}
问题:{issues}
请提供具体的改进方向:"""
reflection = llm.invoke([SystemMessage(content=reflection_prompt)])
return {
"reflection": reflection.content,
"improvement_suggestions": extract_suggestions(reflection.content)
}
5.3 代码生成-测试-修复循环设计
图结构设计:
START
↓
┌─────┴─────┐
↓ ↓
需求分析 状态: {requirements, constraints}
↓
┌─────┴─────┐
↓ ↓
代码生成 状态: {generated_code, language}
↓
┌─────┴─────┐
↓ ↓
测试执行 状态: {test_cases, test_results}
↓
┌─────┴─────┐
↓ ↓
条件判断 → 通过 → END
↓
失败
↓
┌─────┴─────┐
↓ ↓
错误分析 状态: {error_logs, root_cause}
↓
┌─────┴─────┐
↓ ↓
修复生成 状态: {fix_suggestions, patched_code}
↓
└─────┬─────┘
↓
代码生成 (循环)
关键节点实现:
from typing import TypedDict, List, Optional
from enum import Enum
class DevelopmentState(TypedDict):
requirements: str
generated_code: str
test_results: dict
errors: List[str]
iteration_count: int
max_iterations: int = 5
class TestResult(Enum):
PASS = "pass"
FAIL = "fail"
ERROR = "error"
def code_generation_node(state: DevelopmentState) -> dict:
"""代码生成节点"""
prompt = f"""根据以下需求生成代码:
需求:{state['requirements']}
要求:
1. 使用Python实现
2. 包含适当的错误处理
3. 添加必要的注释
请生成完整可运行的代码:"""
response = llm.invoke([SystemMessage(content=prompt)])
code = extract_code_from_response(response.content)
return {
"generated_code": code,
"iteration_count": state.get("iteration_count", 0) + 1
}
def testing_node(state: DevelopmentState) -> dict:
"""测试执行节点"""
code = state["generated_code"]
# 执行测试(这里简化为模拟)
test_cases = generate_test_cases(state["requirements"])
results = run_tests(code, test_cases)
return {
"test_results": results,
"errors": results.get("errors", []) if results["overall"] == TestResult.FAIL else []
}
def analysis_node(state: DevelopmentState) -> dict:
"""错误分析节点"""
errors = state["errors"]
code = state["generated_code"]
analysis_prompt = f"""分析以下代码的错误,找出根本原因:
代码:
{code}
错误信息:
{errors}
请提供:
1. 错误类型和根本原因
2. 修复建议
3. 需要修改的代码位置"""
response = llm.invoke([SystemMessage(content=analysis_prompt)])
return {
"root_cause_analysis": response.content,
"fix_suggestions": extract_fix_suggestions(response.content)
}
def decision_node(state: DevelopmentState) -> str:
"""决策节点:决定下一步"""
# 检查是否通过测试
if state["test_results"].get("overall") == TestResult.PASS:
return "end"
# 检查是否达到最大迭代次数
if state.get("iteration_count", 0) >= state.get("max_iterations", 5):
return "end_with_failure"
# 检查是否需要重新分析
if not state.get("root_cause_analysis"):
return "analyze"
return "fix"
# 构建完整的开发循环图
def create_development_workflow():
workflow = StateGraph(DevelopmentState)
# 添加节点
workflow.add_node("generate", code_generation_node)
workflow.add_node("test", testing_node)
workflow.add_node("analyze", analysis_node)
workflow.add_node("fix", code_generation_node) # 复用代码生成节点进行修复
# 设置初始流程
workflow.add_edge(START, "generate")
workflow.add_edge("generate", "test")
# 添加条件边实现循环
workflow.add_conditional_edges(
"test",
decision_node,
{
"end": END,
"end_with_failure": END,
"analyze": "analyze",
"fix": "fix"
}
)
workflow.add_edge("analyze", "fix")
workflow.add_edge("fix", "test") # 修复后重新测试,形成循环
return workflow.compile()
6. 框架选型指南
应用A:智能客服系统
推荐框架:AgentScope
选择理由:
- 高并发处理能力:AgentScope的消息驱动架构天然支持高并发,能够处理每秒1000+的请求
- 分布式部署支持:原生支持智能体分布式部署,便于水平扩展
- 工程化稳定性:内置容错、监控、日志等企业级特性,保证7×24小时稳定运行
- 响应时间保证:异步架构确保低延迟响应,满足2秒内响应的要求
- 消息持久化:支持消息持久化存储,便于故障恢复和审计
架构设计建议:
- 使用分布式MsgHub管理智能体间通信
- 采用微服务架构,将不同功能的智能体部署在不同服务节点
- 实现负载均衡和故障转移机制
- 集成监控和告警系统
应用B:科研论文辅助写作平台
推荐框架:CAMEL
选择理由:
- 深度协作能力:CAMEL的角色扮演模式特别适合研究员和写作者之间的深度协作
- 自主推进能力:引导性提示让智能体能够自主推进任务,减少人工干预
- 创造性支持:适合需要创造性思维的文献综述和论文撰写
- 多轮讨论支持:支持智能体间进行多轮深入讨论,形成高质量内容
- 轻量级架构:相比其他框架,CAMEL架构更轻量,部署和维护成本低
架构设计建议:
- 设计互补的智能体角色(如研究员、写作者、审阅者)
- 精心设计引导性提示,确保协作方向正确
- 实现任务分解和进度跟踪机制
- 集成文献检索和数据分析工具
应用C:金融风控审批系统
推荐框架:LangGraph
选择理由:
- 严格流程控制:LangGraph的图结构能够精确控制每个审批步骤
- 可追溯性:每一步的状态变化都有明确记录,便于审计
- 条件分支支持:天然支持复杂的决策树和条件分支
- 循环机制:支持审批流程中的循环(如重新提交、补充材料)
- 人工节点集成:易于在流程中插入人工复核节点,实现人机协作
架构设计建议:
START
↓
资料审核节点
↓
┌──────┴──────┐
↓ ↓
通过 不通过
↓ ↓
风险评估节点 拒绝节点
↓
┌──────┴──────┐
↓ ↓
低风险 高风险
↓ ↓
额度计算节点 人工复核节点
↓ ↓
合规检查节点 ↓
↓ 重新评估
└──────┬──────┘
↓
最终决策节点
↓
END
实施要点:
- 为每个审批环节定义明确的状态和验证规则
- 实现严格的权限控制和数据加密
- 集成实时监控和异常检测
- 设计完善的审计日志系统

浙公网安备 33010602011771号