TwoAgentDebateWithTools

Open in ColabOpen in GitHub

Overview

This example demonstrates how to simulate multi-agent conversations where agents have access to tools. The agents interact with each other to engage in logical debates on a given topic, utilizing tools to search for information or perform calculations as needed. Through this, you can gain a practical understanding of integrating agents and tools within LangChain.

Table of Contents

References


Environment Setup

Setting up your environment is the first step. See the Environment Setup guide for more details.

[Note]

The langchain-opentutorial is a package of easy-to-use environment setup guidance, useful functions and utilities for tutorials. Check out the langchain-opentutorial for more details.

You can set API keys in a .env file or set them manually.

[Note] If you’re not using the .env file, no worries! Just enter the keys directly in the cell below, and you’re good to go.

How to Set Up Tavily Search

DialogueAgent and DialogueSimulator

In this simulation, the Moderator Agent and Participant Agents interact to operate effectively.

  • Role Descriptions

    1. Moderator Agent (Agent with authority)

      • Primary Role: Manages speaking turns and coordinates interactions.

      • Characteristics:

        • A central management agent with special authority.

        • Decides when participant agents can speak or act.

      • Example: Similar to a moderator in a meeting assigning speaking turns to participants.

    2. Participant Agents

      • Primary Role: Act or speak according to the instructions from the moderator agent.

      • Characteristics:

        • Do not decide speaking turns independently.

        • Collaborate and participate in activities as directed by the moderator.

  • System Features

    • Centralized Management:

      • The moderator agent coordinates all speaking turns and actions.

      • In contrast to a decentralized system, where all agents self-coordinate.

    This simulation exemplifies a centrally managed approach to speaking and action coordination.

DialogueAgent

The DialogueAgent class manages conversations by setting the agent's name, system message, and language model (ChatOpenAI). The primary methods of the class are as follows:

  • send Method

    • Role:

      • Constructs messages using the current conversation history (message_history) and the agent's name prefix (prefix).

      • The prefix serves as an identifier that includes the agent's name, helping to structure conversation history and organize input formatting for the model.

      • Sends the constructed message to the language model (ChatOpenAI) and returns the generated response.

    • How it works:

      1. Combines the current conversation history (message_history) with the prefix (prefix) to create a single message.

      2. Sends the constructed message to the language model (ChatOpenAI).

      3. Returns the response message generated by the language model.

  • receive Method

    • Role:

      • Adds a message sent by another agent (or user) and the speaker's name to the conversation history.

      • This conversation history is used when the send method is called later.

    • How it works:

      1. Combines the speaker's name (name) and the message (message) into a single line of conversation.

      2. Adds the combined message to the conversation history (message_history).

  • reset Method

    • Role:

      • Resets the conversation history.

      • When reset, it is initialized with a default message: "Here is the conversation so far."

    • How it works:

      1. Resets the conversation history (message_history) to an empty list.

      2. Adds the default message "Here is the conversation so far." to the conversation history.

DialogueSimulator

The DialogueSimulator class coordinates and manages conversations among multiple agents. It simulates interactions between individual DialogueAgent instances, controlling the flow of dialogue and message delivery.

Methods

  • inject Method

    • Purpose:

      • Initiates a conversation with a given name and message.

      • Ensures all agents receive the message.

      • Typically used to set the initial message of a dialogue.

    • How it works:

      1. Delivers the name and message to all agents.

      2. Increments the simulation step (_step) by 1.

  • step Method

    • Purpose:

      • Progresses the simulation by selecting the next speaker and continuing the conversation.

      • The selected speaker generates a message, which is then distributed to all other agents.

    • How it works:

      1. Uses selection_function to determine the next speaker.

      2. The chosen speaker (speaker) generates a message by calling its send method.

      3. All agents receive the speaker's message.

      4. Increments the simulation step (_step) by 1.

      5. Returns the speaker's name and the generated message.

DialogueAgentWithTools

DialogueAgentWithTools extends the DialogueAgent class, adding support for external tools. This class integrates an OpenAI model with external tools to handle both conversational and task-processing functionalities.

Methods

  • __init__ Method

    • Purpose:

      • Initializes the agent with its name, system message, model, and a list of external tools.

    • How it works:

      1. Calls super().__init__ to initialize the base settings (name, system message, model).

      2. Stores the list of tools in self.tools.

  • send Method

    • Purpose:

      • Processes messages using an agent that integrates the OpenAI model and external tools.

      • Generates a response by leveraging the conversation history and available tools.

    • How it works:

      1. Uses hub.pull to retrieve the required prompt for agent execution.

      2. Calls create_openai_tools_agent to initialize an agent that integrates the OpenAI model and tools.

      3. Executes the agent using AgentExecutor to process the input message.

      4. Combines the system message, prefix, and conversation history (message_history) into an input message.

      5. Extracts the output from the execution result and creates an AIMessage object to return the content.

  • create_openai_tools_agent Function

    • Purpose:

      • Combines the OpenAI model and external tools to create a functional agent.

      • The agent is capable of leveraging tools for performing tasks.

    • How it works:

      1. Initializes the agent by integrating the OpenAI model with the provided tools.

      2. Configures the agent's behavior and rules using a supplied prompt.

      3. Ensures the agent can call tools and handle their results as part of its operation.

