LangGraph Agents
Published: 2024-01-28 05:48:30

**LangGraph Agents**



pip install langchain langgraph 

langchain_openai langchainhub langsmith duckduckgo-search beautifulsoup4 gradio
export OPENAI_API_KEY=xxxxxxxxxx
export LANGCHAIN_API_KEY=xxxxxxxxxx

import functools, operator, requests, os, json
from bs4 import BeautifulSoup
from duckduckgo_search import DDGS
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_core.messages import BaseMessage, HumanMessage
from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langgraph.graph import StateGraph, END
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from typing import Annotated, Any, Dict, List, Optional, Sequence, TypedDict
import gradio as gr

# Set environment variables
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "LangGraph Research Agents"

# Initialize model
llm = ChatOpenAI(model="gpt-4-turbo-preview")

# 1. Define custom tools
@tool("internet_search", return_direct=False)
def internet_search(query: str) -> str:
    """Searches the internet using DuckDuckGo."""
    with DDGS() as ddgs:
        results = [r for r in ddgs.text(query, max_results=5)]
        return results if results else "No results found."

@tool("process_content", return_direct=False)
def process_content(url: str) -> str:
    """Processes content from a webpage."""
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')
    return soup.get_text()

tools = [internet_search, process_content]

# 2. Agents 
# Helper function for creating agents
def create_agent(llm: ChatOpenAI, tools: list, system_prompt: str):
    prompt = ChatPromptTemplate.from_messages([
        ("system", system_prompt),
        MessagesPlaceholder(variable_name="messages"),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
    ])
    agent = create_openai_tools_agent(llm, tools, prompt)
    executor = AgentExecutor(agent=agent, tools=tools)
    return executor

# Define agent nodes
def agent_node(state, agent, name):
    result = agent.invoke(state)
    return {"messages": [HumanMessage(content=result["output"], name=name)]}

# Create Agent Supervisor
members = ["Web_Searcher", "Insight_Researcher"]
system_prompt = (
    "As a supervisor, your role is to oversee a dialogue between these"
    " workers: {members}. Based on the user's request,"
    " determine which worker should take the next action. Each worker is responsible for"
    " executing a specific task and reporting back their findings and progress. Once all tasks are complete,"
    " indicate with 'FINISH'."
)

options = ["FINISH"] + members
function_def = {
    "name": "route",
    "description": "Select the next role.",
    "parameters": {
        "title": "routeSchema",
        "type": "object",
        "properties": {"next": {"title": "Next", "anyOf": [{"enum": options}] }},
        "required": ["next"],
    },
}

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    MessagesPlaceholder(variable_name="messages"),
    ("system", "Given the conversation above, who should act next? Or should we FINISH? Select one of: {options}"),
]).partial(options=str(options), members=", ".join(members))

supervisor_chain = (prompt | llm.bind_functions(functions=[function_def], function_call="route") | JsonOutputFunctionsParser())

search_agent = create_agent(llm, tools, "You are a web searcher. Search the internet for information.")
search_node = functools.partial(agent_node, agent=search_agent, name="Web_Searcher")

insights_research_agent = create_agent(llm, tools, 
        """You are a Insight Researcher. Do step by step. 
        Based on the provided content first identify the list of topics,
        then search internet for each topic one by one
        and finally find insights for each topic one by one.
        Include the insights and sources in the final response
        """)
insights_research_node = functools.partial(agent_node, agent=insights_research_agent, name="Insight_Researcher")

# Define the Agent State, Edges and Graph
class AgentState(TypedDict):
    messages: Annotated[Sequence[BaseMessage], operator.add]
    next: str

workflow = StateGraph(AgentState)
workflow.add_node("Web_Searcher", search_node)
workflow.add_node("Insight_Researcher", insights_research_node)
workflow.add_node("supervisor", supervisor_chain)

# Define edges
for member in members:
    workflow.add_edge(member, "supervisor")

