如何通过strands agents sdk实现 A2A 方案实现共享记忆的对话
return f"我记得 {key}: {context['value']} (来自第 {context['conversation_turn']} 轮)"您想用这些数字执行任何其他计算吗?return f"我记得 {key}: {context['value']} (类别: {cat})"session_id=f"conversation_{user_id}", # 会话_{用户ID}summa
·
from strands_tools.a2a_client import A2AClientToolProvider
# 告诉客户端所有可用的服务器地址
provider = A2AClientToolProvider(known_agent_urls=[
"http://localhost:9000", # 计算器
"http://localhost:9001", # 翻译
"http://localhost:9002" # 天气
])
# 客户端Agent会自动选择合适的服务
client_agent = Agent(tools=provider.tools)
client_agent("帮我算 5+3") # 自动选择计算器Agent
client_agent("翻译hello") # 自动选择翻译Agent
client_agent("今天天气怎么样") # 自动选择天气Agent
以通过这个 A2A 方案实现对话,但关于对话流程如何运作,有一些重要的注意事项。让我为您解释并展示如何针对对话进行优化:
当前行为分析
根据您当前的设置:
python
from strands_tools.a2a_client import A2AClientToolProvider provider = A2AClientToolProvider(known_agent_urls=[ "http://localhost:9000", # 数学智能体 "http://localhost:9001", # 翻译智能体 "http://localhost:9002" # 天气智能体 ]) client_agent = Agent(tools=provider.tools) # 每次调用都是独立的 client_agent("帮我计算 5+3") # 调用数学智能体 client_agent("翻译 hello") # 调用翻译智能体 client_agent("今天天气怎么样") # 调用天气智能体
发生的情况:
-
每次调用都是独立的 - 调用之间没有对话记忆
-
客户端智能体将请求路由到相应的专业智能体
-
每个专业智能体处理请求并返回结果
-
跨多次交互没有持久化的对话状态
支持对话的增强型 A2A 设置
以下是实现具有对话记忆的真正对话的方法:
1. 支持会话的客户端智能体
from strands import Agent from strands_tools.a2a_client import A2AClientToolProvider from strands.session.s3_session_manager import S3SessionManager # 创建支持会话的客户端智能体 session_manager = S3SessionManager( session_id="user_conversation_session", # 用户会话会话ID bucket="agent-conversations", # 智能体对话存储桶 prefix="client_sessions" # 客户端会话前缀 ) provider = A2AClientToolProvider(known_agent_urls=[ "http://localhost:9000", # 数学智能体 "http://localhost:9001", # 翻译智能体 "http://localhost:9002" # 天气智能体 ]) client_agent = Agent( name="对话式客户端智能体", # 对话式客户端智能体 session_manager=session_manager, # 启用对话记忆 tools=provider.tools, prompt=""" 您是一个可以帮助处理数学、翻译和天气问题的对话助手。 您可以通过 A2A 协议访问专业智能体。 重要提示: - 记住我们的对话历史 - 基于之前的交互进行构建 - 在适当时提出后续问题 - 在多个请求之间保持上下文 可用的专家: - 数学计算 (localhost:9000) - 语言翻译 (localhost:9001) - 天气信息 (localhost:9002) """ ) # 现在您可以进行真正的对话了 print("=== 对话 1 ===") response1 = client_agent("帮我计算 5+3") print(f"智能体: {response1}") print("\n=== 对话 2 ===") response2 = client_agent("你能再计算一下那个结果的平方吗?") print(f"智能体: {response2}") print("\n=== 对话 3 ===") response3 = client_agent("现在把短语 '答案是 64' 翻译成西班牙语") print(f"智能体: {response3}") print("\n=== 对话 4 ===") response4 = client_agent("马德里今天的天气怎么样?") print(f"智能体: {response4}")
2. 对话式专业智能体
让您的专业智能体也支持对话:
# math_agent.py (localhost:9000) from strands import Agent, tool from strands.multiagent.a2a import A2AServer from strands.session.s3_session_manager import S3SessionManager @tool def calculate(expression: str) -> str: """执行数学计算""" try: result = eval(expression) return f"{expression} 的结果是 {result}" except Exception as e: return f"计算 {expression} 时出错: {str(e)}" @tool def remember_calculation(expression: str, result: str) -> str: """记住一个计算以供将来参考""" # 这可以存储在共享内存或会话中 return f"我会记住 {expression} = {result}" # 支持会话的数学智能体 math_session_manager = S3SessionManager( session_id="math_agent_session", # 数学智能体会话ID bucket="agent-conversations", # 智能体对话存储桶 prefix="math_sessions" # 数学会话前缀 ) math_agent = Agent( name="对话式数学智能体", # 对话式数学智能体 session_manager=math_session_manager, tools=[calculate, remember_calculation], prompt=""" 您是一个对话式数学专家。 - 记住我们对话中之前的计算 - 在相关时引用之前的结果 - 如果数学请求不清楚,请提出澄清问题 - 在有帮助时提供分步解释 """ ) # 使用 A2A 提供服务 server = A2AServer(agent=math_agent, port=9000) server.serve()
3. 多轮对话示例
这是一个展示真正对话的完整示例:
import asyncio from strands import Agent from strands_tools.a2a_client import A2AClientToolProvider from strands.session.file_session_manager import FileSessionManager async def conversational_demo(): # 设置对话式客户端 session_manager = FileSessionManager( session_id="demo_conversation", # 演示会话ID base_dir="./conversation_sessions" # 会话存储目录 ) provider = A2AClientToolProvider(known_agent_urls=[ "http://localhost:9000", # 数学智能体 "http://localhost:9001", # 翻译智能体 "http://localhost:9002" # 天气智能体 ]) client_agent = Agent( name="对话助手", # 对话助手 session_manager=session_manager, tools=provider.tools, prompt=""" 您是一个有用的对话助手,可以访问专业智能体。 关键行为: - 维护对话上下文和记忆 - 自然地引用之前的交互 - 提出后续问题以更好地帮助用户 - 在相关时组合来自多个专家的信息 - 具有对话性和吸引力 可用的专家智能体: - 数学计算和分析 - 语言翻译服务 - 天气信息和预报 """ ) # 模拟多轮对话 conversation = [ "你好!你能帮我做一些计算吗?", "我需要计算 15 * 23", "太好了!现在你能计算那个结果的 20% 吗?", "完美。你能把 '结果是 69' 翻译成法语吗?", "谢谢!顺便问一下,巴黎今天的天气怎么样?", "有趣!那么根据我们之前关于预算和天气的对话,如果我计划去巴黎旅行,你会建议带伞吗?" ] print("=== 多轮对话演示 ===\n") for i, user_input in enumerate(conversation, 1): print(f"👤 用户 (第 {i} 轮): {user_input}") response = await client_agent.run_async(user_input) print(f"🤖 助手: {response}") print("-" * 60) # 短暂延迟以模拟自然对话节奏 await asyncio.sleep(1) # 运行演示 asyncio.run(conversational_demo())
4. 高级对话功能
添加更复杂的对话功能:
from strands import Agent, tool from typing import Dict, List import json from datetime import datetime # 导入 datetime class ConversationalA2AClient: def __init__(self, agent_urls: List[str], user_id: str = "default_user"): self.user_id = user_id self.conversation_history = [] self.context_memory = {} # 具有用户特定会话的会话管理器 self.session_manager = S3SessionManager( session_id=f"conversation_{user_id}", # 会话_{用户ID} bucket="user-conversations", # 用户对话存储桶 prefix=f"users/{user_id}/sessions" # 用户/{用户ID}/会话 前缀 ) # A2A 提供者 self.provider = A2AClientToolProvider(known_agent_urls=agent_urls) # 用于对话管理的增强工具 self.conversation_tools = [ self.remember_context, self.recall_context, self.summarize_conversation, self.ask_clarification ] # 创建对话式智能体 self.agent = Agent( name=f"{user_id} 的个人助手", # {用户ID} 的个人助手 session_manager=self.session_manager, tools=self.provider.tools + self.conversation_tools, prompt=self.get_conversational_prompt() ) @tool def remember_context(self, key: str, value: str, category: str = "general") -> str: """记住对话中的重要上下文""" if category not in self.context_memory: self.context_memory[category] = {} self.context_memory[category][key] = { "value": value, "timestamp": datetime.utcnow().isoformat(), "conversation_turn": len(self.conversation_history) } return f"我会记住 {key}: {value} (类别: {category})" @tool def recall_context(self, key: str = None, category: str = None) -> str: """回忆先前存储的上下文""" if category and category in self.context_memory: if key and key in self.context_memory[category]: context = self.context_memory[category][key] return f"我记得 {key}: {context['value']} (来自第 {context['conversation_turn']} 轮)" else: items = list(self.context_memory[category].keys()) return f"在 {category} 中,我记得: {', '.join(items)}" elif key: # 在所有类别中搜索 for cat, items in self.context_memory.items(): if key in items: context = items[key] return f"我记得 {key}: {context['value']} (类别: {cat})" return f"我不记得关于 {key} 的任何事情" else: # 返回所有上下文的摘要 summary = {} for cat, items in self.context_memory.items(): summary[cat] = list(items.keys()) return f"我记得: {json.dumps(summary, indent=2)}" @tool def summarize_conversation(self, last_n_turns: int = 5) -> str: """总结最近的对话轮次""" recent_history = self.conversation_history[-last_n_turns:] summary = f"最近 {len(recent_history)} 轮的摘要:\n" for i, turn in enumerate(recent_history, 1): summary += f"{i}. 用户: {turn['user'][:50]}...\n" summary += f" 助手: {turn['assistant'][:50]}...\n" return summary @tool def ask_clarification(self, question: str, context: str = "") -> str: """向用户请求澄清""" clarification = f"我需要澄清: {question}" if context: clarification += f"\n上下文: {context}" return clarification def get_conversational_prompt(self) -> str: return f""" 您是 {self.user_id} 的个人对话助手。 您可以通过 A2A 协议访问专业智能体和对话管理工具。 对话指南: 1. 保持自然、吸引人的对话 2. 使用 remember_context 工具记住重要细节 3. 使用 recall_context 工具引用之前的对话 4. 当请求不明确时请求澄清 5. 智能地组合来自多个专家的信息 6. 主动提供相关的帮助 记忆类别: - preferences: 用户偏好和设置 - calculations: 数学结果和公式 - translations: 语言对和翻译 - weather: 位置偏好和天气信息 - tasks: 进行中的任务和项目 始终努力做到有帮助、有上下文且具有对话性! """ async def chat(self, message: str) -> str: """带有对话跟踪的主聊天接口""" # 添加到对话历史 response = await self.agent.run_async(message) self.conversation_history.append({ "user": message, "assistant": response, "timestamp": datetime.utcnow().isoformat() }) return response # 用法 async def advanced_dialogue_demo(): client = ConversationalA2AClient( agent_urls=[ "http://localhost:9000", # 数学 "http://localhost:9001", # 翻译 "http://localhost:9002" # 天气 ], user_id="john_doe" # 用户 john_doe ) # 具有记忆和上下文的扩展对话 conversation = [ "你好!我计划下个月去巴黎旅行。", "你能帮我计算预算吗?我有 2000 美元可以花。", "如果我每天在住宿上花费 150 美元,我可以住多少天?", "太好了!你能把 '我想预订一个房间住 13 天' 翻译成法语吗?", "巴黎三月的天气通常怎么样?", "根据我们关于我的预算和天气的对话,我应该带什么?", "你能再提醒我一下我的总预算是多少吗?", "完美!你能总结一下我们目前的对话吗?" ] print("=== 高级对话式 A2A 演示 ===\n") for i, user_input in enumerate(conversation, 1): print(f"👤 用户 (第 {i} 轮): {user_input}") response = await client.chat(user_input) print(f"🤖 助手: {response}") print("-" * 80) await asyncio.sleep(1) # 运行高级演示 asyncio.run(advanced_dialogue_demo())
启用对话的 A2A 方案的主要优势
-
持久记忆: 跨交互记住对话
-
上下文感知: 智能体可以引用之前的交流
-
多智能体协调: 无缝组合多个专业智能体
-
自然流程: 感觉像是在与一个智能助手交谈
-
可扩展: 可以添加更多专业智能体而无需更改客户端代码
-
用户特定: 每个用户都有自己的对话上下文
预期输出示例
👤 用户 (第 1 轮): 你好!你能帮我做一些计算吗? 🤖 助手: 您好!我很乐意帮您计算。我可以访问一个专业的数学智能体,它可以处理各种数学运算。您想计算什么? 👤 用户 (第 2 轮): 我需要计算 15 * 23 🤖 助手: 让我为您计算一下... 15 * 23 = 345。我会记住这个计算,以防您以后需要参考。您还想计算别的吗? 👤 用户 (第 3 轮): 太好了!现在你能计算那个结果的 20% 吗? 🤖 助手: 当然!取我们之前结果 (345) 的 20%:345 * 0.20 = 69。所以 345 的 20% 是 69。您想用这些数字执行任何其他计算吗?
是的,这个 A2A 方案绝对支持丰富的、有上下文的对话!关键是使用会话管理和对话感知提示(prompt)来在分布式智能体网络中维护上下文。
更多推荐
所有评论(0)