Tool Configuration

Document Search Tool Setup

This code demonstrates the process of setting up a tool to search for documents containing arguments for and against medical school expansion. Using the langchain package, it loads, splits, vectorizes documents, and creates a search tool.

  • Document Loading and Splitting

    • Role:

      • Loads text files and splits the documents into manageable chunks.

    • How it works:

      1. Uses TextLoader to load text files:

        • data/Opposition_to_Medical_School_Expansion.txt: Document with opposing arguments.

        • data/Support_for_Medical_School_Expansion.txt: Document with supporting arguments.

      2. Splits the documents into chunks of 1000 characters with an overlap of 100 characters using RecursiveCharacterTextSplitter.

  • Creating a VectorStore

    • Role:

      • Vectorizes document content for searchability.

    • How it works:

      1. Uses OpenAIEmbeddings to embed the document text.

      2. Creates a vector store using FAISS:

        • vector1: Based on the opposing arguments document.

        • vector2: Based on the supporting arguments document.

  • Creating Retrievers

    • Role:

      • Provides functionality to search for similar documents using the vector store.

    • How it works:

      1. Calls vector1.as_retriever() and vector2.as_retriever() to create retrievers.

      2. Configures each retriever to return the top 5 most similar documents (k=5).

  • Creating Search Tools

    • Role:

      • Defines search retrievers as tools for external use.

    • How it works:

      1. Uses create_retriever_tool to create search tools:

        • doctor_retriever_tool: Tool for searching opposing argument documents.

        • gov_retriever_tool: Tool for searching supporting argument documents.

      2. Adds a name and description to each tool to clarify its purpose.

Internet Search Tool

Web Search Tool: Tavily Search

LangChain provides a built-in tool to easily use the Tavily search engine. Tavily Search is a powerful feature for searching relevant data on the web and returning search results.

Document-Based Tool Setup

  • names: Defines the names (prefixes) of each debater and the tools they can use.

    • "Doctor Union": Tools available to the Doctor Union agent (e.g., doctor_retriever_tool).

    • "Government": Tools available to the Government agent (e.g., gov_retriever_tool).

  • topic: Specifies the debate topic.

    • Example: "As of 2024, is expanding medical school enrollment in South Korea necessary?"

  • word_limit: Sets a word limit for descriptions used by the agents.

Search-Based Tool Setup

  • names_search: Assigns search-based tools to debaters.

    • "Doctor Union" and "Government" are configured to use the search tool (search).

  • topic and word_limit are set the same as in the document-based setup.

Generating Participant Descriptions Using LLM

This code utilizes an LLM (Large Language Model) to create detailed descriptions for participants in a conversation. Based on the given topic and participant information, the LLM generates descriptions that include each participant's perspective and role.

  • conversation_description

    • Purpose:

      • Creates a conversation description based on the discussion topic (topic) and participant names (names).

      • Serves as input text to provide the initial settings of the conversation to the LLM.

    • How it works:

      1. Combines the topic and participant names into a description string.

      2. Example: Here is the topic of conversation: [topic]. The participants are: [Participant1, Participant2, ...].

  • agent_descriptor_system_message

    • Purpose:

      • Provides instructions to the LLM to "add detailed descriptions for participants."

      • A system message used as a guide when generating participant descriptions.

  • generate_agent_description Function

    • Purpose:

      • Generates a description for a specific participant (name) using the LLM.

      • Creates a tailored description that includes the participant's perspective and role.

    • How it works:

      1. Creates the agent_specifier_prompt:

        • Includes the conversation description (conversation_description), participant name (name), and word limit (word_limit).

        • Asks the LLM to generate a professional and concise description.

      2. Calls the ChatOpenAI model to generate the description.

      3. Returns the generated description (agent_description).

  • agent_descriptions

    • Purpose:

      • A dictionary that stores descriptions for all participants.

    • How it works:

      1. Calls the generate_agent_description function for each participant name.

      2. Stores the generated description along with the name in the dictionary.

      3. Result format: {'Participant1': 'Description1', 'Participant2': 'Description2', ...}.

You can write a brief statement explaining the stance of each debater directly.

Global System Message Configuration

The System Message defines the roles and conversational rules for each agent in an interactive AI system. This code clarifies the behavior guidelines and goals that agents must follow during the conversation.