conditional_map = {k: k for k in members}
conditional_map["FINISH"] = END
workflow.add_conditional_edges("supervisor", lambda x: x["next"], conditional_map)
workflow.set_entry_point("supervisor")

graph = workflow.compile()

# Run the graph
for s in graph.stream({
    "messages": [HumanMessage(content="""Search for the latest AI technology trends in 2024,
            summarize the content. After summarise pass it on to insight researcher
            to provide insights for each topic""")]
}):
    if "__end__" not in s:
        print(s)
        print("----")

# final_response = graph.invoke({
#     "messages": [HumanMessage(
#         content="""Search for the latest AI technology trends in 2024,
#                 summarize the content
#                 and provide insights for each topic.""")]
# })

# print(final_response['messages'][1].content)

User Interface

import functools, operator, requests, os, json
from bs4 import BeautifulSoup
from duckduckgo_search import DDGS
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_core.messages import BaseMessage, HumanMessage
from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langgraph.graph import StateGraph, END
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from typing import Annotated, Any, Dict, List, Optional, Sequence, TypedDict
import gradio as gr

# Set environment variables
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "LangGraph Research Agents"

# Initialize model
llm = ChatOpenAI(model="gpt-4-turbo-preview")

# Define custom tools
@tool("internet_search", return_direct=False)
def internet_search(query: str) -> str:
    """Searches the internet using DuckDuckGo."""
    with DDGS() as ddgs:
        results = [r for r in ddgs.text(query, max_results=5)]
        return results if results else "No results found."

@tool("process_content", return_direct=False)
def process_content(url: str) -> str:
    """Processes content from a webpage."""
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')
    return soup.get_text()

tools = [internet_search, process_content]

# Helper function for creating agents
def create_agent(llm: ChatOpenAI, tools: list, system_prompt: str):
    prompt = ChatPromptTemplate.from_messages([
        ("system", system_prompt),
        MessagesPlaceholder(variable_name="messages"),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
    ])
    agent = create_openai_tools_agent(llm, tools, prompt)
    executor = AgentExecutor(agent=agent, tools=tools)
    return executor

# Define agent nodes
def agent_node(state, agent, name):
    result = agent.invoke(state)
    return {"messages": [HumanMessage(content=result["output"], name=name)]}

# Create Agent Supervisor
members = ["Web_Searcher", "Insight_Researcher"]
system_prompt = (
    "As a supervisor, your role is to oversee a dialogue between these"
    " workers: {members}. Based on the user's request,"
    " determine which worker should take the next action. Each worker is responsible for"
    " executing a specific task and reporting back their findings and progress. Once all tasks are complete,"
    " indicate with 'FINISH'."
)

options = ["FINISH"] + members
function_def = {
    "name": "route",
    "description": "Select the next role.",
    "parameters": {
        "title": "routeSchema",
        "type": "object",
        "properties": {"next": {"title": "Next", "anyOf": [{"enum": options}] }},
        "required": ["next"],
    },
}

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    MessagesPlaceholder(variable_name="messages"),
    ("system", "Given the conversation above, who should act next? Or should we FINISH? Select one of: {options}"),
]).partial(options=str(options), members=", ".join(members))

supervisor_chain = (prompt | llm.bind_functions(functions=[function_def], function_call="route") | JsonOutputFunctionsParser())

# Define the Agent State and Graph
class AgentState(TypedDict):
    messages: Annotated[Sequence[BaseMessage], operator.add]
    next: str

search_agent = create_agent(llm, tools, "You are a web searcher. Search the internet for information.")
search_node = functools.partial(agent_node, agent=search_agent, name="Web_Searcher")

insights_research_agent = create_agent(llm, tools, 
        """You are a Insight Researcher. Do step by step. 
        Based on the provided content first identify the list of topics,
        then search internet for each topic one by one
        and finally find insights for each topic one by one.
        Include the insights and sources in the final response
        """)
insights_research_node = functools.partial(agent_node, agent=insights_research_agent, name="Insight_Researcher")

