imashutosh51

LangGraph

Feb 1st, 2026
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.12 KB | None | 0 0
  1. # Whenever you are calling the graph,argument should be a dictionary and dictinary as per the graphstate class args.
  2. #graph return the graph state only.
  3.  
  4.  
  5. from langgraph.prebuilt import ToolNode
  6. from langgraph.prebuilt import tools_condition
  7. tools=[add]
  8. graph=StateGraph(State)
  9. graph.add_node(llm_tool,"llm_tool")
  10. graph.add_node("tools",ToolNode(tools)) #It wraps the tools and make it langgraph compatible
  11.  
  12. graph.add_edge(START,"llm_tool")
  13. graph.add_conditional_edges(
  14.     "llm_tool",
  15.     tools_condition
  16. )
  17. graph.add_edge("tools",END)
  18. graph=graph.compile()
  19.  
  20. graph.invoke({"messages":"what is 2+4?"})
  21.  
  22. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  23.  
  24. #ChatPromptTemplate ways:-
  25. reflection_prompt=ChatPromptTemplate.from_messages(
  26.     [
  27.         (
  28.             "system",
  29.             "You are a viral twitter influencer grading a tweet. Generate critique and recommendations for the user's tweet."
  30.             "Always provide detailed recommendations, including requests for length, virality, style, etc.",
  31.         ),
  32.         MessagesPlaceholder(variable_name="messages") ,  
  33.     ]
  34. )
  35. chain = prompt | llm
  36. result = chain.invoke({"messages": [HumanMessage(content="What's the capital of Germany?")]})
  37.  
  38. prompt = ChatPromptTemplate.from_messages([
  39.     ("system", "You are a helpful assistant."),
  40.     ("human", "What is the capital of {country}?")
  41. ])
  42.  
  43. response = chain.invoke({"country": "France"})
  44. # ----OR
  45. filled_prompt = prompt.format_messages(country="France")
  46. response = llm(filled_prompt)
  47. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  48. #StateGraph
  49. class State(TypedDict):
  50.     messages:Annotated[list,add_messages] #messages would be a key for state,It's value should be a list
  51.                                           #add_messages tell that whenever a node outputs,append into the list,also called reducer, rather than replacing.
  52.  
  53. #Lot of nodes will update the message by returnning the messages then always return in form of a list
  54. #eg. return {"messages": [AIMessage(content="2 + 2 is 4")]}
  55.  
  56.  
  57. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  58. #one way to invoke llm means we can give SystemMessage also while invoking and can avoid making prompt
  59. content = llm.invoke([   #LLM can be invoked with chat history also and .content is neede to extract output
  60.         SystemMessage(content="Write a report section following the provided name and description. Include no preamble. Use markdown formatting."),
  61.         HumanMessage(content=f"Here is the section name: {section.name} and description: {section.description}")
  62.     ])
  63.  
  64. # Method-2 for invoking LLM
  65. msg = llm.invoke( f"Write a joke about {state['topic']} but take into account the feedback: {state['feedback']}")
  66.  
  67. #Calling the LLM without SystemMessage
  68. tool_call=llm_with_tools.invoke([HumanMessage(content=f"What is 2 plus 2",name="Krish")])
  69.  
  70. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  71.  
  72. #Invoking a graph-Method1
  73. graph.invoke({'messages':"Hello, What is agentic ai?"})
  74.  
  75. #Invoking a graph-Method2
  76. messages = graph.invoke({
  77.     "messages": [{"role": "user", "content": "What is agentic ai and 2 plus 2"}]
  78. })
  79.  
  80. #Invoking a graph-Method 3
  81. messages=graph.invoke({"messages":HumanMessage(content="Provide me the top 10 recent AI news for MArch 3rd 2025,add 5 plus 5 and then multiply by 10")})
  82.  
  83. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  84. #For printing messages
  85. from pprint import pprint
  86.  
  87. messages=[AIMessage(content=f"Please tell me how can I help",name="LLMModel")]
  88. messages.append(HumanMessage(content=f"I want to learn coding",name="Krish"))
  89. messages.append(AIMessage(content=f"Which programming language you want to learn",name="LLMModel"))
  90. messages.append(HumanMessage(content=f"I want to learn python programming language",name="Krish"))
  91.  
  92. for message in messages:
  93.     message.pretty_print()
  94.  
  95. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  96.  
  97.  
  98. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  99.  
  100. #Tool to node method 1
  101. from langgraph.graph import ToolNode
  102. tool = StructuredTool.from_function( #Add is just a function takes two arguments and return their sum.
  103.     func=add,
  104.     name="add_numbers",         # 👈 THIS is the tool's name
  105.     description="Add two integers"
  106. )
  107. execute_tools = ToolNode(tools=[tool])
  108. #Here we are manually wrapping the function and giving args like func,name and description where name is used for internal tool calls.
  109.  
  110. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  111. #Tool to node, method 2 here -Langgraph internally wraps the function and give name and description to the node
  112. from langgraph.prebuilt import ToolNode
  113. def add(a:int,b:int)-> int:
  114.     """ Add a and b
  115.    Args:
  116.        a (int): first int
  117.        b (int): second int
  118.  
  119.    Returns:
  120.        int
  121.    """
  122.     return a+b
  123.  
  124. tools=[add]
  125.  
  126. builder=StateGraph(State)
  127. #Make it a node
  128. builder.add_node("tools",ToolNode(tools))
  129.  
  130. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  131. #Conditional_edge for tools_condition
  132. from langgraph.prebuilt import tools_condition #You can directly connect from START to multiple nodes without conditional edge also,It will go to all the nodes parallely.
  133. builder = StateGraph(State)
  134. builder.add_node("tool_calling_llm", tool_calling_llm)
  135. builder.add_node("tools", ToolNode(tools))
  136. builder.add_conditional_edges(
  137.     "llm_tool",
  138.     # If the latest message (result) from assistant is a tool call -> tools_condition won't do anything,it will get routedt to tool call.
  139.     # If the latest message (result) from assistant is a not a tool call -> tools_condition routes to END
  140.     #the above conditions are defined internally with tools_condition
  141.     tools_condition
  142. )
  143. builder.add_edge("tools","tool_calling_llm") #Bind it back to llm node
  144. e
  145. # Method-2 for conditional edge
  146.  
  147. # if condition1:   #this should be a way to return to graph
  148. #     return {"next":"grade_answer"}
  149. # else:
  150. #     return {"next":"generate"}
  151.  
  152. graph.add_conditional_edges(
  153.     "hallucination",
  154.     lambda state: state["next"],  
  155.     {
  156.         "grade_answer": "grade_answer",
  157.         "generate": "generate"
  158.     }
  159. )
  160.  
  161. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  162. from langchain_community.tools import ArxivQueryRun,WikipediaQueryRun
  163. from langchain_community.utilities import WikipediaAPIWrapper,ArxivAPIWrapper
  164. from langchain_community.tools.tavily_search import TavilySearchResults
  165.  
  166. api_wrapper_arxiv=ArxivAPIWrapper(top_k_results=2,doc_content_chars_max=500)
  167. arxiv=ArxivQueryRun(api_wrapper=api_wrapper_arxiv)
  168.  
  169. tavily = TavilySearchResults()
  170.  
  171. tools=[arxiv,tavily,] #you can put here custom python simple functions also as a tool
  172. llm_with_tools = llm.bind_tools(tools)
  173.  
  174.  
  175. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  176. from langgraph.checkpoint.memory import MemorySaver
  177. memory=MemorySaver()
  178. graph_memory = builder.compile(checkpointer=memory)
  179.  
  180. ## Specify the thread
  181.  
  182. config={"configurable":{"thread_id":"1"}}
  183. # Specify an input
  184. messages = [HumanMessage(content="Add 12 and 13.")]
  185. messages=graph_memory.invoke({"messages":messages},config=config)
  186. for m in messages['messages']:
  187.     m.pretty_print()
  188.  
  189. messages = [HumanMessage(content="add that number to 25")]  #Keeping the same config will remeber the previous conversation
  190. messages=graph_memory.invoke({"messages":messages},config=config)
  191. for m in messages['messages']:
  192.     m.pretty_print()
  193.  
  194. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  195. #Memory saver with human in the loop
  196. memory=MemorySaver()
  197. graph=builder.compile(interrupt_before=["assistant"],checkpointer=memory)
  198. thread={"configurable":{"thread_id":"123"}}
  199. initial_input={"messages":HumanMessage(content="Multiply 2 and 3")}
  200.  
  201. # for seeing the full flow
  202. for event in graph.stream(initial_input,thread,stream_mode="values"):
  203.     event['messages'][-1].pretty_print()
  204. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  205. # Schema for structured output to use in evaluation
  206. class Feedback(BaseModel):
  207.     grade: Literal["funny", "not funny"] = Field(
  208.         description="Decide if the joke is funny or not.", #Description helps langgraph to show to the llm while deciding the grade.
  209.     )
  210.     feedback: str = Field(
  211.         description="If the joke is not funny, provide feedback on how to improve it.",
  212.     )
  213.  
  214. # Augment the LLM with schema for structured output
  215. evaluator = llm.with_structured_output(Feedback)
  216. #You can make the chain of evaluator with prompt also and call using .invoke method
  217.  
  218. #
  219. # -Use tools list when you are binding the tools with llm but in graph,use ToolNode(tools) where tools are the list of the tools.
  220.  
  221. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  222. tools=[add,multiply,divide]
  223. llm=llm.bind_tools(tools)
  224. def llm_with_tools(state:State):
  225.     return {'messages':[llm.invoke(state['messages'])]}
  226.  
  227. graph=StateGraph(State)
  228. graph.add_node('llm_with_tools',llm_with_tools)
  229. graph.add_node('tools',ToolNode(tools))
  230.  
  231. graph.add_edge(START,'llm_with_tools')
  232. graph.add_edge('llm_with_tools','tools')
  233. graph.add_conditional_edges('llm_with_tools',tools_condition)
  234.  
  235. graph=graph.compile()
  236. #When we are binding the tools with LLM,this will help LLM to decide wherther to call a tool or not or which tool.It does the tool selection,not it's exectuion.
  237. #but ToolNode(tools) which we have created as a node, does the tool execution.
  238. #One more thing to notice that,you make only one edge with tools but it's two way because the tools returns the response.
  239.  
  240. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  241. #this code is for a chatbot where the LLM gets the previous messsages everytime.
  242. from langgraph.graph import StateGraph
  243. from typing import Annotated
  244. from typing_extensions import TypedDict
  245. from langgraph.graph.message import add_messages
  246.  
  247. class State(TypedDict):
  248.     messages: Annotated[list, add_messages]
  249.  
  250. # Build graph
  251. graph = StateGraph(State)
  252.  
  253. def chatbot(state: State):
  254.     return {"messages": [llm.invoke(state["messages"])]}
  255.  
  256. graph.add_node("chatbot", chatbot)
  257. graph.set_entry_point("chatbot")
  258. graph.set_finish_point("chatbot")
  259.  
  260. app = graph.compile()
  261.  
  262. # Run infinitely
  263. while True:
  264.     user_input = input("You: ")
  265.     if user_input.lower() == "exit":
  266.         break
  267.    
  268.     state = app.invoke({"messages": [{"role": "user", "content": user_input}]})
  269.     print("AI:", state["messages"][-1].content)
  270.  
Advertisement
Add Comment
Please, Sign In to add comment