demo_with_a2a.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. """
  2. ✅ A2A 模式:两个 Agent 通过统一协议通信
  3. 调用方不需要知道 API 细节,Agent Card 动态发现能力
  4. """
  5. import asyncio
  6. import httpx
  7. from a2a.client import A2ACardResolver, ClientConfig, create_client
  8. from a2a.helpers import new_text_message
  9. from a2a.types import Role, SendMessageRequest
  10. A2A_QA_URL = "http://127.0.0.1:9999"
  11. A2A_TRANSLATE_URL = "http://127.0.0.1:9998"
  12. def extract_text(task) -> str:
  13. texts = []
  14. if task.artifacts:
  15. for artifact in task.artifacts:
  16. for part in artifact.parts:
  17. t = part.text.strip() if part.text else ""
  18. if t:
  19. texts.append(t)
  20. return "\n".join(texts)
  21. async def call_a2a_agent(url: str, question: str) -> str:
  22. """通过 A2A 协议调用任意 Agent(统一接口!)"""
  23. async with httpx.AsyncClient() as http_client:
  24. # 1. Agent Card 发现(自动获取能力描述)
  25. resolver = A2ACardResolver(httpx_client=http_client, base_url=url)
  26. agent_card = await resolver.get_agent_card()
  27. print(f" [发现] {agent_card.name} | 技能: {[s.name for s in agent_card.skills]}")
  28. # 2. 统一接口调用(不管什么 Agent 都一样)
  29. config = ClientConfig(streaming=False)
  30. client = await create_client(agent=agent_card, client_config=config)
  31. message = new_text_message(question, role=Role.ROLE_USER)
  32. request = SendMessageRequest(message=message)
  33. result = ""
  34. async for response in client.send_message(request):
  35. result = extract_text(response.task)
  36. await client.close()
  37. return result
  38. async def main():
  39. question = "什么是微服务架构?"
  40. print("=" * 64)
  41. print(" ✅ 使用 A2A 协议")
  42. print(" 两个 Agent,同一套协议,零适配代码")
  43. print("=" * 64)
  44. print(f"\n 用户: {question}")
  45. # Step 1: 调用问答 Agent — 通过 A2A
  46. print("\n ── 调用 问答 Agent ──")
  47. qa_result = await call_a2a_agent(A2A_QA_URL, question)
  48. print(f" 回答: {qa_result[:80]}...")
  49. # Step 2: 把回答送去翻译 — 同一个函数,换个 URL 而已
  50. print("\n ── 调用 翻译 Agent ──")
  51. print(" ✓ 同一套 send_message(),无需任何适配")
  52. trans_result = await call_a2a_agent(A2A_TRANSLATE_URL, f"把下面这句话翻译成英文:{qa_result}")
  53. print(f" 翻译: {trans_result[:80]}...")
  54. # Step 3: 再加第三个 Agent 怎么办?
  55. print("\n ── 再加第 3 个 Agent ──")
  56. print(" ✓ call_a2a_agent(url, question) 直接复用")
  57. print(" ✓ 换个 URL 和问题就行,代码一行不改")
  58. # ===== 对比总结 =====
  59. print()
  60. print("-" * 64)
  61. print(" 对比:")
  62. print(" 问答 Agent: A2A 协议 → send_message()")
  63. print(" 翻译 Agent: A2A 协议 → send_message()")
  64. print(" → 两个 Agent 共享同一套接口")
  65. print(" → 新增 Agent 只需知道 URL,无需适配代码")
  66. if __name__ == "__main__":
  67. asyncio.run(main())