workflow = StateGraph(AgentState)
workflow.add_node("Web_Searcher", search_node)
workflow.add_node("Insight_Researcher", insights_research_node)
workflow.add_node("supervisor", supervisor_chain)

# Define edges
for member in members:
    workflow.add_edge(member, "supervisor")

conditional_map = {k: k for k in members}
conditional_map["FINISH"] = END
workflow.add_conditional_edges("supervisor", lambda x: x["next"], conditional_map)
workflow.set_entry_point("supervisor")

graph = workflow.compile()

# Run the graph
def run_graph(input_message):
    response = graph.invoke({
        "messages": [HumanMessage(content=input_message)]
    })
    return json.dumps(response['messages'][1].content, indent=2)

inputs = gr.inputs.Textbox(lines=2, placeholder="Enter your query here...")
outputs = gr.outputs.Textbox()

demo = gr.Interface(fn=run_graph, inputs=inputs, outputs=outputs)
demo.launch()

Prompt

Search for the latest AI technology trends in 2024, summarise the content. After summarising pass it on to insight researcher to provide insights for each topic

Output

Let’s delve into insights derived from the latest findings on AI technology trends for 2024:

1. Multimodal AI

    Insight: Multimodal AI’s growth to a $4.5 billion market by 2028 underscores a significant shift towards AI systems that can handle a variety of inputs like text, images, and audio, akin to human sensory processing. This indicates a move towards more natural and intuitive AI-human interactions.
    Sources: B12, Unite.AI

2. Agentic AI

    Insight: The emergence of AI systems capable of autonomous action without direct supervision highlights a trend towards AI that can independently pursue complex goals. This could dramatically enhance efficiency in various sectors by enabling AI to take on more proactive roles.
    Sources: GREY Journal, OpenAI

3. Open Source AI

    Insight: Google’s partnership with Hugging Face to provide open-source AI tools on its cloud platform exemplifies the growing trend of democratizing AI technology. This movement aims to make powerful AI tools more accessible, fostering innovation across the board.
    Sources: The Verge, TechRepublic

4. Retrieval-Augmented Generation (RAG)

    Insight: RAG’s integration with fine-tuning methods tailored to specific industries, like agriculture, suggests a push towards making AI-generated content more accurate and relevant. This could significantly benefit sectors where factual precision is paramount.
    Sources: Marktechpost, NVIDIA Blog

5. Customized Enterprise Generative AI Models

    Insight: Enterprises are increasingly favoring customized generative AI models tailored with proprietary data, indicating a shift from one-size-fits-all solutions to more specific, efficient, and cost-effective AI applications.
    Sources: Deloitte US, TechTarget

6. Quantum AI

    Insight: The integration of AI with quantum computing, as seen in Microsoft’s Azure Quantum Elements, signifies a pursuit of breakthrough capabilities in complex problem-solving, potentially revolutionizing fields like drug discovery and climate modeling.
    Sources: Microsoft, AIMultiple

7. AI Legislation

    Insight: The momentum towards comprehensive AI policies, highlighted by actions such as President Biden’s executive order, reflects a growing recognition of the need to balance AI innovation with ethical considerations and societal protections.
    Sources: MIT Technology Review, Scale

8. Ethical AI

    Insight: The focus on developing AI systems that are transparent, fair, and accountable is becoming increasingly prominent. This trend towards ethical AI is driven by a global effort to ensure AI’s growth benefits society as a whole.
    Sources: UNESCO, Forbes

9. Augmented Working

    Insight: The concept of Augmented Working emphasizes a synergistic relationship between human capabilities and AI’s potential. This trend suggests a future where AI not only assists but enhances human work across various sectors.
    Sources: Medium, Forbes

10. Next Generation of Generative AI

    Insight: The evolution towards multi-modal generative AI systems capable of creating complex, multi-faceted outputs signals a future where AI can produce content that rivals human creativity, potentially transforming the landscape of content creation.
    Sources: Forbes, MIT Technology Review

These insights provide a deeper understanding of the potential impacts and opportunities associated with each of the AI technology trends for 2024.
Categories