THE SUMMARYAI-generated
Langraph Agent Crash Course: Building a Stock Screener
Key Concepts:
- Langraph: An agent framework that uses a graph structure to define agent behavior.
- Nodes: Represent individual steps or components in the agent's workflow (e.g., chatbot, tool).
- Edges: Define the flow of information and control between nodes.
- State: A dictionary containing information passed between nodes, updated using a reducer function.
- Memory: Allows the agent to retain information across multiple interactions.
- Tools: External functions or APIs that the agent can use to perform specific tasks.
- Conditional Edges (Router): Determine the next node to visit based on the current state.
- LLM Binding: Attaching tool descriptions to the LLM to enable tool usage.
1. Introduction to Langraph
- Langraph is presented as a powerful but complex agent framework.
- It offers features like human-in-the-loop interaction, tracing via Langsmith, and support for various LLMs and tools.
- The video aims to provide a crash course on building agents with Langraph by creating a stock screener.
- The analogy of cities (nodes) and highways (edges) is used to explain the graph structure.
2. Building a Simple Chatbot (Initial Setup)
- Dependencies: The following Python packages are imported:
typing.Annotated: For defining state with metadata.langraph.graph.start,langraph.graph.end,langraph.graph.StateGraph: For defining graph structure.langraph.graph.message.add_messages: A reducer function for updating the state.langraph.checkpoint.memory.InMemorySaver: For adding memory to the agent.langchain_llama.ChatLlama: For using a local LLM.colorama.Fore: For colored terminal output.yfinance: For accessing Yahoo Finance data.
- LLM Creation: A ChatLlama instance is created using the "quen-2.5-14b" model.
llm = ChatLlama(model="quen-2.5-14b") - State Definition: A
Stateclass is defined as a dictionary with a "messages" key.- The
Annotatedtype is used to specify that the "messages" key should be a list, and theadd_messagesreducer function is used to append new messages to this list.
class State(TypedDict): messages: Annotated[List[BaseMessage], add_messages] - The
- Chatbot Node: A
chatbotfunction is defined to represent the LLM node.- It takes the current
stateas input. - It invokes the LLM with the
state["messages"]to get a response. - It returns a dictionary containing the LLM's response as a message.
def chatbot(state): return {"messages": [llm.invoke(state["messages"])]} - It takes the current
- Graph Assembly: A
StateGraphinstance is created to represent the graph.- Nodes are added using
graph_builder.add_node(). - Edges are added using
graph_builder.add_edge(). - The initial graph consists of a "start" node, a "chatbot" node, and an "end" node, with edges connecting them in sequence.
graph_builder = StateGraph(State) graph_builder.add_node("chatbot", chatbot) graph_builder.add_edge("start", "chatbot") graph_builder.add_edge("chatbot", "end") - Nodes are added using
- Memory Addition: An
InMemorySaverinstance is created to enable memory.- The graph is compiled using
graph_builder.compile(), with thecheckpointargument set to theInMemorySaverinstance.
memory = InMemorySaver() graph = graph_builder.compile(checkpoint=memory) - The graph is compiled using
- Call Loop: A
while Trueloop is used to continuously prompt the user for input.- The user's input is formatted as a message and passed to the graph using
graph.invoke(). - The LLM's response is extracted from the result and printed to the console.
while True: prompt = input("Pass your prompt here: ") messages = [{"role": "user", "content": prompt}] result = graph.invoke({"messages": messages}) print(Fore.YELLOW + result["messages"][-1].content + Fore.RESET) - The user's input is formatted as a message and passed to the graph using
- Configurable: A
configis created to pass a thread ID to the agent.config = {"thread_id": "1234"}
3. Building a Tool: Yahoo Finance Stock Screener
- Dependencies: The following Python packages are imported:
langchain.tools.Tool: For creating custom tools.yfinance: For accessing Yahoo Finance data.json: For formatting the tool's output.
- Tool Definition: A
simple_screenerfunction is defined to perform stock screening using Yahoo Finance.- It takes
screen_type(string) andoffset(integer) as input. - It uses
yf.predefined_screener_queriesto retrieve a predefined screener query based on thescreen_type. - It uses
yf.screento execute the query and retrieve the results. - It formats the results into a string containing the stock's short name, bid, ask, exchange, 52-week high, 52-week low, average analyst rating, dividend yield, and symbol.
- It dumps the raw result to a JSON object.
@tool def simple_screener(screen_type: str, offset: int) -> str: """Returns screened assets or stocks, funds, bonds given a popular criteria.""" query = yf.predefined_screener_queries[screen_type]["query"] results = yf.screen(query, offset=offset, count=5) # ... (formatting logic) ... return f"Stock screener results: {output_data}" - It takes
- Tool Testing: The
simple_screenerfunction is tested with the "day_gainers" screen type and an offset of 0.- The results are printed to the console.
- The raw result is dumped to a JSON file named "output.json".
4. Integrating the Tool into the Langraph Agent
- Tool Import: The
simple_screenerfunction is imported into theflow.pyscript. - Tool List Creation: A list of tools is created, containing the
simple_screenerfunction.tools = [simple_screener] - LLM Binding: The LLM is bound to the tools using
llm.bind_tools(tools).- This provides the LLM with information about the available tools and how to use them.
llm_with_tools = llm.bind_tools(tools) - Chatbot Node Update: The
chatbotfunction is updated to use thellm_with_toolsinstance instead of the raw LLM.def chatbot(state): return {"messages": [llm_with_tools.invoke(state["messages"])]} - Tool Node Creation: A
ToolNodeinstance is created to represent the tool node in the graph.tool_node = ToolNode(tools=tools) - Router (Conditional Edge): A
routerfunction is defined to determine whether to call a tool or end the conversation.- It checks if the last message in the state contains a "tool_calls" key.
- If it does, it returns "tools" to indicate that the tool node should be visited.
- Otherwise, it returns "end" to indicate that the conversation should end.
def router(state): last_message = state["messages"][-1] if "tool_calls" in last_message and last_message["tool_calls"]: return "tools" else: return "end" - Graph Update: The graph is updated to include the tool node and the conditional edge.
- The
graph_builder.add_node()method is used to add the tool node. - The
graph_builder.add_conditional_edges()method is used to add a conditional edge that routes the conversation to either the tool node or the end node based on the output of the router function. - An edge is added from the tool node back to the chatbot node.
graph_builder.add_node("tools", tool_node) graph_builder.add_conditional_edges( "chatbot", router, {"tools": "tools", "end": "end"} ) graph_builder.add_edge("tools", "chatbot") - The
5. Running the Agent
- The
flow.pyscript is executed. - The user is prompted for input.
- The agent processes the input, potentially calling the stock screener tool.
- The results are printed to the console.
6. Conclusion
- The video demonstrates how to build a Langraph agent with memory and tool integration.
- The agent can be used to perform complex tasks, such as stock screening.
- Langraph provides a flexible and powerful framework for building sophisticated agents.
AI summaries can miss context or contain errors. Check important details against the original video.