Components

  • generate_system_message Function

    • Purpose:

      • Creates a system message defining an agent's behavior guidelines based on its name (name), description (description), and tools (tools).

    • How it works:

      1. Composes a basic conversation setup, including the agent's name and description.

      2. Specifies rules for the agent:

        • DO:

          • Use tools to retrieve information.

          • Counter arguments from the opposing agent and cite sources.

        • DO NOT:

          • Generate fake citations or reference unverified sources.

          • Repeat points already mentioned.

      3. Instructs the agent to respond in Korean and stop speaking after completing its point of view.

      4. Returns the final system message.

  • agent_system_messages Dictionary

    • Purpose:

      • Stores the system messages generated for all agents.

    • How it works:

      1. Combines names (agent names and tools) with agent_descriptions (agent descriptions).

      2. Calls generate_system_message for each agent to create a system message.

      3. Stores the resulting messages in a dictionary, using agent names as keys.

  • System Message Output

    • Purpose:

      • Displays the generated system messages for verification.

    • How it works:

      1. Iterates through the agent_system_messages dictionary.

      2. Prints each agent's name and its corresponding system message.

topic_specifier_prompt

The topic_specifier_prompt is code that generates a prompt to make the given conversation topic more specific. It utilizes an LLM (Large Language Model) to refine the initial topic and create a clear topic to be conveyed to the conversation participants.

  • topic_specifier_prompt

    • Role:

      • Generates a prompt that includes the necessary instructions to specify the topic.

    • Composition:

      1. SystemMessage:

        • Provides the LLM with instructions to "make the topic more specific."

      2. HumanMessage:

        • Includes the initial topic (topic) and participant names (names), requesting the topic to be specified within 100 words.

        • Requires the response to be written in Korean.

  • ChatOpenAI

    • Role:

      • Takes the topic_specifier_prompt as input and generates a more detailed topic.

    • Parameters:

      • temperature=1.0:

        • Configures the model to generate more creative and varied topics.

  • Topic Specification Results

    • Original topic: Outputs the initial topic.

    • Detailed topic: Outputs the topic refined by the LLM.

Or, you can specify it directly as follows.

Agent Creation and Integration

This code creates and integrates agents to be used in the debate simulation. Each agent is based on the DialogueAgentWithTools class and is equipped to explore evidence and present counterarguments using tools.

Components

  • agents

    • Purpose:

      • Creates the base agents for the simulation.

      • Each agent is configured with a name, system message, model, and tools.

    • How it works:

      1. Iterates through names and agent_system_messages.

      2. Initializes an instance of DialogueAgentWithTools for each participant.

      3. Adds the created agents to the agents list.

  • agents_with_search

    • Purpose:

      • Creates additional agents equipped with search tools.

    • How it works:

      1. Iterates through names_search and agent_system_messages.

      2. Initializes DialogueAgentWithTools instances with search functionality.

      3. Adds the created agents to the agents_with_search list.

  • Agent Integration

    • Purpose:

      • Combines agents and agents_with_search into a unified list for the simulation.

    • How it works:

      1. Calls agents.extend(agents_with_search) to merge the two lists.

      2. The unified agents list contains all participants, equipped with the required tools and functionalities.

The select_next_speaker function is responsible for selecting the next speaker.

Debate Execution

This code runs and manages a conversation between agents using the DialogueSimulator. The debate is based on a specified topic and participating agents, with each step outputting the speaker and their message.

Components

  • max_iters

    • Purpose:

      • Sets the maximum number of dialogue iterations.

      • Here, max_iters=3 limits the conversation to 3 exchanges.

  • simulator

    • Purpose:

      • An instance of the DialogueSimulator class that manages the flow of dialogue and message delivery.

    • Initialization:

      1. agents: The list of agents participating in the conversation.

      2. select_next_speaker: A function to select the next speaker.

  • inject Method

    • Purpose:

      • Starts the conversation by injecting the specified topic through the "Moderator" agent.

    • How it works:

      1. Calls simulator.inject("Moderator", specified_topic) to inject the topic.

      2. The "Moderator" presents the topic, initiating the dialogue.

      3. Outputs the topic:

        • print(f"(Moderator): {specified_topic}").

  • step Method

    • Purpose:

      • Executes one step of the simulation, generating a speaker and their message.

    • How it works:

      1. Calls simulator.step() to select the next speaker.

      2. The selected speaker generates a message, which all agents receive.

      3. Returns the speaker's name (name) and message (message).

      4. Outputs the speaker and message:

        • print(f"({name}): {message}").

  • Repeat Loop

    • Purpose:

      • Uses a while loop to continue the conversation up to max_iters times.

    • How it works:

      1. Initializes n = 0 and increments n with each iteration.

      2. While n < max_iters, calls simulator.step() to continue the conversation.

      3. Outputs the speaker and message at each step.

Last updated