You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

llamaindex_agent.py 5.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. """
  2. This example shows how integrate llamaindex agent.
  3. """
  4. import asyncio
  5. import os
  6. from dataclasses import dataclass
  7. from typing import List, Optional
  8. from agnext.application import SingleThreadedAgentRuntime
  9. from agnext.components import RoutedAgent, message_handler
  10. from agnext.core import AgentId, MessageContext
  11. from llama_index.core import Settings
  12. from llama_index.core.agent import ReActAgent
  13. from llama_index.core.agent.runner.base import AgentRunner
  14. from llama_index.core.base.llms.types import (
  15. ChatMessage,
  16. MessageRole,
  17. )
  18. from llama_index.core.chat_engine.types import AgentChatResponse
  19. from llama_index.core.memory import ChatSummaryMemoryBuffer
  20. from llama_index.core.memory.types import BaseMemory
  21. from llama_index.embeddings.azure_openai import AzureOpenAIEmbedding
  22. from llama_index.llms.azure_openai import AzureOpenAI
  23. from llama_index.tools.wikipedia import WikipediaToolSpec
  24. @dataclass
  25. class Resource:
  26. content: str
  27. node_id: str
  28. score: Optional[float] = None
  29. @dataclass
  30. class Message:
  31. content: str
  32. sources: Optional[List[Resource]] = None
  33. class LlamaIndexAgent(RoutedAgent):
  34. def __init__(self, description: str, llama_index_agent: AgentRunner, memory: BaseMemory | None = None) -> None:
  35. super().__init__(description)
  36. self._llama_index_agent = llama_index_agent
  37. self._memory = memory
  38. @message_handler
  39. async def handle_user_message(self, message: Message, ctx: MessageContext) -> Message:
  40. # retriever history messages from memory!
  41. history_messages: List[ChatMessage] = []
  42. # type: ignore
  43. # pyright: ignore
  44. response: AgentChatResponse # pyright: ignore
  45. if self._memory is not None:
  46. history_messages = self._memory.get(input=message.content)
  47. response = await self._llama_index_agent.achat(message=message.content, history_messages=history_messages) # pyright: ignore
  48. else:
  49. response = await self._llama_index_agent.achat(message=message.content) # pyright: ignore
  50. if isinstance(response, AgentChatResponse):
  51. if self._memory is not None:
  52. self._memory.put(ChatMessage(role=MessageRole.USER, content=message.content))
  53. self._memory.put(ChatMessage(role=MessageRole.ASSISTANT, content=response.response))
  54. assert isinstance(response.response, str)
  55. resources: List[Resource] = [
  56. Resource(content=source_node.get_text(), score=source_node.score, node_id=source_node.id_)
  57. for source_node in response.source_nodes
  58. ]
  59. tools: List[Resource] = [
  60. Resource(content=source.content, node_id=source.tool_name) for source in response.sources
  61. ]
  62. resources.extend(tools)
  63. return Message(content=response.response, sources=resources)
  64. else:
  65. return Message(content="I'm sorry, I don't have an answer for you.")
  66. async def main() -> None:
  67. runtime = SingleThreadedAgentRuntime()
  68. # setup llamaindex
  69. llm = AzureOpenAI(
  70. deployment_name=os.environ.get("AZURE_OPENAI_MODEL", ""),
  71. temperature=0.0,
  72. api_key=os.environ.get("AZURE_OPENAI_KEY", ""),
  73. azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT", ""),
  74. api_version=os.environ.get("AZURE_OPENAI_API_VERSION", ""),
  75. )
  76. embed_model = AzureOpenAIEmbedding(
  77. deployment_name=os.environ.get("AZURE_OPENAI_EMBEDDING_MODEL", ""),
  78. temperature=0.0,
  79. api_key=os.environ.get("AZURE_OPENAI_KEY", ""),
  80. azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT", ""),
  81. api_version=os.environ.get("AZURE_OPENAI_API_VERSION", ""),
  82. )
  83. Settings.llm = llm
  84. Settings.embed_model = embed_model
  85. # create a react agent to use wikipedia tool
  86. # Get the wikipedia tool spec for llamaindex agents
  87. wiki_spec = WikipediaToolSpec()
  88. wikipedia_tool = wiki_spec.to_tool_list()[1]
  89. # create a memory buffer for the react agent
  90. memory = ChatSummaryMemoryBuffer(llm=llm, token_limit=16000)
  91. # create the agent using the ReAct agent pattern
  92. llama_index_agent = ReActAgent.from_tools(
  93. tools=[wikipedia_tool], llm=llm, max_iterations=8, memory=memory, verbose=True
  94. )
  95. await runtime.register(
  96. "chat_agent",
  97. lambda: LlamaIndexAgent("Chat agent", llama_index_agent=llama_index_agent),
  98. )
  99. agent = AgentId("chat_agent", key="default")
  100. runtime.start()
  101. # Send a message to the agent and get the response.
  102. message = Message(content="What are the best movies from studio Ghibli?")
  103. response = await runtime.send_message(message, agent)
  104. assert isinstance(response, Message)
  105. print(response.content)
  106. if response.sources is not None:
  107. for source in response.sources:
  108. print(source.content)
  109. await runtime.stop()
  110. if __name__ == "__main__":
  111. import logging
  112. logging.basicConfig(level=logging.WARNING)
  113. logging.getLogger("agnext").setLevel(logging.DEBUG)
  114. asyncio.run(main())