■ create_react_agent 함수를 사용해 CompiledStateGraph 객체를 만들고 CHROMA 벡터 저장소를 검색하는 방법을 보여준다.
※ OPENAI_API_KEY 환경 변수 값은 .env 파일에 정의한다.
▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
import bs4 from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_community.document_loaders import WebBaseLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_chroma import Chroma from langchain_openai import OpenAIEmbeddings from langchain.tools.retriever import create_retriever_tool from langgraph.checkpoint.memory import MemorySaver from langgraph.prebuilt import create_react_agent from langchain_core.messages import HumanMessage load_dotenv() chatOpenAI = ChatOpenAI(model = "gpt-4o") webBaseLoader = WebBaseLoader( web_paths = ("https://lilianweng.github.io/posts/2023-06-23-agent/",), bs_kwargs = dict(parse_only = bs4.SoupStrainer(class_ = ("post-content", "post-title", "post-header"))) ) documentList = webBaseLoader.load() recursiveCharacterTextSplitter = RecursiveCharacterTextSplitter(chunk_size = 1000, chunk_overlap = 200) splitDocumentList = recursiveCharacterTextSplitter.split_documents(documentList) openAIEmbeddings = OpenAIEmbeddings() chroma = Chroma.from_documents(documents = splitDocumentList, embedding = openAIEmbeddings) vectorStoreRetriever = chroma.as_retriever() tool = create_retriever_tool( vectorStoreRetriever, "blog_post_retriever", "Searches and returns excerpts from the Autonomous Agents blog post.", ) toolList = [tool] memorySaver = MemorySaver() compiledStateGraph = create_react_agent(chatOpenAI, toolList, checkpointer = memorySaver) configurableDictionary = {"configurable" : {"thread_id" : "abc123"}} for addableUpdatesDict in compiledStateGraph.stream( {"messages" : [HumanMessage(content = "Hi! I'm bob")]}, config = configurableDictionary ): print(addableUpdatesDict) print("-" * 10) print("-" * 50) for addableUpdatesDict in compiledStateGraph.stream( {"messages" : [HumanMessage(content = "What is Task Decomposition?")]}, config = configurableDictionary ): print(addableUpdatesDict) print("-" * 10) print("-" * 50) for addableUpdatesDict in compiledStateGraph.stream( {"messages" : [HumanMessage(content = "What according to the blog post are common ways of doing it? redo the search")]}, config = configurableDictionary ): print(addableUpdatesDict) print("-" * 10) print("-" * 50) """ {'agent': {'messages': [AIMessage(content='Hello Bob! How can I assist you today?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 64, 'total_tokens': 75, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-2024-08-06', 'system_fingerprint': 'fp_831e067d82', 'finish_reason': 'stop', 'logprobs': None}, id='run-ebcf4411-f53c-4226-abf7-05919f78696a-0', usage_metadata={'input_tokens': 64, 'output_tokens': 11, 'total_tokens': 75, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}} ---------- -------------------------------------------------- {'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_xSXsCQowPtOKcHNk2n5keQrH', 'function': {'arguments': '{"query":"Task Decomposition"}', 'name': 'blog_post_retriever'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 88, 'total_tokens': 107, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-2024-08-06', 'system_fingerprint': 'fp_831e067d82', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-1f048552-b5e6-43cc-a296-fbd61f5b1f52-0', tool_calls=[{'name': 'blog_post_retriever', 'args': {'query': 'Task Decomposition'}, 'id': 'call_xSXsCQowPtOKcHNk2n5keQrH', 'type': 'tool_call'}], usage_metadata={'input_tokens': 88, 'output_tokens': 19, 'total_tokens': 107, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}} ---------- {'tools': {'messages': [ToolMessage(content='Fig. 1. Overview of a LLM-powered autonomous agent system.\nComponent One: Planning#\nA complicated task usually involves many steps. An agent needs to know what they are and plan ahead.\nTask Decomposition#\nChain of thought (CoT; Wei et al. 2022) has become a standard prompting technique for enhancing model performance on complex tasks. The model is instructed to “think step by step” to utilize more test-time computation to decompose hard tasks into smaller and simpler steps. CoT transforms big tasks into multiple manageable tasks and shed lights into an interpretation of the model’s thinking process.\n\nTree of Thoughts (Yao et al. 2023) extends CoT by exploring multiple reasoning possibilities at each step. It first decomposes the problem into multiple thought steps and generates multiple thoughts per step, creating a tree structure. The search process can be BFS (breadth-first search) or DFS (depth-first search) with each state evaluated by a classifier (via a prompt) or majority vote.\nTask decomposition can be done (1) by LLM with simple prompting like "Steps for XYZ.\\n1.", "What are the subgoals for achieving XYZ?", (2) by using task-specific instructions; e.g. "Write a story outline." for writing a novel, or (3) with human inputs.\n\n(3) Task execution: Expert models execute on the specific tasks and log results.\nInstruction:\n\nWith the input and the inference results, the AI assistant needs to describe the process and results. The previous stages can be formed as - User Input: {{ User Input }}, Task Planning: {{ Tasks }}, Model Selection: {{ Model Assignment }}, Task Execution: {{ Predictions }}. You must first answer the user\'s request in a straightforward manner. Then describe the task process and show your analysis and model inference results to the user in the first person. If inference results contain a file path, must tell the user the complete file path.\n\nFig. 11. Illustration of how HuggingGPT works. (Image source: Shen et al. 2023)\nThe system comprises of 4 stages:\n(1) Task planning: LLM works as the brain and parses the user requests into multiple tasks. There are four attributes associated with each task: task type, ID, dependencies, and arguments. They use few-shot examples to guide LLM to do task parsing and planning.\nInstruction:', name='blog_post_retriever', id='287871db-d352-4790-bdd5-6c0bd7b5ab8a', tool_call_id='call_xSXsCQowPtOKcHNk2n5keQrH')]}} ---------- {'agent': {'messages': [AIMessage(content='Task Decomposition is a technique used to break down complex tasks into smaller, more manageable steps. This approach is often applied to enhance model performance on challenging tasks by utilizing a structured method of thinking. The concept is prominently featured in techniques like Chain of Thought (CoT) and Tree of Thoughts, which promote step-by-step reasoning and explore multiple reasoning possibilities to solve tasks effectively.\n\nIn Task Decomposition, large tasks are divided into sub-tasks, which can be processed individually. This can be achieved through various methods, including simple prompting with Large Language Models (LLMs), task-specific instructions, or human inputs. The decomposition facilitates better understanding and execution, making complex tasks easier to handle.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 138, 'prompt_tokens': 605, 'total_tokens': 743, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-2024-08-06', 'system_fingerprint': 'fp_831e067d82', 'finish_reason': 'stop', 'logprobs': None}, id='run-bef0b760-7d7a-4b3d-ab2a-1aace69b3a55-0', usage_metadata={'input_tokens': 605, 'output_tokens': 138, 'total_tokens': 743, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}} ---------- -------------------------------------------------- {'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_KDj2dCvLlrBV8M7ClXOritbL', 'function': {'arguments': '{"query":"common ways of Task Decomposition"}', 'name': 'blog_post_retriever'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 766, 'total_tokens': 788, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-2024-08-06', 'system_fingerprint': 'fp_831e067d82', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-e24f692e-bc52-4e07-b4f1-2c51aa09fe81-0', tool_calls=[{'name': 'blog_post_retriever', 'args': {'query': 'common ways of Task Decomposition'}, 'id': 'call_KDj2dCvLlrBV8M7ClXOritbL', 'type': 'tool_call'}], usage_metadata={'input_tokens': 766, 'output_tokens': 22, 'total_tokens': 788, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}} ---------- {'tools': {'messages': [ToolMessage(content='Tree of Thoughts (Yao et al. 2023) extends CoT by exploring multiple reasoning possibilities at each step. It first decomposes the problem into multiple thought steps and generates multiple thoughts per step, creating a tree structure. The search process can be BFS (breadth-first search) or DFS (depth-first search) with each state evaluated by a classifier (via a prompt) or majority vote.\nTask decomposition can be done (1) by LLM with simple prompting like "Steps for XYZ.\\n1.", "What are the subgoals for achieving XYZ?", (2) by using task-specific instructions; e.g. "Write a story outline." for writing a novel, or (3) with human inputs.\n\nFig. 1. Overview of a LLM-powered autonomous agent system.\nComponent One: Planning#\nA complicated task usually involves many steps. An agent needs to know what they are and plan ahead.\nTask Decomposition#\nChain of thought (CoT; Wei et al. 2022) has become a standard prompting technique for enhancing model performance on complex tasks. The model is instructed to “think step by step” to utilize more test-time computation to decompose hard tasks into smaller and simpler steps. CoT transforms big tasks into multiple manageable tasks and shed lights into an interpretation of the model’s thinking process.\n\nResources:\n1. Internet access for searches and information gathering.\n2. Long Term memory management.\n3. GPT-3.5 powered Agents for delegation of simple tasks.\n4. File output.\n\nPerformance Evaluation:\n1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n2. Constructively self-criticize your big-picture behavior constantly.\n3. Reflect on past decisions and strategies to refine your approach.\n4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n\n(3) Task execution: Expert models execute on the specific tasks and log results.\nInstruction:\n\nWith the input and the inference results, the AI assistant needs to describe the process and results. The previous stages can be formed as - User Input: {{ User Input }}, Task Planning: {{ Tasks }}, Model Selection: {{ Model Assignment }}, Task Execution: {{ Predictions }}. You must first answer the user\'s request in a straightforward manner. Then describe the task process and show your analysis and model inference results to the user in the first person. If inference results contain a file path, must tell the user the complete file path.', name='blog_post_retriever', id='108965fd-dd0b-4b5b-a454-b8a34f339404', tool_call_id='call_KDj2dCvLlrBV8M7ClXOritbL')]}} ---------- {'agent': {'messages': [AIMessage(content='According to the blog post, common ways of performing Task Decomposition include:\n\n1. **Using Large Language Models (LLMs) with Simple Prompting**: This involves direct prompts such as "Steps for XYZ.\\n1." or "What are the subgoals for achieving XYZ?" to guide the decomposition process.\n\n2. **Task-Specific Instructions**: Tailored instructions depending on the task, like "Write a story outline" when writing a novel, which helps in dividing the task into smaller components.\n\n3. **Human Inputs**: Involving humans to manually break down tasks into smaller, manageable parts.\n\nThese methods facilitate the breakdown of complex tasks into simpler steps, enhancing the model\'s performance and understanding.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 145, 'prompt_tokens': 1310, 'total_tokens': 1455, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-2024-08-06', 'system_fingerprint': 'fp_831e067d82', 'finish_reason': 'stop', 'logprobs': None}, id='run-45dede11-2405-45f6-be2e-2ff3736aba68-0', usage_metadata={'input_tokens': 1310, 'output_tokens': 145, 'total_tokens': 1455, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}} ---------- -------------------------------------------------- """ |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
aiohappyeyeballs==2.4.3 aiohttp==3.11.7 aiosignal==1.3.1 annotated-types==0.7.0 anyio==4.6.2.post1 asgiref==3.8.1 attrs==24.2.0 backoff==2.2.1 bcrypt==4.2.1 beautifulsoup4==4.12.3 bs4==0.0.2 build==1.2.2.post1 cachetools==5.5.0 certifi==2024.8.30 charset-normalizer==3.4.0 chroma-hnswlib==0.7.6 chromadb==0.5.20 click==8.1.7 colorama==0.4.6 coloredlogs==15.0.1 dataclasses-json==0.6.7 Deprecated==1.2.15 distro==1.9.0 durationpy==0.9 fastapi==0.115.5 filelock==3.16.1 flatbuffers==24.3.25 frozenlist==1.5.0 fsspec==2024.10.0 google-auth==2.36.0 googleapis-common-protos==1.66.0 greenlet==3.1.1 grpcio==1.68.0 h11==0.14.0 httpcore==1.0.7 httptools==0.6.4 httpx==0.27.2 httpx-sse==0.4.0 huggingface-hub==0.26.2 humanfriendly==10.0 idna==3.10 importlib_metadata==8.5.0 importlib_resources==6.4.5 jiter==0.8.0 jsonpatch==1.33 jsonpointer==3.0.0 kubernetes==31.0.0 langchain==0.3.8 langchain-chroma==0.1.4 langchain-community==0.3.8 langchain-core==0.3.21 langchain-openai==0.2.10 langchain-text-splitters==0.3.2 langgraph==0.2.53 langgraph-checkpoint==2.0.6 langgraph-sdk==0.1.36 langsmith==0.1.146 markdown-it-py==3.0.0 marshmallow==3.23.1 mdurl==0.1.2 mmh3==5.0.1 monotonic==1.6 mpmath==1.3.0 msgpack==1.1.0 multidict==6.1.0 mypy-extensions==1.0.0 numpy==1.26.4 oauthlib==3.2.2 onnxruntime==1.20.1 openai==1.55.1 opentelemetry-api==1.28.2 opentelemetry-exporter-otlp-proto-common==1.28.2 opentelemetry-exporter-otlp-proto-grpc==1.28.2 opentelemetry-instrumentation==0.49b2 opentelemetry-instrumentation-asgi==0.49b2 opentelemetry-instrumentation-fastapi==0.49b2 opentelemetry-proto==1.28.2 opentelemetry-sdk==1.28.2 opentelemetry-semantic-conventions==0.49b2 opentelemetry-util-http==0.49b2 orjson==3.10.12 overrides==7.7.0 packaging==24.2 posthog==3.7.3 propcache==0.2.0 protobuf==5.28.3 pyasn1==0.6.1 pyasn1_modules==0.4.1 pydantic==2.10.2 pydantic-settings==2.6.1 pydantic_core==2.27.1 Pygments==2.18.0 PyPika==0.48.9 pyproject_hooks==1.2.0 pyreadline3==3.5.4 python-dateutil==2.9.0.post0 python-dotenv==1.0.1 PyYAML==6.0.2 regex==2024.11.6 requests==2.32.3 requests-oauthlib==2.0.0 requests-toolbelt==1.0.0 rich==13.9.4 rsa==4.9 shellingham==1.5.4 six==1.16.0 sniffio==1.3.1 soupsieve==2.6 SQLAlchemy==2.0.35 starlette==0.41.3 sympy==1.13.3 tenacity==9.0.0 tiktoken==0.8.0 tokenizers==0.20.4 tqdm==4.67.1 typer==0.13.1 typing-inspect==0.9.0 typing_extensions==4.12.2 urllib3==2.2.3 uvicorn==0.32.1 watchfiles==1.0.0 websocket-client==1.8.0 websockets==14.1 wrapt==1.17.0 yarl==1.18.0 zipp==3.21.0 |
※ pip install python-dotenv langchain langchain-community langchain-openai langchain_chroma langgraph bs4 명령을 실행했다.