I’m trying to get comfortable with LangGraph in an attempt to then develop a chatbot based on this framework.
When trying to test the idea of a node in my chatbot, I found myself faced with this error.
Could somebody please help me understand what’s wrong with my code and how can I solve this problem?
I would be truly thankful!
The code:
<code>from typing import Annotated, List
from langchain_openai import ChatOpenAI
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.messages import BaseMessage
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
# Define AgentState class with the proper typing
class AgentState(TypedDict):
messages: Annotated[List[BaseMessage], add_messages]
# Initialize the tool and LLM
tool = TavilySearchResults(max_results=3)
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
llm_with_tools = llm.bind_tools(tools)
# Define the function for the game title search
def game_title_search(state: AgentState):
game_search_prompt = PromptTemplate(
template="""You are part of a chatbot that provides personalized video game recommendations based on user preferences. n
Your task is to search for video games that match the user query, using the Tavily API. n
Only return the titles of the games. n
The number of games to return is limited to 5. nn
The results provided will look as follows (Python list): n
['game_title_1', 'game_title_2', 'game_title_3', ...]
input_variables=["query"],
game_search = game_search_prompt | llm_with_tools
game_search_result = game_search.invoke({"query": state["query"]})
return {"messages": [game_search_result]} # Also, I need to extract the game titles from the tool result and update the state attribute "games" - how can I do this?
graph_builder = StateGraph(AgentState)
graph_builder.add_node("game_search", game_title_search)
tool_node = ToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges(
graph_builder.add_edge("tools", "game_search")
graph_builder.set_entry_point("game_search")
graph = graph_builder.compile()
# Define the initial state
user_input = "What games are similar to The Witcher 3?"
input_state["query"] = user_input
input_state["messages"] = [("user", user_input)]
output = graph.invoke(input_state, config={"recursion_limit": 50})
<code>from typing import Annotated, List
from langchain_openai import ChatOpenAI
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.messages import BaseMessage
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
# Define AgentState class with the proper typing
class AgentState(TypedDict):
messages: Annotated[List[BaseMessage], add_messages]
query: str
games: List[str]
# Initialize the tool and LLM
tool = TavilySearchResults(max_results=3)
tools = [tool]
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
llm_with_tools = llm.bind_tools(tools)
# Define the function for the game title search
def game_title_search(state: AgentState):
game_search_prompt = PromptTemplate(
template="""You are part of a chatbot that provides personalized video game recommendations based on user preferences. n
Your task is to search for video games that match the user query, using the Tavily API. n
Only return the titles of the games. n
The number of games to return is limited to 5. nn
The results provided will look as follows (Python list): n
['game_title_1', 'game_title_2', 'game_title_3', ...]
User Query: {query}""",
input_variables=["query"],
)
game_search = game_search_prompt | llm_with_tools
game_search_result = game_search.invoke({"query": state["query"]})
return {"messages": [game_search_result]} # Also, I need to extract the game titles from the tool result and update the state attribute "games" - how can I do this?
# Build the graph
graph_builder = StateGraph(AgentState)
graph_builder.add_node("game_search", game_title_search)
tool_node = ToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges(
"game_search",
tools_condition,
)
graph_builder.add_edge("tools", "game_search")
graph_builder.set_entry_point("game_search")
graph = graph_builder.compile()
# Define the initial state
input_state = {
"messages": [],
"query": "",
"games": []
}
user_input = "What games are similar to The Witcher 3?"
input_state["query"] = user_input
input_state["messages"] = [("user", user_input)]
output = graph.invoke(input_state, config={"recursion_limit": 50})
print(output)
</code>
from typing import Annotated, List
from langchain_openai import ChatOpenAI
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
from langchain_core.messages import BaseMessage
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition
# Define AgentState class with the proper typing
class AgentState(TypedDict):
messages: Annotated[List[BaseMessage], add_messages]
query: str
games: List[str]
# Initialize the tool and LLM
tool = TavilySearchResults(max_results=3)
tools = [tool]
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
llm_with_tools = llm.bind_tools(tools)
# Define the function for the game title search
def game_title_search(state: AgentState):
game_search_prompt = PromptTemplate(
template="""You are part of a chatbot that provides personalized video game recommendations based on user preferences. n
Your task is to search for video games that match the user query, using the Tavily API. n
Only return the titles of the games. n
The number of games to return is limited to 5. nn
The results provided will look as follows (Python list): n
['game_title_1', 'game_title_2', 'game_title_3', ...]
User Query: {query}""",
input_variables=["query"],
)
game_search = game_search_prompt | llm_with_tools
game_search_result = game_search.invoke({"query": state["query"]})
return {"messages": [game_search_result]} # Also, I need to extract the game titles from the tool result and update the state attribute "games" - how can I do this?
# Build the graph
graph_builder = StateGraph(AgentState)
graph_builder.add_node("game_search", game_title_search)
tool_node = ToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)
graph_builder.add_conditional_edges(
"game_search",
tools_condition,
)
graph_builder.add_edge("tools", "game_search")
graph_builder.set_entry_point("game_search")
graph = graph_builder.compile()
# Define the initial state
input_state = {
"messages": [],
"query": "",
"games": []
}
user_input = "What games are similar to The Witcher 3?"
input_state["query"] = user_input
input_state["messages"] = [("user", user_input)]
output = graph.invoke(input_state, config={"recursion_limit": 50})
print(output)
What I was expecting was for the LLM chain to return back a Python list of the video games’ titles it fetched from the web-search operation, which was then supposed to be used in updating the state’s attribute “games”. But I can’t even think of a way of implementing that until I find a solution to this problem of mine.