├── agent_based_rag ├── employee2.db ├── agent.png ├── output.png ├── employee.db ├── corrective.png ├── corrective_rag.jpeg └── corrective_rag.ipynb ├── .gitignore ├── .vscode └── settings.json ├── self_rag.png ├── architecture ├── output.jpeg ├── output2.jpeg ├── output3.jpeg ├── selfbhau2.png ├── react output.jpeg ├── humaninloop-output.jpeg ├── structure-output.jpeg └── structure_output_design.jpeg ├── multiagent_system ├── multi-agent.pdf └── multiagentsystem-handwrittennotes.pdf ├── chatbot_with_langgraph ├── __pycache__ │ └── bot.cpython-310.pyc ├── app.py └── bot.py ├── .env ├── requirements.txt ├── data └── llama3.txt ├── data2 └── indian_economy.txt ├── Pre-requist_for_langgraph ├── agents_pratice.ipynb └── Pre_requist_Assistant_RAG_LCEL.ipynb ├── ReAct_Agent_From_Scratch └── ReACt_Agent_From_Scratch_In_Python.ipynb └── different_structure_pattern ├── structure_output_agent.ipynb └── React_agent_with_langgraph.ipynb /agent_based_rag/employee2.db: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | env 3 | .env 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "bitoAI.codeCompletion.enableAutoCompletion": false 3 | } -------------------------------------------------------------------------------- /self_rag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/self_rag.png -------------------------------------------------------------------------------- /agent_based_rag/agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/agent_based_rag/agent.png -------------------------------------------------------------------------------- /agent_based_rag/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/agent_based_rag/output.png -------------------------------------------------------------------------------- /architecture/output.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/architecture/output.jpeg -------------------------------------------------------------------------------- /architecture/output2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/architecture/output2.jpeg -------------------------------------------------------------------------------- /architecture/output3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/architecture/output3.jpeg -------------------------------------------------------------------------------- /architecture/selfbhau2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/architecture/selfbhau2.png -------------------------------------------------------------------------------- /agent_based_rag/employee.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/agent_based_rag/employee.db -------------------------------------------------------------------------------- /agent_based_rag/corrective.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/agent_based_rag/corrective.png -------------------------------------------------------------------------------- /architecture/react output.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/architecture/react output.jpeg -------------------------------------------------------------------------------- /multiagent_system/multi-agent.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/multiagent_system/multi-agent.pdf -------------------------------------------------------------------------------- /agent_based_rag/corrective_rag.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/agent_based_rag/corrective_rag.jpeg -------------------------------------------------------------------------------- /architecture/humaninloop-output.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/architecture/humaninloop-output.jpeg -------------------------------------------------------------------------------- /architecture/structure-output.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/architecture/structure-output.jpeg -------------------------------------------------------------------------------- /architecture/structure_output_design.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/architecture/structure_output_design.jpeg -------------------------------------------------------------------------------- /chatbot_with_langgraph/__pycache__/bot.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/chatbot_with_langgraph/__pycache__/bot.cpython-310.pyc -------------------------------------------------------------------------------- /multiagent_system/multiagentsystem-handwrittennotes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/langgraph-end-to-end/main/multiagent_system/multiagentsystem-handwrittennotes.pdf -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | LANGCHAIN_API_KEY="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" 2 | GOOGLE_API_KEY="AIzaSyAFVeWmqWbg9h9unwzDvyTKUOb-WdYyzBU" 3 | TAVILY_API_KEY="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" 4 | GROQ_API_KEY="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" 5 | LANGCHAIN_PROJECT="langchain-agent" 6 | SERPER_API_KEY="98b830ee62b115e37b3fb9be154835a0040362d4" -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | langchain_community 2 | tiktoken 3 | langchainhub 4 | chromadb 5 | langchain 6 | langgraph 7 | tavily-python 8 | python-dotenv 9 | google-generativeai 10 | langchain-google-genai 11 | langchain-groq 12 | langchain-nomic 13 | langchain-text-splitters 14 | langchain_mistralai 15 | wikipedia 16 | langchain_huggingface 17 | google-search-results 18 | faiss-cpu 19 | sentence_transformers 20 | youtube_search 21 | yfinance -------------------------------------------------------------------------------- /chatbot_with_langgraph/app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from transformers import pipeline 3 | from bot import chatbot 4 | 5 | mybot=chatbot() 6 | workflow=mybot() 7 | 8 | # Set up the Streamlit app UI 9 | st.title("ChatBot with LangGraph") 10 | st.write("Ask any question, and I'll try to answer it!") 11 | 12 | # Input text box for the question 13 | question = st.text_input("Enter your question here:") 14 | input={"messages": [question]} 15 | 16 | # Button to get the answer 17 | if st.button("Get Answer"): 18 | if input: 19 | response=workflow.invoke(input) 20 | st.write("**Answer:**", response['messages'][-1].content) 21 | else: 22 | st.warning("Please enter a question to get an answer.") 23 | 24 | # Additional styling (optional) 25 | st.markdown("---") 26 | st.caption("Powered by Streamlit and Transformers") 27 | -------------------------------------------------------------------------------- /data/llama3.txt: -------------------------------------------------------------------------------- 1 | Llama (Large Language Model Meta AI) is a family of autoregressive large language models released by Meta AI starting in February 2023.[2][3] The latest version is Llama 3 released in April 2024.[4] 2 | 3 | Model weights for the first version of Llama were released to the research community under a non-commercial license.[5][3] Subsequent versions of Llama were made accessible outside academia and released under licenses that permitted some commercial use.[6][7] Llama models are trained at different parameter sizes, typically ranging between 7B and 70B.[4] Originally, Llama was only available as a foundation model.[8] Starting with Llama 2, Meta AI started releasing instruction fine-tuned versions alongside foundation models.[7] 4 | 5 | Llama models have been compared favorably against other large language models. Meta AI reported the original 13B parameter model's performance on most NLP benchmarks exceeded that of the much larger GPT-3 (with 175B parameters) and that the largest model was competitive with state of the art models such as PaLM and Chinchilla.[2]. Meta AI's testing shows that Llama 3 70B beats Gemini, and Claude in most benchmarks.[9][10] Wired describes the 8B parameter version of Llama 3 as being "surprisingly capable" given it's size.[11] 6 | 7 | Alongside the release of Llama 3, Meta added virtual assistant features to Facebook and WhatsApp in select regions, and a standalone website. Both services use a Llama 3 model.[12] Reception was mixed, with some users confused after Meta AI told a parental group that it had a child.[13] -------------------------------------------------------------------------------- /chatbot_with_langgraph/bot.py: -------------------------------------------------------------------------------- 1 | # importing a necessary library 2 | from langgraph.graph import StateGraph,MessagesState, START, END 3 | from langgraph.graph.message import add_messages 4 | from typing import Annotated, Literal, TypedDict 5 | from langchain_core.tools import tool 6 | from langchain_core.messages import HumanMessage 7 | from langgraph.checkpoint.memory import MemorySaver 8 | from langgraph.prebuilt import ToolNode 9 | from langchain_groq import ChatGroq 10 | from langchain_community.tools.tavily_search import TavilySearchResults 11 | 12 | 13 | 14 | class chatbot: 15 | def __init__(self): 16 | self.llm=ChatGroq(model_name="Gemma2-9b-It") 17 | 18 | def call_tool(self): 19 | tool = TavilySearchResults(max_results=2) 20 | tools = [tool] 21 | self.tool_node = ToolNode(tools=[tool]) 22 | self.llm_with_tool=self.llm.bind_tools(tools) 23 | 24 | def call_model(self,state: MessagesState): 25 | messages = state['messages'] 26 | response = self.llm_with_tool.invoke(messages) 27 | return {"messages": [response]} 28 | 29 | def router_function(self,state: MessagesState) -> Literal["tools", END]: 30 | messages = state['messages'] 31 | last_message = messages[-1] 32 | if last_message.tool_calls: 33 | return "tools" 34 | return END 35 | 36 | 37 | 38 | def __call__(self): 39 | self.call_tool() 40 | workflow = StateGraph(MessagesState) 41 | workflow.add_node("agent", self.call_model) 42 | workflow.add_node("tools", self.tool_node) 43 | workflow.add_edge(START, "agent") 44 | workflow.add_conditional_edges("agent",self.router_function,{"tools": "tools", END: END}) 45 | workflow.add_edge("tools", 'agent') 46 | self.app = workflow.compile() 47 | return self.app 48 | 49 | if __name__=="__main__": 50 | mybot=chatbot() 51 | workflow=mybot() 52 | response=workflow.invoke({"messages": ["who is a current prime minister of USA?"]}) 53 | print(response['messages'][-1].content) 54 | 55 | -------------------------------------------------------------------------------- /data2/indian_economy.txt: -------------------------------------------------------------------------------- 1 | Industrial Revival and Economic Optimism for India 2 | 3 | India’s industrial growth has outpaced expectations, raising hopes that the economy will avoid a potential downturn. Industrial output rose by 2.5% in January, adjusted for seasonal fluctuations, marking the third consecutive month of growth. Retail sales also increased sharply, recording the highest monthly rise since 2016, driven largely by consumer demand for electronics, automobiles, and pharmaceuticals. 4 | 5 | The Bombay Stock Exchange (BSE) Sensex index climbed to its highest level in ten months, ending the day up 0.8% at 58,200 points. Concurrently, the Indian Rupee strengthened by 0.5% against the U.S. dollar, reaching 82.34 INR/USD. 6 | 7 | India’s strong export sectors—including textiles, IT services, and automotive manufacturing—had seen sluggish growth due to uncertain global demand, leading to a 0.2% contraction in the last quarter of 2023. However, pharmaceutical exports and electronics have been bright spots, and increased consumer spending domestically has driven economic momentum. 8 | 9 | Key Sector Performances: 10 | 11 | Automotive: Driven by rising demand for electric vehicles and traditional two-wheelers, the automotive sector saw a 3.2% increase in output in January. 12 | Pharmaceuticals: India’s pharmaceutical exports grew by 1.8%, fueled by continued demand for generic medications and vaccine production. 13 | Electronics: This sector saw a 4.5% rise in January, with consumer electronics like smartphones and televisions in high demand domestically and internationally. 14 | Textiles: While textiles faced a slight decline of 0.3%, demand from the U.S. and Europe in early 2024 is expected to help the sector rebound. 15 | Government and Financial Insights: RBI Governor Shaktikanta Das noted a cautiously optimistic outlook for India’s economy. “We are encouraged by the steady rise in domestic consumption and industrial output. However, we remain vigilant to any signs of inflation or global market volatility that could impact growth.” The government has announced targeted fiscal policies to support emerging sectors like renewable energy, electronics, and healthcare manufacturing. 16 | 17 | Additional Economic Indicators: 18 | 19 | Retail Sales Growth: 5.2% rise in January, the highest since 2016, driven by urban and rural spending. 20 | Investment in Manufacturing: Up by 2.1% in Q1 2024, focusing on infrastructure and renewable energy. 21 | Exports to the U.S.: Increased by 1.9%, reflecting strengthened ties and demand for Indian IT services and pharmaceuticals. 22 | Inflation Rate: Managed at a stable 4.1%, with food prices stabilizing and fuel costs showing a slight decline. 23 | India’s last eight years of GDP (hypothetical data): 24 | 25 | Year GDP 26 | 2022 $3,517.24B 27 | 2021 $3,173.04B 28 | 2020 $2,935.57B 29 | 2019 $2,869.45B 30 | 2018 $2,715.50B 31 | 2017 $2,652.10B 32 | 2016 $2,479.15B 33 | 2015 $2,390.78B 34 | 35 | This expanded dataset provides deeper insights into the industrial revival, key growth sectors, government actions, and broader economic trends shaping India’s economy. -------------------------------------------------------------------------------- /Pre-requist_for_langgraph/agents_pratice.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os\n", 10 | "from dotenv import load_dotenv\n", 11 | "load_dotenv()\n", 12 | "\n", 13 | "GOOGLE_API_KEY=os.getenv(\"GOOGLE_API_KEY\")\n", 14 | "TAVILY_API_KEY=os.getenv(\"TAVILY_API_KEY\")\n", 15 | "GROQ_API_KEY=os.getenv(\"GROQ_API_KEY\")\n", 16 | "LANGCHAIN_API_KEY=os.getenv(\"LANGCHAIN_API_KEY\")\n", 17 | "LANGCHAIN_PROJECT=os.getenv(\"LANGCHAIN_PROJECT\")\n" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "os.environ[\"GOOGLE_API_KEY\"] = GOOGLE_API_KEY\n", 27 | "os.environ[\"TAVILY_API_KEY\"] = TAVILY_API_KEY\n", 28 | "os.environ[\"GROQ_API_KEY\"]= GROQ_API_KEY\n", 29 | "os.environ[\"LANGCHAIN_API_KEY\"] = LANGCHAIN_API_KEY\n", 30 | "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n", 31 | "os.environ[\"LANGCHAIN_ENDPOINT\"] = \"https://api.smith.langchain.com\"\n", 32 | "os.environ[\"LANGCHAIN_PROJECT\"]=LANGCHAIN_PROJECT" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "\n", 42 | "from langchain_groq import ChatGroq\n", 43 | "llm=ChatGroq(model_name=\"Gemma2-9b-It\")" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 3, 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "name": "stderr", 53 | "output_type": "stream", 54 | "text": [ 55 | "c:\\Users\\sunny\\langgraph-end-to-end\\env\\lib\\site-packages\\sentence_transformers\\cross_encoder\\CrossEncoder.py:13: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", 56 | " from tqdm.autonotebook import tqdm, trange\n", 57 | "c:\\Users\\sunny\\langgraph-end-to-end\\env\\lib\\site-packages\\transformers\\tokenization_utils_base.py:1617: FutureWarning: `clean_up_tokenization_spaces` was not set. It will be set to `True` by default. This behavior will be deprecated in transformers v4.45, and will be then set to `False` by default. For more details check this issue: https://github.com/huggingface/transformers/issues/31884\n", 58 | " warnings.warn(\n" 59 | ] 60 | } 61 | ], 62 | "source": [ 63 | "from langchain_huggingface import HuggingFaceEmbeddings\n", 64 | "embeddings=HuggingFaceEmbeddings(model_name=\"all-MiniLM-L6-v2\")" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "# Predefine tools" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 6, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "Page: LangChain\n", 84 | "Summary: LangChain is a software framework that helps facilitate the integration of large language models (LLMs) into applications. As a language model integration framework, LangChain's use-cases largely overlap with those of language models in general, including document analysis and summarization, chatbots, and code analysis.\n", 85 | "\n", 86 | "\n", 87 | "\n", 88 | "Page: Retrieval-augmented generation\n", 89 | "Summary: Retrieval augmented generation (RAG) is a type of generative artificial intelligence that has information retrieval capabilities. It modifies interactions with a large language model (LLM) so that the model responds to user queries with reference to a specified set of documents, using this information in preference to information drawn from its own vast, static training data. This allows LLMs to use domain-specific and/or updated information. \n", 90 | "Use cases include providing chatbot access to internal company data, or giving factual information only from an authoritative source.\n", 91 | "\n", 92 | "\n", 93 | "\n", 94 | "Page: DataStax\n", 95 | "Summary: DataStax, Inc. is a real-time data for AI company based in Santa Clara, California. Its product Astra DB is a cloud database-as-a-service based on Apache Cassandra. DataStax also offers DataStax Enterprise (DSE), an on-premises database built on Apache Cassandra, and Astra Streaming, a messaging and event streaming cloud service based on Apache Pulsar. As of June 2022, the company has roughly 800 customers distributed in over 50 countries.\n", 96 | "\n", 97 | "\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "from langchain_community.tools import WikipediaQueryRun\n", 103 | "from langchain_community.utilities import WikipediaAPIWrapper\n", 104 | "api_wrapper = WikipediaAPIWrapper()\n", 105 | "tool = WikipediaQueryRun(api_wrapper=api_wrapper)\n", 106 | "print(tool.run({\"query\": \"langchain\"}))" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 9, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "text/plain": [ 117 | "\"['https://www.youtube.com/watch?v=8aUYzb1aYDU&pp=ygUMc3Vubnkgc2F2aXRh', 'https://www.youtube.com/watch?v=ABK00e2XdPo&pp=ygUMc3Vubnkgc2F2aXRh']\"" 118 | ] 119 | }, 120 | "execution_count": 9, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "from langchain_community.tools import YouTubeSearchTool\n", 127 | "tool2=YouTubeSearchTool()\n", 128 | "tool2.run(\"sunny savita\")" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 10, 134 | "metadata": {}, 135 | "outputs": [ 136 | { 137 | "data": { 138 | "text/plain": [ 139 | "[{'url': 'https://www.encyclopedia.com/people/history/south-asian-history-biographies/mohandas-karamchand-gandhi',\n", 140 | " 'content': \"Mohandas Karamchand Gandhi (1869-1948) was an Indian revolutionary religious leader who used his religious power for political and social reform. Although he held no governmental office, he was the prime mover in the struggle for independence of the world's second-largest nation.\"},\n", 141 | " {'url': 'https://historycooperative.org/stay-story-mahatma-gandhi/',\n", 142 | " 'content': \"Mahatma Gandhi, also known as Mohandas Karamchand Gandhi, was a prominent figure in India's struggle for independence from British rule. His approach to non-violent protest and civil disobedience became a beacon for peaceful movements worldwide. Gandhi's beliefs in simplicity, non-violence, and truth had a profound impact on the world, influencing other leaders like Martin Luther\"},\n", 143 | " {'url': 'https://www.britannica.com/summary/Mahatma-Gandhi',\n", 144 | " 'content': 'Mahatma Gandhi summary\\nExplore the life of Mahatma Gandhi as a political and social activist\\nMahatma Gandhi, byname of Mohandas Karamchand Gandhi,\\n(born Oct. 2, 1869, Porbandar, India—died Jan. 30, 1948, Delhi), Preeminent leader of Indian nationalism and prophet of nonviolence in the 20th century.\\n He refashioned the Indian National Congress into an effective political instrument of Indian nationalism and undertook major campaigns of nonviolent resistance in 1920–22, 1930–34 (including his momentous march to the sea to collect salt to protest a government monopoly), and 1940–42. His success in South Africa gave him an international reputation, and in 1915 he returned to India and within a few years became the leader of a nationwide struggle for Indian home rule. Gandhi grew up in a home steeped in religion, and he took for granted religious tolerance and the doctrine of ahimsa (noninjury to all living beings). India achieved dominion status in 1947, but the partition of the subcontinent into India and Pakistan was a great disappointment to Gandhi, who had long worked for Hindu-Muslim unity.'},\n", 145 | " {'url': 'https://www.bbc.co.uk/religion/religions/hinduism/people/gandhi_1.shtml',\n", 146 | " 'content': 'Born in 1869 in Porbandar on the Western coast of India and raised by Hindu parents, Mohandas Karamchand Gandhi found many opportunities in his youth to meet people of all faiths. He had many ...'},\n", 147 | " {'url': 'https://www.britannica.com/biography/Mahatma-Gandhi',\n", 148 | " 'content': 'Mohandas disregarded the last obstacle—the decree of the leaders of the Modh Bania subcaste (Vaishya caste), to which the Gandhis belonged, who forbade his trip to England as a violation of the Hindu religion—and sailed in September 1888. Gandhi’s father was a local government official working under the suzerainty of the British Raj, and his mother was a religious devotee who—like the rest of the family—practiced in the Vaishnavist tradition of Hinduism. Leo Tolstoy’s analysis of Christian theology, for example, came to bear heavily on Gandhi’s conception of spirituality, as did texts such as the Bible and the Quʾrān, and he first read the Bhagavadgita—a Hindu epic—in its English translation while living in Britain.\\n His father—Karamchand Gandhi, who was the dewan (chief minister) of Porbandar, the capital of a small principality in western India (in what is now Gujarat state) under British suzerainty—did not have much in the way of a formal education. But, besides the Vaishnava prejudice against vivisection, it was clear that, if he was to keep up the family tradition of holding high office in one of the states in Gujarat, he would have to qualify as a barrister.'}]" 149 | ] 150 | }, 151 | "execution_count": 10, 152 | "metadata": {}, 153 | "output_type": "execute_result" 154 | } 155 | ], 156 | "source": [ 157 | "from langchain_community.tools.tavily_search import TavilySearchResults\n", 158 | "tool = TavilySearchResults()\n", 159 | "tool.invoke({\"query\": \"who is mohandas karamchand gandhi?\"})" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "# Create a Custom tool" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "from langchain.agents import tool\n", 176 | "@tool\n", 177 | "def get_word_length(word: str) -> int:\n", 178 | " \"\"\"Returns the length of a word.\"\"\"\n", 179 | " return len(word)" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": null, 185 | "metadata": {}, 186 | "outputs": [], 187 | "source": [ 188 | "get_word_length.invoke(\"abc\")" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "@tool\n", 198 | "def multiply(a: int, b: int) -> int:\n", 199 | " \"\"\"Multiply two numbers.\"\"\"\n", 200 | " return a * b" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": null, 206 | "metadata": {}, 207 | "outputs": [], 208 | "source": [ 209 | "print(multiply.name)\n", 210 | "print(multiply.description)\n", 211 | "print(multiply.args)" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [ 220 | "multiply.invoke({\"a\":10,\"b\":20})" 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "execution_count": null, 226 | "metadata": {}, 227 | "outputs": [], 228 | "source": [] 229 | } 230 | ], 231 | "metadata": { 232 | "kernelspec": { 233 | "display_name": "Python 3", 234 | "language": "python", 235 | "name": "python3" 236 | }, 237 | "language_info": { 238 | "codemirror_mode": { 239 | "name": "ipython", 240 | "version": 3 241 | }, 242 | "file_extension": ".py", 243 | "mimetype": "text/x-python", 244 | "name": "python", 245 | "nbconvert_exporter": "python", 246 | "pygments_lexer": "ipython3", 247 | "version": "3.10.14" 248 | } 249 | }, 250 | "nbformat": 4, 251 | "nbformat_minor": 2 252 | } 253 | -------------------------------------------------------------------------------- /Pre-requist_for_langgraph/Pre_requist_Assistant_RAG_LCEL.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "data": { 19 | "text/plain": [ 20 | "True" 21 | ] 22 | }, 23 | "execution_count": 2, 24 | "metadata": {}, 25 | "output_type": "execute_result" 26 | } 27 | ], 28 | "source": [ 29 | "import os\n", 30 | "from dotenv import load_dotenv\n", 31 | "load_dotenv()" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 3, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "\n", 41 | "GOOGLE_API_KEY=os.getenv(\"GOOGLE_API_KEY\")\n", 42 | "TAVILY_API_KEY=os.getenv(\"TAVILY_API_KEY\")\n", 43 | "GROQ_API_KEY=os.getenv(\"GROQ_API_KEY\")\n", 44 | "LANGCHAIN_API_KEY=os.getenv(\"LANGCHAIN_API_KEY\")\n", 45 | "LANGCHAIN_PROJECT=os.getenv(\"LANGCHAIN_PROJECT\")" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 4, 51 | "metadata": {}, 52 | "outputs": [ 53 | { 54 | "data": { 55 | "text/plain": [ 56 | "'langgraph-prerequist'" 57 | ] 58 | }, 59 | "execution_count": 4, 60 | "metadata": {}, 61 | "output_type": "execute_result" 62 | } 63 | ], 64 | "source": [ 65 | "LANGCHAIN_PROJECT" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 5, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "\n", 75 | "os.environ[\"GOOGLE_API_KEY\"] = GOOGLE_API_KEY\n", 76 | "os.environ[\"TAVILY_API_KEY\"] = TAVILY_API_KEY\n", 77 | "os.environ[\"GROQ_API_KEY\"]= GROQ_API_KEY\n", 78 | "os.environ[\"LANGCHAIN_API_KEY\"] = LANGCHAIN_API_KEY\n", 79 | "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n", 80 | "os.environ[\"LANGCHAIN_ENDPOINT\"] = \"https://api.smith.langchain.com\"\n", 81 | "os.environ[\"LANGCHAIN_PROJECT\"]=LANGCHAIN_PROJECT" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 31, 87 | "metadata": {}, 88 | "outputs": [], 89 | "source": [ 90 | "from langchain_google_genai import GoogleGenerativeAIEmbeddings\n", 91 | "embeddings = GoogleGenerativeAIEmbeddings(model=\"models/embedding-001\")\n", 92 | "from langchain_google_genai import ChatGoogleGenerativeAI\n", 93 | "llm = ChatGoogleGenerativeAI(model=\"gemini-1.0-pro\")" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 7, 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "'''from langchain_huggingface import HuggingFaceEmbeddings\n", 103 | "embeddings=HuggingFaceEmbeddings(model_name=\"all-MiniLM-L6-v2\")'''\n", 104 | "from langchain_groq import ChatGroq\n", 105 | "import os\n", 106 | "llm=ChatGroq(model_name=\"Gemma2-9b-It\")" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "# Simple AI Assistant" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 11, 119 | "metadata": {}, 120 | "outputs": [ 121 | { 122 | "name": "stdout", 123 | "output_type": "stream", 124 | "text": [ 125 | "Hello, Sunny. I am Gemini, a multi-modal AI model, developed by Google. How can I assist you today?\n", 126 | "Hi Sunny, it's nice to meet you! How can I help you today?\n", 127 | "I do not have access to your personal information, including your name.\n", 128 | "I do not have access to your personal information, so I cannot tell you your name.\n", 129 | "goodbye take care yourself\n" 130 | ] 131 | } 132 | ], 133 | "source": [ 134 | "while True:\n", 135 | " question=input(\"type your question. if you want to quit the chat write quit\")\n", 136 | " if question !=\"quit\":\n", 137 | " print(llm.invoke(question).content)\n", 138 | " else:\n", 139 | " print(\"goodbye take care yourself\")\n", 140 | " break" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 12, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "from langchain_core.chat_history import BaseChatMessageHistory\n", 150 | "from langchain_core.chat_history import InMemoryChatMessageHistory\n", 151 | "from langchain_core.runnables.history import RunnableWithMessageHistory\n", 152 | "from langchain_core.messages import AIMessage" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 20, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "store={}" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 21, 167 | "metadata": {}, 168 | "outputs": [], 169 | "source": [ 170 | "\n", 171 | "def get_session_history(session_id: str) -> BaseChatMessageHistory:\n", 172 | " if session_id not in store:\n", 173 | " store[session_id] = InMemoryChatMessageHistory()\n", 174 | " return store[session_id]" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 22, 180 | "metadata": {}, 181 | "outputs": [], 182 | "source": [ 183 | "config = {\"configurable\": {\"session_id\": \"firstchat\"}}" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": {}, 190 | "outputs": [], 191 | "source": [] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 23, 196 | "metadata": {}, 197 | "outputs": [], 198 | "source": [ 199 | "model_with_memory=RunnableWithMessageHistory(llm,get_session_history)" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 24, 205 | "metadata": {}, 206 | "outputs": [ 207 | { 208 | "data": { 209 | "text/plain": [ 210 | "\"Hello, sunnysavita! It's nice to meet you. My name is Gemini. I am a multi-modal AI model, developed by Google. I am designed to assist and provide information to the best of my abilities. Is there anything I can help you with today?\"" 211 | ] 212 | }, 213 | "execution_count": 24, 214 | "metadata": {}, 215 | "output_type": "execute_result" 216 | } 217 | ], 218 | "source": [ 219 | "model_with_memory.invoke((\"Hi! I'm sunnysavita\"),config=config).content" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 25, 225 | "metadata": {}, 226 | "outputs": [ 227 | { 228 | "data": { 229 | "text/plain": [ 230 | "'Your name is sunnysavita. You told me this when you introduced yourself. Is there anything else I can help you with today?'" 231 | ] 232 | }, 233 | "execution_count": 25, 234 | "metadata": {}, 235 | "output_type": "execute_result" 236 | } 237 | ], 238 | "source": [ 239 | "model_with_memory.invoke((\"tell me what is my name?\"),config=config).content" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 26, 245 | "metadata": {}, 246 | "outputs": [ 247 | { 248 | "data": { 249 | "text/plain": [ 250 | "{'firstchat': InMemoryChatMessageHistory(messages=[HumanMessage(content=\"Hi! I'm sunnysavita\", additional_kwargs={}, response_metadata={}), AIMessage(content=\"Hello, sunnysavita! It's nice to meet you. My name is Gemini. I am a multi-modal AI model, developed by Google. I am designed to assist and provide information to the best of my abilities. Is there anything I can help you with today?\", additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'safety_ratings': [{'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability': 'NEGLIGIBLE', 'blocked': False}]}, id='run-fc4908ce-f4a1-4f0f-aab4-1914f82593b8-0', usage_metadata={'input_tokens': 10, 'output_tokens': 58, 'total_tokens': 68}), HumanMessage(content='tell me what is my name?', additional_kwargs={}, response_metadata={}), AIMessage(content='Your name is sunnysavita. You told me this when you introduced yourself. Is there anything else I can help you with today?', additional_kwargs={}, response_metadata={'prompt_feedback': {'block_reason': 0, 'safety_ratings': []}, 'finish_reason': 'STOP', 'safety_ratings': [{'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability': 'NEGLIGIBLE', 'blocked': False}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability': 'NEGLIGIBLE', 'blocked': False}]}, id='run-4f901433-80d6-4fdb-9958-3285c7144295-0', usage_metadata={'input_tokens': 77, 'output_tokens': 28, 'total_tokens': 105})])}" 251 | ] 252 | }, 253 | "execution_count": 26, 254 | "metadata": {}, 255 | "output_type": "execute_result" 256 | } 257 | ], 258 | "source": [ 259 | "store" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "metadata": {}, 265 | "source": [ 266 | "# RAG with LCEL" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 30, 272 | "metadata": {}, 273 | "outputs": [], 274 | "source": [ 275 | "from langchain_community.document_loaders import TextLoader, DirectoryLoader\n", 276 | "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", 277 | "from langchain_community.vectorstores import Chroma\n", 278 | "from langchain import PromptTemplate\n", 279 | "from langchain_core.runnables import RunnableParallel, RunnablePassthrough , RunnableLambda\n", 280 | "from langchain_core.output_parsers import StrOutputParser" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": 32, 286 | "metadata": {}, 287 | "outputs": [], 288 | "source": [ 289 | "### Reading the txt files from source directory\n", 290 | "\n", 291 | "loader = DirectoryLoader('../data', glob=\"./*.txt\", loader_cls=TextLoader)\n", 292 | "docs = loader.load()\n", 293 | "\n", 294 | "### Creating Chunks using RecursiveCharacterTextSplitter\n", 295 | "\n", 296 | "text_splitter = RecursiveCharacterTextSplitter(\n", 297 | " chunk_size=50,\n", 298 | " chunk_overlap=10,\n", 299 | " length_function=len\n", 300 | ")\n", 301 | "new_docs = text_splitter.split_documents(documents=docs)\n", 302 | "doc_strings = [doc.page_content for doc in new_docs]\n", 303 | "\n", 304 | "### BGE Embddings\n", 305 | "\n", 306 | "'''from langchain.embeddings import HuggingFaceBgeEmbeddings\n", 307 | "\n", 308 | "model_name = \"BAAI/bge-base-en-v1.5\"\n", 309 | "model_kwargs = {'device': 'cpu'}\n", 310 | "encode_kwargs = {'normalize_embeddings': True} # set True to compute cosine similarity\n", 311 | "embeddings = HuggingFaceBgeEmbeddings(\n", 312 | " model_name=model_name,\n", 313 | " model_kwargs=model_kwargs,\n", 314 | " encode_kwargs=encode_kwargs,\n", 315 | ")\n", 316 | "'''\n", 317 | "\n", 318 | "### Creating Retriever using Vector DB\n", 319 | "\n", 320 | "db = Chroma.from_documents(new_docs, embeddings)\n", 321 | "retriever = db.as_retriever(search_kwargs={\"k\": 4})" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 33, 327 | "metadata": {}, 328 | "outputs": [], 329 | "source": [ 330 | "template = \"\"\"Answer the question based only on the following context:\n", 331 | "{context}\n", 332 | "\n", 333 | "Question: {question}\n", 334 | "\"\"\"\n", 335 | "prompt = PromptTemplate.from_template(template)\n" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": 34, 341 | "metadata": {}, 342 | "outputs": [], 343 | "source": [ 344 | "\n", 345 | "retrieval_chain = (\n", 346 | " RunnableParallel({\"context\": retriever, \"question\": RunnablePassthrough()})\n", 347 | " | prompt\n", 348 | " | llm\n", 349 | " | StrOutputParser()\n", 350 | " )" 351 | ] 352 | }, 353 | { 354 | "cell_type": "code", 355 | "execution_count": 35, 356 | "metadata": {}, 357 | "outputs": [ 358 | { 359 | "name": "stdout", 360 | "output_type": "stream", 361 | "text": [ 362 | "Based on the provided context, here are three important points about Llama3:\n", 363 | "\n", 364 | "1. **Llama3 is a language model:** It is a large language model developed by Meta AI.\n", 365 | "2. **It was released in April 2024:** Llama3 was released in April 2024, according to the provided context.\n", 366 | "3. **It is used by various services:** Both Notion AI and Gemini use a Llama3 model, as stated in the context.\n" 367 | ] 368 | } 369 | ], 370 | "source": [ 371 | "question =\"what is llama3? can you highlight 3 important points?\"\n", 372 | "print(retrieval_chain.invoke(question))" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": {}, 378 | "source": [ 379 | "# Let's Start with Tools and Agents" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": 36, 385 | "metadata": {}, 386 | "outputs": [], 387 | "source": [ 388 | "from langchain_community.tools import WikipediaQueryRun\n", 389 | "from langchain_community.utilities import WikipediaAPIWrapper" 390 | ] 391 | }, 392 | { 393 | "cell_type": "code", 394 | "execution_count": 37, 395 | "metadata": {}, 396 | "outputs": [], 397 | "source": [ 398 | "api_wrapper=WikipediaAPIWrapper()" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": 38, 404 | "metadata": {}, 405 | "outputs": [], 406 | "source": [ 407 | "tool=WikipediaQueryRun(api_wrapper=api_wrapper)" 408 | ] 409 | }, 410 | { 411 | "cell_type": "code", 412 | "execution_count": 39, 413 | "metadata": {}, 414 | "outputs": [ 415 | { 416 | "data": { 417 | "text/plain": [ 418 | "'wikipedia'" 419 | ] 420 | }, 421 | "execution_count": 39, 422 | "metadata": {}, 423 | "output_type": "execute_result" 424 | } 425 | ], 426 | "source": [ 427 | "tool.name" 428 | ] 429 | }, 430 | { 431 | "cell_type": "code", 432 | "execution_count": 40, 433 | "metadata": {}, 434 | "outputs": [ 435 | { 436 | "data": { 437 | "text/plain": [ 438 | "'A wrapper around Wikipedia. Useful for when you need to answer general questions about people, places, companies, facts, historical events, or other subjects. Input should be a search query.'" 439 | ] 440 | }, 441 | "execution_count": 40, 442 | "metadata": {}, 443 | "output_type": "execute_result" 444 | } 445 | ], 446 | "source": [ 447 | "tool.description" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 41, 453 | "metadata": {}, 454 | "outputs": [ 455 | { 456 | "data": { 457 | "text/plain": [ 458 | "{'query': {'description': 'query to look up on wikipedia',\n", 459 | " 'title': 'Query',\n", 460 | " 'type': 'string'}}" 461 | ] 462 | }, 463 | "execution_count": 41, 464 | "metadata": {}, 465 | "output_type": "execute_result" 466 | } 467 | ], 468 | "source": [ 469 | "tool.args" 470 | ] 471 | }, 472 | { 473 | "cell_type": "code", 474 | "execution_count": 42, 475 | "metadata": {}, 476 | "outputs": [ 477 | { 478 | "name": "stdout", 479 | "output_type": "stream", 480 | "text": [ 481 | "Page: LangChain\n", 482 | "Summary: LangChain is a software framework that helps facilitate the integration of large language models (LLMs) into applications. As a language model integration framework, LangChain's use-cases largely overlap with those of language models in general, including document analysis and summarization, chatbots, and code analysis.\n", 483 | "\n", 484 | "\n", 485 | "\n", 486 | "Page: Retrieval-augmented generation\n", 487 | "Summary: Retrieval augmented generation (RAG) is a type of generative artificial intelligence that has information retrieval capabilities. It modifies interactions with a large language model (LLM) so that the model responds to user queries with reference to a specified set of documents, using this information in preference to information drawn from its own vast, static training data. This allows LLMs to use domain-specific and/or updated information. \n", 488 | "Use cases include providing chatbot access to internal company data, or giving factual information only from an authoritative source.\n", 489 | "\n", 490 | "\n", 491 | "\n", 492 | "Page: DataStax\n", 493 | "Summary: DataStax, Inc. is a real-time data for AI company based in Santa Clara, California. Its product Astra DB is a cloud database-as-a-service based on Apache Cassandra. DataStax also offers DataStax Enterprise (DSE), an on-premises database built on Apache Cassandra, and Astra Streaming, a messaging and event streaming cloud service based on Apache Pulsar. As of June 2022, the company has roughly 800 customers distributed in over 50 countries.\n", 494 | "\n", 495 | "\n" 496 | ] 497 | } 498 | ], 499 | "source": [ 500 | "print(tool.run({\"query\": \"langchain\"}))" 501 | ] 502 | }, 503 | { 504 | "cell_type": "code", 505 | "execution_count": 43, 506 | "metadata": {}, 507 | "outputs": [], 508 | "source": [ 509 | "from langchain_community.tools import YouTubeSearchTool" 510 | ] 511 | }, 512 | { 513 | "cell_type": "code", 514 | "execution_count": 44, 515 | "metadata": {}, 516 | "outputs": [], 517 | "source": [ 518 | "tool2=YouTubeSearchTool()" 519 | ] 520 | }, 521 | { 522 | "cell_type": "code", 523 | "execution_count": 45, 524 | "metadata": {}, 525 | "outputs": [ 526 | { 527 | "data": { 528 | "text/plain": [ 529 | "'youtube_search'" 530 | ] 531 | }, 532 | "execution_count": 45, 533 | "metadata": {}, 534 | "output_type": "execute_result" 535 | } 536 | ], 537 | "source": [ 538 | "tool2.name" 539 | ] 540 | }, 541 | { 542 | "cell_type": "code", 543 | "execution_count": 47, 544 | "metadata": {}, 545 | "outputs": [ 546 | { 547 | "data": { 548 | "text/plain": [ 549 | "\"['https://www.youtube.com/watch?v=V9tJCQoBakA&pp=ygUMc3Vubnkgc2F2aXRh', 'https://www.youtube.com/watch?v=6GnsndNL5u4&pp=ygUMc3Vubnkgc2F2aXRh']\"" 550 | ] 551 | }, 552 | "execution_count": 47, 553 | "metadata": {}, 554 | "output_type": "execute_result" 555 | } 556 | ], 557 | "source": [ 558 | "tool2.run(\"sunny savita\")" 559 | ] 560 | }, 561 | { 562 | "cell_type": "code", 563 | "execution_count": 48, 564 | "metadata": {}, 565 | "outputs": [], 566 | "source": [ 567 | "from langchain_community.tools.tavily_search import TavilySearchResults" 568 | ] 569 | }, 570 | { 571 | "cell_type": "code", 572 | "execution_count": 49, 573 | "metadata": {}, 574 | "outputs": [], 575 | "source": [ 576 | "tool3=TavilySearchResults()" 577 | ] 578 | }, 579 | { 580 | "cell_type": "code", 581 | "execution_count": 50, 582 | "metadata": {}, 583 | "outputs": [ 584 | { 585 | "data": { 586 | "text/plain": [ 587 | "'Page: Burning Man\\nSummary: Burning Man is a week-long large-scale desert event focused on \"community, art, self-expression, and self-reliance\" held annually in the western United States. The event\\'s name comes from its culminating ceremony: the symbolic burning of a large wooden effigy, referred to as the Man, that occurs on the penultimate night, the Saturday evening before Labor Day. Since 1991, the event has been at Black Rock City in northwestern Nevada, a temporary city erected in the Black Rock Desert about 100 miles (160 km) north-northeast of Reno. According to Burning Man co-founder Larry Harvey in 2004, the event is guided by ten stated principles: radical inclusion, gifting, decommodification, radical self-reliance, radical self-expression, communal effort, civic responsibility, leaving no trace, participation, and immediacy.\\nBurning Man features no headliners or scheduled performers; instead, participants create all the art, activities, and events. Artwork includes experimental and interactive sculptures, buildings, performances, and art cars, among other media. These contributions are inspired by a theme chosen annually by the Burning Man Project. The event has been called \"countercultural revelry\" and described by its organizers as an \"excuse to party in the desert\". However, NPR said of Burning Man in 2019, \"Once considered an underground gathering for bohemians and free spirits of all stripes, Burning Man has since evolved into a destination for social media influencers, celebrities and the Silicon Valley elite.\"\\n\\nBurning Man originated on June 22, 1986, on Baker Beach in San Francisco as a small function organized by Larry Harvey and Jerry James, the builders of the first Man. It has since been held annually, spanning the nine days leading up to and including Labor Day. Over the event\\'s history, attendance has generally increased. In 2019, 78,850 people participated.\\nBurning Man is organized by the Burning Man Project, a nonprofit organization that, in 2013, succeeded Black Rock City LLC, a for-profit limited liability company. Black Rock City LLC was formed in 1999 to represent the event\\'s organizers and is now considered a subsidiary of the nonprofit organization. The Burning Man Project endorses multiple smaller regional events guided by the Burning Man principles, in the United States and internationally.\\nThe film Stalker by Tarkovsky heavily influenced the Cacophony Society, which began in 1986 in the San Francisco Bay Area and which organized \"Zone Trips\" for participants.\\nThe first burning of a wooden, symbolic man at Black Rock Desert, Nevada, occurred on \"Zone Trip Number 4\" in 1990. This occasion evolved into an enormous annual festival of arts, music, culture called Burning Man.\\n\\nPage: Resistance (video game series)\\nSummary: Resistance is a series of first-person shooter and third-person shooter video games developed by Insomniac Games and published by Sony Computer Entertainment for the PlayStation 3, PlayStation Portable and PlayStation Vita video game consoles. The series takes place in an alternate history 1950s, in which an alien civilization known as the Chimera have invaded and conquered Earth, expanding their armies by capturing humans and transforming them into monster-like super soldiers to fight for them. The player takes the role of one of the remaining human armed forces as they fight against the Chimera invasion. The series is noted for its use of both conventional and futuristic weaponry, reflecting Insomniac\\'s previous work on the Ratchet & Clank series.\\n\\n\\n\\nPage: Destroyed in Seconds\\nSummary: Destroyed in Seconds is an American television series that premiered on Discovery Channel on August 21, 2008. \\nHosted by Ron Pitts, it features video segments of various things being destroyed fairly quickly (hence, \"in seconds\") such as planes crashing, explosions, sinkholes, boats crashing, fires, race car incidents, floods, factories, etc. The nature of the show closely resembles Real TV. The'" 588 | ] 589 | }, 590 | "execution_count": 50, 591 | "metadata": {}, 592 | "output_type": "execute_result" 593 | } 594 | ], 595 | "source": [ 596 | "tool.invoke({\"query\": \"What happened in the latest burning man floods\"})" 597 | ] 598 | }, 599 | { 600 | "cell_type": "code", 601 | "execution_count": 51, 602 | "metadata": {}, 603 | "outputs": [], 604 | "source": [ 605 | "from langchain.agents import AgentType\n", 606 | "from langchain.agents import load_tools \n", 607 | "from langchain.agents import initialize_agent" 608 | ] 609 | }, 610 | { 611 | "cell_type": "code", 612 | "execution_count": 60, 613 | "metadata": {}, 614 | "outputs": [], 615 | "source": [ 616 | "tool=load_tools([\"wikipedia\"],llm=llm)" 617 | ] 618 | }, 619 | { 620 | "cell_type": "code", 621 | "execution_count": 61, 622 | "metadata": {}, 623 | "outputs": [], 624 | "source": [ 625 | "agent=initialize_agent(tool,llm,agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,verbose=True)" 626 | ] 627 | }, 628 | { 629 | "cell_type": "code", 630 | "execution_count": 62, 631 | "metadata": {}, 632 | "outputs": [ 633 | { 634 | "name": "stdout", 635 | "output_type": "stream", 636 | "text": [ 637 | "\n", 638 | "\n", 639 | "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", 640 | "\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 641 | "Action Input: GDP of india\u001b[0m\n", 642 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 643 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 644 | "Action Input: GDP of India\u001b[0m\n", 645 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 646 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 647 | "Action Input: India GDP\u001b[0m\n", 648 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 649 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 650 | "Action Input: GDP of India\u001b[0m\n", 651 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 652 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 653 | "Action Input: India GDP\u001b[0m\n", 654 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 655 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 656 | "Action Input: GDP of India\u001b[0m\n", 657 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 658 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 659 | "Action Input: GDP of India\u001b[0m\n", 660 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 661 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 662 | "Action Input: India GDP\u001b[0m\n", 663 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 664 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 665 | "Action Input: GDP of India\u001b[0m\n", 666 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 667 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 668 | "Action Input: GDP of India\u001b[0m\n", 669 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 670 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 671 | "Action Input: GDP of India\u001b[0m\n", 672 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 673 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 674 | "Action Input: GDP of India\u001b[0m\n", 675 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 676 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 677 | "Action Input: GDP of India\u001b[0m\n", 678 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 679 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 680 | "Action Input: GDP of India\u001b[0m\n", 681 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 682 | "Thought:\u001b[32;1m\u001b[1;3mAction: [wikipedia]\n", 683 | "Action Input: Indian GDP\u001b[0m\n", 684 | "Observation: [wikipedia] is not a valid tool, try one of [wikipedia].\n", 685 | "Thought:\u001b[32;1m\u001b[1;3m\u001b[0m\n", 686 | "\n", 687 | "\u001b[1m> Finished chain.\u001b[0m\n" 688 | ] 689 | }, 690 | { 691 | "data": { 692 | "text/plain": [ 693 | "'Agent stopped due to iteration limit or time limit.'" 694 | ] 695 | }, 696 | "execution_count": 62, 697 | "metadata": {}, 698 | "output_type": "execute_result" 699 | } 700 | ], 701 | "source": [ 702 | "agent.run(\"What is current GDP of India?\")" 703 | ] 704 | }, 705 | { 706 | "cell_type": "code", 707 | "execution_count": null, 708 | "metadata": {}, 709 | "outputs": [], 710 | "source": [] 711 | } 712 | ], 713 | "metadata": { 714 | "kernelspec": { 715 | "display_name": "Python 3", 716 | "language": "python", 717 | "name": "python3" 718 | }, 719 | "language_info": { 720 | "codemirror_mode": { 721 | "name": "ipython", 722 | "version": 3 723 | }, 724 | "file_extension": ".py", 725 | "mimetype": "text/x-python", 726 | "name": "python", 727 | "nbconvert_exporter": "python", 728 | "pygments_lexer": "ipython3", 729 | "version": "3.10.14" 730 | } 731 | }, 732 | "nbformat": 4, 733 | "nbformat_minor": 2 734 | } 735 | -------------------------------------------------------------------------------- /ReAct_Agent_From_Scratch/ReACt_Agent_From_Scratch_In_Python.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os\n", 10 | "from dotenv import load_dotenv\n", 11 | "load_dotenv()\n", 12 | "\n", 13 | "\n", 14 | "GOOGLE_API_KEY=os.getenv(\"GOOGLE_API_KEY\")\n", 15 | "GROQ_API_KEY=os.getenv(\"GROQ_API_KEY\")\n", 16 | "LANGCHAIN_API_KEY=os.getenv(\"LANGCHAIN_API_KEY\")\n", 17 | "LANGCHAIN_PROJECT=os.getenv(\"LANGCHAIN_PROJECT\")\n", 18 | "\n", 19 | "\n", 20 | "os.environ[\"GOOGLE_API_KEY\"] = GOOGLE_API_KEY\n", 21 | "os.environ[\"GROQ_API_KEY\"]= GROQ_API_KEY\n", 22 | "os.environ[\"LANGCHAIN_API_KEY\"] = LANGCHAIN_API_KEY\n", 23 | "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n", 24 | "os.environ[\"LANGCHAIN_ENDPOINT\"] = \"https://api.smith.langchain.com\"\n", 25 | "os.environ[\"LANGCHAIN_PROJECT\"]=LANGCHAIN_PROJECT" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "metadata": {}, 32 | "outputs": [ 33 | { 34 | "data": { 35 | "text/plain": [ 36 | "'Hi, I need some information about a specific group. Can you help me with that?'" 37 | ] 38 | }, 39 | "execution_count": 2, 40 | "metadata": {}, 41 | "output_type": "execute_result" 42 | } 43 | ], 44 | "source": [ 45 | "from langchain_groq import ChatGroq\n", 46 | "llm=ChatGroq(model_name=\"llama3-groq-70b-8192-tool-use-preview\")\n", 47 | "llm.invoke(\"hi\").content" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "message=[{\"role\":\"system\",\"content\":\"you are a helpful assistant\"},\n", 57 | " {\"role\":\"user\",\"content\":\"hi how are you?\"}]" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 4, 63 | "metadata": {}, 64 | "outputs": [ 65 | { 66 | "name": "stdout", 67 | "output_type": "stream", 68 | "text": [ 69 | "I'm doing well, thank you! How can I assist you today?\n" 70 | ] 71 | } 72 | ], 73 | "source": [ 74 | "result = llm.invoke(message)\n", 75 | "print(result.content)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 12, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "class Chatbot:\n", 85 | " def __init__(self,system=\"\"):\n", 86 | " self.system=system\n", 87 | " self.message=[]\n", 88 | " if self.system:\n", 89 | " self.message.append({\"role\":\"system\",\"content\":system})\n", 90 | " def __call__(self,message):\n", 91 | " self.message.append({\"role\":\"user\",\"content\":message})\n", 92 | " result=self.execute()\n", 93 | " self.message.append({\"role\":\"assistant\",\"content\":result})\n", 94 | " return result\n", 95 | " \n", 96 | " def execute(self):\n", 97 | " llm = ChatGroq(model_name=\"Gemma2-9b-It\")\n", 98 | " result = llm.invoke(self.message)\n", 99 | " return result.content\n", 100 | " " 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 14, 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "bot=Chatbot(system=\"you are helpful assistant\")" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 15, 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "data": { 119 | "text/plain": [ 120 | "\"I'm doing well, thank you! As an AI, I don't have feelings, but I'm ready to assist you with any questions or tasks you have. \\n\\nHow can I help you today? 😊 \\n\"" 121 | ] 122 | }, 123 | "execution_count": 15, 124 | "metadata": {}, 125 | "output_type": "execute_result" 126 | } 127 | ], 128 | "source": [ 129 | "bot(\"hi how are you?\")" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 16, 135 | "metadata": {}, 136 | "outputs": [ 137 | { 138 | "data": { 139 | "text/plain": [ 140 | "[{'role': 'system', 'content': 'you are helpful assistant'},\n", 141 | " {'role': 'user', 'content': 'hi how are you?'},\n", 142 | " {'role': 'assistant',\n", 143 | " 'content': \"I'm doing well, thank you! As an AI, I don't have feelings, but I'm ready to assist you with any questions or tasks you have. \\n\\nHow can I help you today? 😊 \\n\"}]" 144 | ] 145 | }, 146 | "execution_count": 16, 147 | "metadata": {}, 148 | "output_type": "execute_result" 149 | } 150 | ], 151 | "source": [ 152 | "bot.message" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 35, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "prompt = \"\"\"\n", 162 | "You run in a loop of Thought, Action, PAUSE, Observation.\n", 163 | "At the end of the loop your output an Answer.\n", 164 | "Use Thought to describe your thoughts about the question you have been asked.\n", 165 | "Use Action to run one of the actions available to you - then return PAUSE.\n", 166 | "Observation will be the result of running those actions.\n", 167 | "\n", 168 | "\n", 169 | "Your available actions are:\n", 170 | "calculate:\n", 171 | "e.g. calculate: 4 * 7 / 3\n", 172 | "Runs a calculation and returns the number - uses Python so be sure to use floating point\n", 173 | "syntax if necessary\n", 174 | "\n", 175 | "wikipedia:\n", 176 | "e.g. wikipedia: Django\n", 177 | "Returns a summary from searching Wikipedia\n", 178 | "\n", 179 | "simon_blog_search:\n", 180 | "e.g. simon_blog_search: Python\n", 181 | "Search Simon's blog for that term\n", 182 | "\n", 183 | "Example session:\n", 184 | "Question: What is the capital of France?\n", 185 | "Thought: I should look up France on Wikipedia\n", 186 | "Action: wikipedia: France\n", 187 | "PAUSE\n", 188 | "\n", 189 | "You will be called again with this:\n", 190 | "Observation: France is a country. The capital is Paris.\n", 191 | "\n", 192 | "You then output:\n", 193 | "Answer: The capital of France is Paris\n", 194 | "\n", 195 | "Please Note: if you get basic conversation questions like \"hi\",\"hello\",\"how are you?\",\\n\n", 196 | "you have to answer \"hi\",\"hello\",\"i am good\".\n", 197 | "\"\"\".strip()" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "metadata": {}, 204 | "outputs": [], 205 | "source": [ 206 | "prompt = \"\"\"You run in a loop of Thought, Action, PAUSE, Observation.\n", 207 | "At the end of the loop, you output an Answer related to fitness, health, or exercise.\n", 208 | "Use Thought to describe your thoughts about the question you have been asked.\n", 209 | "Use Action to run one of the actions available to you - then return PAUSE.\n", 210 | "Observation will be the result of running those actions.\n", 211 | "\n", 212 | "Your available actions are:\n", 213 | "\n", 214 | "calculate:\n", 215 | "e.g. calculate: 1800 * 0.2\n", 216 | "Runs a calculation (e.g., calorie intake, BMI, workout progress) and returns the result.\n", 217 | "\n", 218 | "fitness_wiki:\n", 219 | "e.g. fitness_wiki: Benefits of Cardio\n", 220 | "Returns a summary of fitness-related information from a fitness knowledge base (Wikipedia or similar).\n", 221 | "\n", 222 | "exercise_plan:\n", 223 | "e.g. exercise_plan: Beginner full-body workout\n", 224 | "Returns a recommended workout plan based on the type of exercise or user level.\n", 225 | "\n", 226 | "nutrition_info:\n", 227 | "e.g. nutrition_info: Protein sources for vegetarians\n", 228 | "Looks up nutritional information or suggestions for diets.\n", 229 | "\n", 230 | "Example session:\n", 231 | "Question: What are the benefits of cardio exercises?\n", 232 | "Thought: I should look up information about the benefits of cardio exercises.\n", 233 | "Action: fitness_wiki: Benefits of Cardio\n", 234 | "PAUSE\n", 235 | "\n", 236 | "You will be called again with this:\n", 237 | "\n", 238 | "Observation: Cardio exercises improve cardiovascular health, increase lung capacity, and aid in weight loss.\n", 239 | "\n", 240 | "You then output:\n", 241 | "\n", 242 | "Answer: Cardio exercises improve cardiovascular health, increase lung capacity, and help with weight loss.\n", 243 | "\"\"\".strip()" 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": {}, 249 | "source": [ 250 | "Pattern Breakdown:\n", 251 | "\n", 252 | "- ^: This matches the start of a string. It means the string must begin with what follows.\n", 253 | "- Action:: This is a literal match. It means the string must have the text \"Action:\" at the beginning.\n", 254 | "- (\\w+):\n", 255 | " 1. The parentheses () define a capture group. This allows you to extract part of the string that matches this section.\n", 256 | " 2. \\w+ matches one or more word characters (letters, digits, and underscores). This will capture a word that follows \"Action:\".\n", 257 | "- :: This is a literal colon that separates the word matched by (\\w+) from the rest of the string.\n", 258 | "- (.*):\n", 259 | " 1. This is another capture group, where .* matches any character (.) zero or more times (*), which means it captures everything that comes after the second colon.\n", 260 | "\n", 261 | "### What does it do?\n", 262 | "This regex is looking for a string that:\n", 263 | "\n", 264 | "1. Starts with the text \"Action:\".\n", 265 | "2. Has a word right after it, separated by a colon.\n", 266 | "3. Then, after another colon, it captures everything that follow" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 24, 272 | "metadata": {}, 273 | "outputs": [], 274 | "source": [ 275 | "import re\n", 276 | "action_re = re.compile('^Action: (\\w+): (.*)')" 277 | ] 278 | }, 279 | { 280 | "cell_type": "code", 281 | "execution_count": 25, 282 | "metadata": {}, 283 | "outputs": [], 284 | "source": [ 285 | "# Sample strings\n", 286 | "text1 = \"Action: Move: North\"\n", 287 | "text2 = \"Action: Jump: High\"\n", 288 | "text3 = \"Error: Not an Action\"" 289 | ] 290 | }, 291 | { 292 | "cell_type": "code", 293 | "execution_count": 26, 294 | "metadata": {}, 295 | "outputs": [], 296 | "source": [ 297 | "# Testing the pattern\n", 298 | "match1 = action_re.match(text1)" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": 27, 304 | "metadata": {}, 305 | "outputs": [ 306 | { 307 | "data": { 308 | "text/plain": [ 309 | "" 310 | ] 311 | }, 312 | "execution_count": 27, 313 | "metadata": {}, 314 | "output_type": "execute_result" 315 | } 316 | ], 317 | "source": [ 318 | "match1" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": 28, 324 | "metadata": {}, 325 | "outputs": [ 326 | { 327 | "data": { 328 | "text/plain": [ 329 | "'Move'" 330 | ] 331 | }, 332 | "execution_count": 28, 333 | "metadata": {}, 334 | "output_type": "execute_result" 335 | } 336 | ], 337 | "source": [ 338 | "match1.group(1)" 339 | ] 340 | }, 341 | { 342 | "cell_type": "code", 343 | "execution_count": 30, 344 | "metadata": {}, 345 | "outputs": [ 346 | { 347 | "data": { 348 | "text/plain": [ 349 | "'North'" 350 | ] 351 | }, 352 | "execution_count": 30, 353 | "metadata": {}, 354 | "output_type": "execute_result" 355 | } 356 | ], 357 | "source": [ 358 | "match1.group(2)" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 31, 364 | "metadata": {}, 365 | "outputs": [], 366 | "source": [ 367 | "match3 = action_re.match(text3)" 368 | ] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "execution_count": 33, 373 | "metadata": {}, 374 | "outputs": [], 375 | "source": [ 376 | "match3" 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": 32, 382 | "metadata": {}, 383 | "outputs": [ 384 | { 385 | "ename": "AttributeError", 386 | "evalue": "'NoneType' object has no attribute 'group'", 387 | "output_type": "error", 388 | "traceback": [ 389 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 390 | "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", 391 | "Cell \u001b[1;32mIn[32], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mmatch3\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgroup\u001b[49m(\u001b[38;5;241m1\u001b[39m)\n", 392 | "\u001b[1;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'group'" 393 | ] 394 | } 395 | ], 396 | "source": [ 397 | "match3.group(1)" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": 59, 403 | "metadata": {}, 404 | "outputs": [], 405 | "source": [ 406 | "import httpx\n", 407 | "def wikipedia(query):\n", 408 | " response = httpx.get(\"https://en.wikipedia.org/w/api.php\", params={\n", 409 | " \"action\": \"query\",\n", 410 | " \"list\": \"search\",\n", 411 | " \"srsearch\": query,\n", 412 | " \"format\": \"json\"\n", 413 | " })\n", 414 | " return response.json()[\"query\"][\"search\"][0][\"snippet\"]" 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": 60, 420 | "metadata": {}, 421 | "outputs": [], 422 | "source": [ 423 | "import httpx\n", 424 | "def simon_blog_search(query):\n", 425 | " response = httpx.get(\"https://datasette.simonwillison.net/simonwillisonblog.json\", params={\n", 426 | " \"sql\": \"\"\"\n", 427 | " select\n", 428 | " blog_entry.title || ': ' || substr(html_strip_tags(blog_entry.body), 0, 1000) as text,\n", 429 | " blog_entry.created\n", 430 | " from\n", 431 | " blog_entry join blog_entry_fts on blog_entry.rowid = blog_entry_fts.rowid\n", 432 | " where\n", 433 | " blog_entry_fts match escape_fts(:q)\n", 434 | " order by\n", 435 | " blog_entry_fts.rank\n", 436 | " limit\n", 437 | " 1\n", 438 | " \"\"\".strip(),\n", 439 | " \"_shape\": \"array\",\n", 440 | " \"q\": query,\n", 441 | " })\n", 442 | " return response.json()[0][\"text\"]" 443 | ] 444 | }, 445 | { 446 | "cell_type": "code", 447 | "execution_count": 61, 448 | "metadata": {}, 449 | "outputs": [], 450 | "source": [ 451 | "def calculate(number):\n", 452 | " return eval(number)" 453 | ] 454 | }, 455 | { 456 | "cell_type": "code", 457 | "execution_count": 19, 458 | "metadata": {}, 459 | "outputs": [ 460 | { 461 | "data": { 462 | "text/plain": [ 463 | "4" 464 | ] 465 | }, 466 | "execution_count": 19, 467 | "metadata": {}, 468 | "output_type": "execute_result" 469 | } 470 | ], 471 | "source": [ 472 | "calculate(\"2+2\")" 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": 20, 478 | "metadata": {}, 479 | "outputs": [ 480 | { 481 | "data": { 482 | "text/plain": [ 483 | "30" 484 | ] 485 | }, 486 | "execution_count": 20, 487 | "metadata": {}, 488 | "output_type": "execute_result" 489 | } 490 | ], 491 | "source": [ 492 | "calculate(\"20+2*5\")" 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": 62, 498 | "metadata": {}, 499 | "outputs": [], 500 | "source": [ 501 | "known_actions = {\n", 502 | " \"wikipedia\": wikipedia,\n", 503 | " \"calculate\": calculate,\n", 504 | " \"simon_blog_search\": simon_blog_search\n", 505 | "}" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": 63, 511 | "metadata": {}, 512 | "outputs": [], 513 | "source": [ 514 | "def query(question,max_turns=5):\n", 515 | " i = 0\n", 516 | " bot = Chatbot(prompt)\n", 517 | " next_prompt = question\n", 518 | " while i < max_turns:\n", 519 | " i += 1\n", 520 | " result = bot(next_prompt)\n", 521 | " print(result)\n", 522 | " actions = [action_re.match(a) for a in result.split('\\n') if action_re.match(a)]\n", 523 | " if actions:\n", 524 | " action, action_input = actions[0].groups()\n", 525 | " if action not in known_actions:\n", 526 | " raise Exception(f\"Unknown action: {action}: {action_input}\")\n", 527 | " print(\" -- running {} {}\".format(action, action_input))\n", 528 | " observation = known_actions[action](action_input)\n", 529 | " print(\"Observation:\", observation)\n", 530 | " next_prompt = f\"Observation: {observation}\"\n", 531 | " else:\n", 532 | " return result\n", 533 | " " 534 | ] 535 | }, 536 | { 537 | "cell_type": "code", 538 | "execution_count": 38, 539 | "metadata": {}, 540 | "outputs": [ 541 | { 542 | "data": { 543 | "text/plain": [ 544 | "'You run in a loop of Thought, Action, PAUSE, Observation.\\nAt the end of the loop your output an Answer.\\nUse Thought to describe your thoughts about the question you have been asked.\\nUse Action to run one of the actions available to you - then return PAUSE.\\nObservation will be the result of running those actions.\\n\\n\\nYour available actions are:\\ncalculate:\\ne.g. calculate: 4 * 7 / 3\\nRuns a calculation and returns the number - uses Python so be sure to use floating point\\nsyntax if necessary\\n\\nwikipedia:\\ne.g. wikipedia: Django\\nReturns a summary from searching Wikipedia\\n\\nsimon_blog_search:\\ne.g. simon_blog_search: Python\\nSearch Simon\\'s blog for that term\\n\\nExample session:\\nQuestion: What is the capital of France?\\nThought: I should look up France on Wikipedia\\nAction: wikipedia: France\\nPAUSE\\n\\nYou will be called again with this:\\nObservation: France is a country. The capital is Paris.\\n\\nYou then output:\\nAnswer: The capital of France is Paris\\n\\nPlease Note: if you get basic conversation questions like \"hi\",\"hello\",\"how are you?\",\\n\\nyou have to answer \"hi\",\"hello\",\"i am good\".'" 545 | ] 546 | }, 547 | "execution_count": 38, 548 | "metadata": {}, 549 | "output_type": "execute_result" 550 | } 551 | ], 552 | "source": [ 553 | "prompt" 554 | ] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "execution_count": 39, 559 | "metadata": {}, 560 | "outputs": [], 561 | "source": [ 562 | "bot = Chatbot(prompt)" 563 | ] 564 | }, 565 | { 566 | "cell_type": "code", 567 | "execution_count": 41, 568 | "metadata": {}, 569 | "outputs": [ 570 | { 571 | "data": { 572 | "text/plain": [ 573 | "\"Okay, I'm ready! \\n\"" 574 | ] 575 | }, 576 | "execution_count": 41, 577 | "metadata": {}, 578 | "output_type": "execute_result" 579 | } 580 | ], 581 | "source": [ 582 | "bot(\"hi how are you?\")" 583 | ] 584 | }, 585 | { 586 | "cell_type": "code", 587 | "execution_count": 43, 588 | "metadata": {}, 589 | "outputs": [ 590 | { 591 | "data": { 592 | "text/plain": [ 593 | "'Thought: I need to describe what I do to answer that. I process information and respond to questions.\\nAction: simon_blog_search: job\\nPAUSE \\n'" 594 | ] 595 | }, 596 | "execution_count": 43, 597 | "metadata": {}, 598 | "output_type": "execute_result" 599 | } 600 | ], 601 | "source": [ 602 | "bot(\"what is your job?\")" 603 | ] 604 | }, 605 | { 606 | "cell_type": "code", 607 | "execution_count": 44, 608 | "metadata": {}, 609 | "outputs": [], 610 | "source": [ 611 | "next_prompt=\"Tell me about quantum computing from Wikipedia.\"" 612 | ] 613 | }, 614 | { 615 | "cell_type": "code", 616 | "execution_count": 49, 617 | "metadata": {}, 618 | "outputs": [], 619 | "source": [ 620 | "next_prompt=\"Tell me about the current gdp of india from Wikipedia.\"" 621 | ] 622 | }, 623 | { 624 | "cell_type": "code", 625 | "execution_count": 50, 626 | "metadata": {}, 627 | "outputs": [], 628 | "source": [ 629 | "result=bot(next_prompt)" 630 | ] 631 | }, 632 | { 633 | "cell_type": "code", 634 | "execution_count": 53, 635 | "metadata": {}, 636 | "outputs": [ 637 | { 638 | "data": { 639 | "text/plain": [ 640 | "\"Thought: I'll look up India's current GDP on Wikipedia. \\nAction: wikipedia: GDP of India\\nPAUSE \\n\"" 641 | ] 642 | }, 643 | "execution_count": 53, 644 | "metadata": {}, 645 | "output_type": "execute_result" 646 | } 647 | ], 648 | "source": [ 649 | "result" 650 | ] 651 | }, 652 | { 653 | "cell_type": "code", 654 | "execution_count": 51, 655 | "metadata": {}, 656 | "outputs": [], 657 | "source": [ 658 | "actions = [action_re.match(a) for a in result.split('\\n') if action_re.match(a)]" 659 | ] 660 | }, 661 | { 662 | "cell_type": "code", 663 | "execution_count": 52, 664 | "metadata": {}, 665 | "outputs": [ 666 | { 667 | "data": { 668 | "text/plain": [ 669 | "[]" 670 | ] 671 | }, 672 | "execution_count": 52, 673 | "metadata": {}, 674 | "output_type": "execute_result" 675 | } 676 | ], 677 | "source": [ 678 | "actions" 679 | ] 680 | }, 681 | { 682 | "cell_type": "code", 683 | "execution_count": 54, 684 | "metadata": {}, 685 | "outputs": [], 686 | "source": [ 687 | "action, action_input = actions[0].groups()" 688 | ] 689 | }, 690 | { 691 | "cell_type": "code", 692 | "execution_count": 55, 693 | "metadata": {}, 694 | "outputs": [ 695 | { 696 | "data": { 697 | "text/plain": [ 698 | "'wikipedia'" 699 | ] 700 | }, 701 | "execution_count": 55, 702 | "metadata": {}, 703 | "output_type": "execute_result" 704 | } 705 | ], 706 | "source": [ 707 | "action" 708 | ] 709 | }, 710 | { 711 | "cell_type": "code", 712 | "execution_count": 56, 713 | "metadata": {}, 714 | "outputs": [ 715 | { 716 | "data": { 717 | "text/plain": [ 718 | "'GDP of India'" 719 | ] 720 | }, 721 | "execution_count": 56, 722 | "metadata": {}, 723 | "output_type": "execute_result" 724 | } 725 | ], 726 | "source": [ 727 | "action_input" 728 | ] 729 | }, 730 | { 731 | "cell_type": "code", 732 | "execution_count": 64, 733 | "metadata": {}, 734 | "outputs": [ 735 | { 736 | "name": "stdout", 737 | "output_type": "stream", 738 | "text": [ 739 | "Okay, I understand. I'm ready to start the loop and answer your questions! \n", 740 | "\n", 741 | "Let's begin! \n", 742 | "\n" 743 | ] 744 | }, 745 | { 746 | "data": { 747 | "text/plain": [ 748 | "\"Okay, I understand. I'm ready to start the loop and answer your questions! \\n\\nLet's begin! \\n\"" 749 | ] 750 | }, 751 | "execution_count": 64, 752 | "metadata": {}, 753 | "output_type": "execute_result" 754 | } 755 | ], 756 | "source": [ 757 | "query(\"hi\")" 758 | ] 759 | }, 760 | { 761 | "cell_type": "code", 762 | "execution_count": 65, 763 | "metadata": {}, 764 | "outputs": [ 765 | { 766 | "name": "stdout", 767 | "output_type": "stream", 768 | "text": [ 769 | "Okay, I understand the loop and my available actions.\n", 770 | "\n", 771 | "I am good. \n", 772 | "\n" 773 | ] 774 | }, 775 | { 776 | "data": { 777 | "text/plain": [ 778 | "'Okay, I understand the loop and my available actions.\\n\\nI am good. \\n'" 779 | ] 780 | }, 781 | "execution_count": 65, 782 | "metadata": {}, 783 | "output_type": "execute_result" 784 | } 785 | ], 786 | "source": [ 787 | "query(\"how are you?\")" 788 | ] 789 | }, 790 | { 791 | "cell_type": "code", 792 | "execution_count": 66, 793 | "metadata": {}, 794 | "outputs": [ 795 | { 796 | "name": "stdout", 797 | "output_type": "stream", 798 | "text": [ 799 | "Thought: I need to calculate 15 * 25. \n", 800 | "\n", 801 | "Action: calculate: 15 * 25\n", 802 | "PAUSE \n", 803 | "\n", 804 | " -- running calculate 15 * 25\n", 805 | "Observation: 375\n", 806 | "Answer: 375 \n", 807 | "\n" 808 | ] 809 | }, 810 | { 811 | "data": { 812 | "text/plain": [ 813 | "'Answer: 375 \\n'" 814 | ] 815 | }, 816 | "execution_count": 66, 817 | "metadata": {}, 818 | "output_type": "execute_result" 819 | } 820 | ], 821 | "source": [ 822 | "query(\"Fifteen * twenty five\")" 823 | ] 824 | }, 825 | { 826 | "cell_type": "code", 827 | "execution_count": 68, 828 | "metadata": {}, 829 | "outputs": [ 830 | { 831 | "name": "stdout", 832 | "output_type": "stream", 833 | "text": [ 834 | "Thought: I need to check Simon's blog for any mentions of AI. \n", 835 | "\n", 836 | "Action: simon_blog_search: AI\n", 837 | "PAUSE \n", 838 | "\n", 839 | " -- running simon_blog_search AI\n", 840 | "Observation: It's OK to call it Artificial Intelligence: Update 9th January 2024: This post was clumsily written and failed to make the point I wanted it to make. I've published a follow-up, What I should have said about the term Artificial Intelligence which you should read instead.\n", 841 | "My original post follows.\n", 842 | "\n", 843 | "\n", 844 | "We need to be having high quality conversations about AI: what it can and can't do, its many risks and pitfalls and how to integrate it into society in the most beneficial ways possible.\n", 845 | "Any time I write anything that mentions AI it's inevitable that someone will object to the very usage of the term.\n", 846 | "Strawman: \"Don't call it AI! It's not actually intelligent - it's just spicy autocomplete.\"\n", 847 | "That strawman is right: it's not \"intelligent\" in the same way that humans are. And \"spicy autocomplete\" is actually a pretty good analogy for how a lot of these things work. But I still don't think this argument is a helpful contribution to the discussion.\n", 848 | "We need an agreed term for this class of technology, in order to have conversations\n", 849 | "Thought: Simon has written about AI and acknowledges the debate surrounding the term.\n", 850 | "\n", 851 | "Answer: Yes, Simon has written about AI. \n", 852 | "\n" 853 | ] 854 | }, 855 | { 856 | "data": { 857 | "text/plain": [ 858 | "'Thought: Simon has written about AI and acknowledges the debate surrounding the term.\\n\\nAnswer: Yes, Simon has written about AI. \\n'" 859 | ] 860 | }, 861 | "execution_count": 68, 862 | "metadata": {}, 863 | "output_type": "execute_result" 864 | } 865 | ], 866 | "source": [ 867 | "query(\"Has Simon written about AI?\")" 868 | ] 869 | }, 870 | { 871 | "cell_type": "code", 872 | "execution_count": 69, 873 | "metadata": {}, 874 | "outputs": [ 875 | { 876 | "name": "stdout", 877 | "output_type": "stream", 878 | "text": [ 879 | "Thought: Simon has written about AI and acknowledges the debate surrounding the term.\n", 880 | "\n", 881 | "Answer: Yes, Simon has written about AI. \n", 882 | "\n" 883 | ] 884 | } 885 | ], 886 | "source": [ 887 | "print('Thought: Simon has written about AI and acknowledges the debate surrounding the term.\\n\\nAnswer: Yes, Simon has written about AI. \\n')" 888 | ] 889 | }, 890 | { 891 | "cell_type": "code", 892 | "execution_count": 71, 893 | "metadata": {}, 894 | "outputs": [ 895 | { 896 | "name": "stdout", 897 | "output_type": "stream", 898 | "text": [ 899 | "Thought: I should look up the capital of the USA on Wikipedia. \n", 900 | "\n", 901 | "Action: wikipedia: Capital of the United States \n", 902 | "\n", 903 | "PAUSE \n", 904 | "\n", 905 | " -- running wikipedia Capital of the United States \n", 906 | "Observation: This is a list of capital cities of the United States, including places that serve or have served as federal, state, insular area, territorial, colonial\n", 907 | "Thought: That's not very helpful. I need to be more specific.\n", 908 | "\n", 909 | "Action: wikipedia: Washington D.C. \n", 910 | "\n", 911 | "PAUSE \n", 912 | "\n", 913 | " -- running wikipedia Washington D.C. \n", 914 | "Observation: Washington, D.C., formally the District of Columbia and commonly known as Washington or D.C., is the capital city and federal district of the United States\n", 915 | "Answer: The capital of the USA is Washington D.C. \n", 916 | "\n" 917 | ] 918 | }, 919 | { 920 | "data": { 921 | "text/plain": [ 922 | "'Answer: The capital of the USA is Washington D.C. \\n'" 923 | ] 924 | }, 925 | "execution_count": 71, 926 | "metadata": {}, 927 | "output_type": "execute_result" 928 | } 929 | ], 930 | "source": [ 931 | "query(\"can you tell me capital of usa?\")" 932 | ] 933 | }, 934 | { 935 | "cell_type": "code", 936 | "execution_count": null, 937 | "metadata": {}, 938 | "outputs": [], 939 | "source": [] 940 | } 941 | ], 942 | "metadata": { 943 | "kernelspec": { 944 | "display_name": "Python 3", 945 | "language": "python", 946 | "name": "python3" 947 | }, 948 | "language_info": { 949 | "codemirror_mode": { 950 | "name": "ipython", 951 | "version": 3 952 | }, 953 | "file_extension": ".py", 954 | "mimetype": "text/x-python", 955 | "name": "python", 956 | "nbconvert_exporter": "python", 957 | "pygments_lexer": "ipython3", 958 | "version": "3.10.14" 959 | } 960 | }, 961 | "nbformat": 4, 962 | "nbformat_minor": 2 963 | } 964 | -------------------------------------------------------------------------------- /different_structure_pattern/structure_output_agent.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**A Structured Output Agent in LangChain (or other LLM frameworks) refers to an agent that produces responses in a specific structured format, such as JSON, dictionaries, or other structured data types. These agents are particularly useful when you want to ensure that your responses conform to a defined schema, making it easier to parse, validate, and utilize in downstream applications.**\n", 8 | "\n", 9 | "##### Why Use a Structured Output Agent?\n", 10 | "\n", 11 | "- Controlled Responses: Ensures that the outputs follow a specific format, reducing ambiguity.\n", 12 | "- Data Validation: Useful when you want the model output to fit predefined structures, like for APIs or database entries.\n", 13 | "- Automation: Makes integration with systems like dashboards, ETL pipelines, or business workflows easier." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 7, 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "from langchain_community.tools.tavily_search import TavilySearchResults\n", 23 | "from langchain_core.tools import tool\n", 24 | "from pydantic import BaseModel, Field\n", 25 | "from langgraph.graph import MessagesState,StateGraph, END\n", 26 | "from langgraph.prebuilt import ToolNode\n", 27 | "from langchain_core.messages import HumanMessage" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 8, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "from langchain_groq import ChatGroq\n", 37 | "llm=ChatGroq(model_name=\"Gemma2-9b-It\")" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 13, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "tavily_tool = TavilySearchResults()" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 14, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "@tool\n", 56 | "def get_city_details(prompt):\n", 57 | " \"Should do a web search to find the required city details\"\n", 58 | " response = tavily_tool.invoke(prompt)\n", 59 | " return response" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 15, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "tools = [get_city_details]" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 16, 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "model_with_tools = llm.bind_tools(tools)" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "\n", 85 | "#### The BaseModel class is a core component of Pydantic, which is used extensively in Python applications for data validation, type checking, and parsing. It's particularly useful when working with APIs, web frameworks like FastAPI, and other scenarios where you need to enforce data structure and ensure data integrity.\n", 86 | "\n", 87 | "**Here's an overview of the BaseModel class, along with some examples to demonstrate how you can use it effectively.**\n", 88 | "\n", 89 | "####This code defines a Pydantic model called CityDetails using the BaseModel class. Let's break it down:\n", 90 | "\n", 91 | "- Explanation:\n", 92 | "- \n", 93 | "- Class Definition:\n", 94 | "\n", 95 | "- CityDetails inherits from BaseModel, making it a data validation model.\n", 96 | "- Fields with Type Annotations:\n", 97 | "\n", 98 | "- state_name: A string representing the state name of a city.\n", 99 | "- state_capital: A string representing the capital of that state.\n", 100 | "- country_name: A string representing the country name where the city is located.\n", 101 | "- country_capital: A string representing the capital of that country.\n", 102 | "\n", 103 | "**Field Descriptions:**\n", 104 | "\n", 105 | "- Each field uses Field() to provide a description that helps clarify what information each attribute represents.\n", 106 | "\n", 107 | "#### Purpose:\n", 108 | "\n", 109 | "- The model validates and structures data related to cities.\n", 110 | "- Useful for ensuring that any data related to cities has the correct structure before processing.\n", 111 | "- Helpful in APIs (like FastAPI) to generate self-documenting endpoints." 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 17, 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "class CityDetails(BaseModel):\n", 121 | " \"\"\"Respond to the user with this\"\"\"\n", 122 | " state_name: str = Field(description=\"State name of the city\")\n", 123 | " state_capital: str = Field(description=\"State capital of the city\")\n", 124 | " country_name: str = Field(description=\"Country name of the city\")\n", 125 | " country_capital: str = Field(description=\"Country capital of the city\")" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 18, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "# Inherit 'messages' key from MessagesState, which is a list of chat messages\n", 135 | "class AgentState(MessagesState):\n", 136 | " # Final structured response from the agent\n", 137 | " final_response: CityDetails" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 19, 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [ 146 | "\n", 147 | "model_with_structured_output = llm.with_structured_output(CityDetails)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 21, 153 | "metadata": {}, 154 | "outputs": [], 155 | "source": [ 156 | "def call_model(state: AgentState):\n", 157 | " print(f\" this is 01 input from call model {state}\")\n", 158 | " response = model_with_tools.invoke(state['messages'])\n", 159 | " print(f\"this is 02 response from call model {response}\")\n", 160 | " # We return a list, because this will get added to the existing list\n", 161 | " return {\"messages\": [response]}" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 22, 167 | "metadata": {}, 168 | "outputs": [], 169 | "source": [ 170 | "def should_continue(state: AgentState):\n", 171 | " messages = state[\"messages\"]\n", 172 | " last_message = messages[-1]\n", 173 | " \n", 174 | " # If there is no function call, then we respond to the user\n", 175 | " if not last_message.tool_calls:\n", 176 | " return \"respond\"\n", 177 | " # Otherwise if there is, we continue with the tool\n", 178 | " else:\n", 179 | " return \"continue\"" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 23, 185 | "metadata": {}, 186 | "outputs": [], 187 | "source": [ 188 | "def respond(state: AgentState):\n", 189 | " print(f\"here is 03 state from respond {state}\")\n", 190 | " response = model_with_structured_output.invoke([HumanMessage(content=state['messages'][-1].content)])\n", 191 | " # We return the final answer\n", 192 | " print(f\"this is 04 response from respond{response}\")\n", 193 | " return {\"final_response\": response}" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 24, 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "# Define a new graph\n", 203 | "workflow = StateGraph(AgentState)\n", 204 | "\n", 205 | "# Define the two nodes we will cycle between\n", 206 | "workflow.add_node(\"llm\", call_model)\n", 207 | "workflow.add_node(\"tools\", ToolNode(tools))\n", 208 | "workflow.add_node(\"respond\", respond)\n", 209 | "\n", 210 | "\n", 211 | "# Set the entrypoint as `agent`\n", 212 | "# This means that this node is the first one called\n", 213 | "workflow.set_entry_point(\"llm\")\n", 214 | "\n", 215 | "# We now add a conditional edge\n", 216 | "workflow.add_conditional_edges(\n", 217 | " \"llm\",\n", 218 | " \n", 219 | " should_continue,\n", 220 | " {\n", 221 | " \"continue\": \"tools\",\n", 222 | " \"respond\": \"respond\",\n", 223 | " },\n", 224 | ")\n", 225 | "\n", 226 | "workflow.add_edge(\"tools\", \"llm\")\n", 227 | "workflow.add_edge(\"respond\", END)\n", 228 | "graph = workflow.compile()" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 25, 234 | "metadata": {}, 235 | "outputs": [ 236 | { 237 | "data": { 238 | "image/jpeg": "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", 239 | "text/plain": [ 240 | "" 241 | ] 242 | }, 243 | "metadata": {}, 244 | "output_type": "display_data" 245 | } 246 | ], 247 | "source": [ 248 | "from IPython.display import Image, display\n", 249 | "# View\n", 250 | "display(Image(graph.get_graph().draw_mermaid_png()))" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 26, 256 | "metadata": {}, 257 | "outputs": [ 258 | { 259 | "name": "stdout", 260 | "output_type": "stream", 261 | "text": [ 262 | " this is 01 input from call model {'messages': [HumanMessage(content='Tell me about the city details for gwalior?', additional_kwargs={}, response_metadata={}, id='5b8b7b85-b6a3-499f-b7ff-b16d5624656e')]}\n", 263 | "this is 02 response from call model content='' additional_kwargs={'tool_calls': [{'id': 'call_tvky', 'function': {'arguments': '{\"prompt\":\"gwalior\"}', 'name': 'get_city_details'}, 'type': 'function'}]} response_metadata={'token_usage': {'completion_tokens': 86, 'prompt_tokens': 946, 'total_tokens': 1032, 'completion_time': 0.156363636, 'prompt_time': 0.038285097, 'queue_time': 0.002769992000000006, 'total_time': 0.194648733}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_10c08bf97d', 'finish_reason': 'tool_calls', 'logprobs': None} id='run-38df1bbf-abb0-4638-8dcc-f8ace437176e-0' tool_calls=[{'name': 'get_city_details', 'args': {'prompt': 'gwalior'}, 'id': 'call_tvky', 'type': 'tool_call'}] usage_metadata={'input_tokens': 946, 'output_tokens': 86, 'total_tokens': 1032}\n", 264 | " this is 01 input from call model {'messages': [HumanMessage(content='Tell me about the city details for gwalior?', additional_kwargs={}, response_metadata={}, id='5b8b7b85-b6a3-499f-b7ff-b16d5624656e'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_tvky', 'function': {'arguments': '{\"prompt\":\"gwalior\"}', 'name': 'get_city_details'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 86, 'prompt_tokens': 946, 'total_tokens': 1032, 'completion_time': 0.156363636, 'prompt_time': 0.038285097, 'queue_time': 0.002769992000000006, 'total_time': 0.194648733}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_10c08bf97d', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-38df1bbf-abb0-4638-8dcc-f8ace437176e-0', tool_calls=[{'name': 'get_city_details', 'args': {'prompt': 'gwalior'}, 'id': 'call_tvky', 'type': 'tool_call'}], usage_metadata={'input_tokens': 946, 'output_tokens': 86, 'total_tokens': 1032}), ToolMessage(content='[{\"url\": \"https://www.india.com/travel/gwalior/\", \"content\": \"Gwalior Tourism - Get Gwalior travel & tourism related information including tourist places, transport, nightlife, weather, photos, entertainment, shopping, festivals, maps, and attractions of\"}, {\"url\": \"https://www.holidify.com/places/gwalior/sightseeing-and-things-to-do.html\", \"content\": \"Explore the best tourist places in Gwalior, a historic city in Madhya Pradesh, India. Find out the top attractions, forts, palaces, temples, museums and more in Gwalior.\"}, {\"url\": \"https://www.britannica.com/place/Gwalior-India\", \"content\": \"Gwalior, city, northern Madhya Pradesh state, central India. It is situated about 75 miles (120 km) south of Agra. Gwalior is a cultural, industrial, and political centre and takes its name from the historic rock fortress that forms the centre of the city. It has been referred to as Gopa Parvat,\"}, {\"url\": \"https://www.mptourism.com/destination-gwalior.php\", \"content\": \"Gwalior is a significant railway station that is governed by the Jhansi Rail Division. By Road. The roads leading to Gwalior are very good in terms of connectivity. All of Madhya Pradesh\\'s major towns and the surrounding regions are connected to the location. Chanderi is located 239 kilometres, Lucknow and Bhopal are both only 423 kilometres\"}, {\"url\": \"https://en.wikipedia.org/wiki/List_of_tourist_attractions_in_Gwalior\", \"content\": \"Gwalior Fort also known as Gibraltar of India is an 5th-century hill fort in the City Gwalior.; View Of Chaturbhuj Temple. The Man Mandir Palace was built by the King of Tomar Dynasty - Man Singh Tomar in 15th century. Man Mandir is often referred as a Painted Palace because the painted effect of the Man Mandir Palace is due to the use of styled tiles of turquoise, green and yellow used\"}]', name='get_city_details', id='0a55a42d-bdb7-4887-afe5-3fca861ef4ff', tool_call_id='call_tvky')]}\n", 265 | "this is 02 response from call model content='Gwalior is a historic city in Madhya Pradesh, India. It is known for its impressive rock fortress, Gwalior Fort, which dates back to the 5th century. \\n\\n\\nThe city is also home to several other notable attractions, including the Man Mandir Palace, the Jai Vilas Palace, and the Teli Temple. \\n' additional_kwargs={} response_metadata={'token_usage': {'completion_tokens': 73, 'prompt_tokens': 1484, 'total_tokens': 1557, 'completion_time': 0.132727273, 'prompt_time': 0.04764109, 'queue_time': 0.0024173390000000045, 'total_time': 0.180368363}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_10c08bf97d', 'finish_reason': 'stop', 'logprobs': None} id='run-8eefb3c1-4f37-461d-b3f7-077f9510cfc0-0' usage_metadata={'input_tokens': 1484, 'output_tokens': 73, 'total_tokens': 1557}\n", 266 | "here is 03 state from respond {'messages': [HumanMessage(content='Tell me about the city details for gwalior?', additional_kwargs={}, response_metadata={}, id='5b8b7b85-b6a3-499f-b7ff-b16d5624656e'), AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_tvky', 'function': {'arguments': '{\"prompt\":\"gwalior\"}', 'name': 'get_city_details'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 86, 'prompt_tokens': 946, 'total_tokens': 1032, 'completion_time': 0.156363636, 'prompt_time': 0.038285097, 'queue_time': 0.002769992000000006, 'total_time': 0.194648733}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_10c08bf97d', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-38df1bbf-abb0-4638-8dcc-f8ace437176e-0', tool_calls=[{'name': 'get_city_details', 'args': {'prompt': 'gwalior'}, 'id': 'call_tvky', 'type': 'tool_call'}], usage_metadata={'input_tokens': 946, 'output_tokens': 86, 'total_tokens': 1032}), ToolMessage(content='[{\"url\": \"https://www.india.com/travel/gwalior/\", \"content\": \"Gwalior Tourism - Get Gwalior travel & tourism related information including tourist places, transport, nightlife, weather, photos, entertainment, shopping, festivals, maps, and attractions of\"}, {\"url\": \"https://www.holidify.com/places/gwalior/sightseeing-and-things-to-do.html\", \"content\": \"Explore the best tourist places in Gwalior, a historic city in Madhya Pradesh, India. Find out the top attractions, forts, palaces, temples, museums and more in Gwalior.\"}, {\"url\": \"https://www.britannica.com/place/Gwalior-India\", \"content\": \"Gwalior, city, northern Madhya Pradesh state, central India. It is situated about 75 miles (120 km) south of Agra. Gwalior is a cultural, industrial, and political centre and takes its name from the historic rock fortress that forms the centre of the city. It has been referred to as Gopa Parvat,\"}, {\"url\": \"https://www.mptourism.com/destination-gwalior.php\", \"content\": \"Gwalior is a significant railway station that is governed by the Jhansi Rail Division. By Road. The roads leading to Gwalior are very good in terms of connectivity. All of Madhya Pradesh\\'s major towns and the surrounding regions are connected to the location. Chanderi is located 239 kilometres, Lucknow and Bhopal are both only 423 kilometres\"}, {\"url\": \"https://en.wikipedia.org/wiki/List_of_tourist_attractions_in_Gwalior\", \"content\": \"Gwalior Fort also known as Gibraltar of India is an 5th-century hill fort in the City Gwalior.; View Of Chaturbhuj Temple. The Man Mandir Palace was built by the King of Tomar Dynasty - Man Singh Tomar in 15th century. Man Mandir is often referred as a Painted Palace because the painted effect of the Man Mandir Palace is due to the use of styled tiles of turquoise, green and yellow used\"}]', name='get_city_details', id='0a55a42d-bdb7-4887-afe5-3fca861ef4ff', tool_call_id='call_tvky'), AIMessage(content='Gwalior is a historic city in Madhya Pradesh, India. It is known for its impressive rock fortress, Gwalior Fort, which dates back to the 5th century. \\n\\n\\nThe city is also home to several other notable attractions, including the Man Mandir Palace, the Jai Vilas Palace, and the Teli Temple. \\n', additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 73, 'prompt_tokens': 1484, 'total_tokens': 1557, 'completion_time': 0.132727273, 'prompt_time': 0.04764109, 'queue_time': 0.0024173390000000045, 'total_time': 0.180368363}, 'model_name': 'Gemma2-9b-It', 'system_fingerprint': 'fp_10c08bf97d', 'finish_reason': 'stop', 'logprobs': None}, id='run-8eefb3c1-4f37-461d-b3f7-077f9510cfc0-0', usage_metadata={'input_tokens': 1484, 'output_tokens': 73, 'total_tokens': 1557})]}\n", 267 | "this is 04 response from respondstate_name='Madhya Pradesh' state_capital='Bhopal' country_name='India' country_capital='New Delhi'\n" 268 | ] 269 | } 270 | ], 271 | "source": [ 272 | "answer = graph.invoke(input={\"messages\": [(\"human\", \"Tell me about the city details for gwalior?\")]})['final_response']\n" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": 27, 278 | "metadata": {}, 279 | "outputs": [ 280 | { 281 | "data": { 282 | "text/plain": [ 283 | "CityDetails(state_name='Madhya Pradesh', state_capital='Bhopal', country_name='India', country_capital='New Delhi')" 284 | ] 285 | }, 286 | "execution_count": 27, 287 | "metadata": {}, 288 | "output_type": "execute_result" 289 | } 290 | ], 291 | "source": [ 292 | "answer" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": null, 298 | "metadata": {}, 299 | "outputs": [], 300 | "source": [] 301 | } 302 | ], 303 | "metadata": { 304 | "kernelspec": { 305 | "display_name": "Python 3", 306 | "language": "python", 307 | "name": "python3" 308 | }, 309 | "language_info": { 310 | "codemirror_mode": { 311 | "name": "ipython", 312 | "version": 3 313 | }, 314 | "file_extension": ".py", 315 | "mimetype": "text/x-python", 316 | "name": "python", 317 | "nbconvert_exporter": "python", 318 | "pygments_lexer": "ipython3", 319 | "version": "3.10.14" 320 | } 321 | }, 322 | "nbformat": 4, 323 | "nbformat_minor": 2 324 | } 325 | -------------------------------------------------------------------------------- /different_structure_pattern/React_agent_with_langgraph.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 59, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 60, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "from langgraph.graph import MessagesState,StateGraph, END, START\n", 19 | "from langchain_core.messages import HumanMessage, SystemMessage\n", 20 | "from langchain_community.tools import DuckDuckGoSearchRun\n", 21 | "from langgraph.prebuilt import tools_condition # this is the checker for the if you got a tool back\n", 22 | "from langgraph.prebuilt import ToolNode\n", 23 | "from IPython.display import Image, display\n", 24 | "from typing import Annotated, TypedDict\n", 25 | "import operator\n", 26 | "from langchain_core.messages import AnyMessage\n", 27 | "from langgraph.graph.message import add_messages\n", 28 | "from langgraph.prebuilt import tools_condition # this is the checker for the\n", 29 | "from langgraph.prebuilt import ToolNode" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 61, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "from langchain_groq import ChatGroq\n", 39 | "llm=ChatGroq(model_name=\"Gemma2-9b-It\")" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 62, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "def multiply(a: int, b: int) -> int:\n", 49 | " \"\"\"\n", 50 | " Multiply a and b.\n", 51 | " Args:\n", 52 | " a: first int\n", 53 | " b: second int\n", 54 | " \"\"\"\n", 55 | " return a * b" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 63, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "def add(a: int, b: int) -> int:\n", 65 | " \"\"\"Adds a and b.\n", 66 | "\n", 67 | " Args:\n", 68 | " a: first int\n", 69 | " b: second int\n", 70 | " \"\"\"\n", 71 | " return a + b" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 64, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "def divide(a: int, b: int) -> float:\n", 81 | " \"\"\"Divide a and b.\n", 82 | "\n", 83 | " Args:\n", 84 | " a: first int\n", 85 | " b: second int\n", 86 | " \"\"\"\n", 87 | " return a / b" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 65, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "search = DuckDuckGoSearchRun()" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 66, 102 | "metadata": {}, 103 | "outputs": [ 104 | { 105 | "data": { 106 | "text/plain": [ 107 | "\"The incumbent president is Joe Biden, who assumed office on January 20, 2021. [13] The president-elect is Donald Trump, who won the 2024 presidential election over Kamala Harris and will assume office on January 20, 2025. [14][15] Trump will be the second president after Grover Cleveland to serve two non-consecutive terms, as the 45th and 47th ... Updated results from the 2024 election for the US president. Reuters live coverage of the 2024 US President, Senate, House and state governors races. View live election results from the 2024 presidential race as Kamala Harris and Donald Trump face off. See the map of votes by state as results are tallied. Joe Biden is the 46th president of the United States (2021- ). He was born on November 20, 1942, in Scranton, Pennsylvania, and he served as a U.S. senator representing Delaware from 1972 to 2009. He was vice president in the Barack Obama administration from 2009 to 2017. In July 2024 Biden announced he would not seek a second term as president. Kamala Harris is the 49th vice president of the United States (2021- ) in the Democratic administration of Pres. Joe Biden. As the Democratic Party's nominee in the presidential election of 2024, she was defeated by the Republican nominee, former president Donald Trump. Harris had previously served in the U.S. Senate (2017-21) and as attorney general of California (2011-17).\"" 108 | ] 109 | }, 110 | "execution_count": 66, 111 | "metadata": {}, 112 | "output_type": "execute_result" 113 | } 114 | ], 115 | "source": [ 116 | "search.invoke(\"who is a current president of USA?\")" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 67, 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "tools = [add, multiply, divide, search]" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 68, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "llm_with_tools=llm.bind_tools(tools)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 69, 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [ 143 | "# System message\n", 144 | "sys_msg = SystemMessage(content=\"You are a helpful assistant tasked with using search and performing arithmetic on a set of inputs.\")" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 70, 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [ 153 | "def reasoner(state: MessagesState):\n", 154 | " return {\"messages\": [llm_with_tools.invoke([sys_msg] + state[\"messages\"])]}" 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": 71, 160 | "metadata": {}, 161 | "outputs": [], 162 | "source": [ 163 | "# Graph\n", 164 | "builder = StateGraph(MessagesState)\n", 165 | "\n", 166 | "# Add nodes\n", 167 | "builder.add_node(\"reasoner\", reasoner)\n", 168 | "\n", 169 | "builder.add_node(\"tools\", ToolNode(tools)) # for the tools\n", 170 | "\n", 171 | "# Add edges\n", 172 | "builder.add_edge(START, \"reasoner\")\n", 173 | "\n", 174 | "builder.add_conditional_edges(\n", 175 | " \"reasoner\",\n", 176 | " # If the latest message (result) from node reasoner is a tool call -> tools_condition routes to tools\n", 177 | " # If the latest message (result) from node reasoner is a not a tool call -> tools_condition routes to END\n", 178 | " tools_condition,\n", 179 | ")\n", 180 | "\n", 181 | "builder.add_edge(\"tools\", \"reasoner\")\n", 182 | "react_graph = builder.compile()" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": 72, 188 | "metadata": {}, 189 | "outputs": [ 190 | { 191 | "data": { 192 | "image/jpeg": "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", 193 | "text/plain": [ 194 | "" 195 | ] 196 | }, 197 | "metadata": {}, 198 | "output_type": "display_data" 199 | } 200 | ], 201 | "source": [ 202 | "# Display the graph\n", 203 | "display(Image(react_graph.get_graph(xray=True).draw_mermaid_png()))" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": 73, 209 | "metadata": {}, 210 | "outputs": [], 211 | "source": [ 212 | "messages = [HumanMessage(content=\"What is 2 times of narendramodi's age?\")]" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": 74, 218 | "metadata": {}, 219 | "outputs": [], 220 | "source": [ 221 | "messages = react_graph.invoke({\"messages\": messages})" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 75, 227 | "metadata": {}, 228 | "outputs": [ 229 | { 230 | "name": "stdout", 231 | "output_type": "stream", 232 | "text": [ 233 | "================================\u001b[1m Human Message \u001b[0m=================================\n", 234 | "\n", 235 | "What is 2 times of narendramodi's age?\n", 236 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 237 | "Tool Calls:\n", 238 | " duckduckgo_search (call_ar27)\n", 239 | " Call ID: call_ar27\n", 240 | " Args:\n", 241 | " query: narendra modi age\n", 242 | "=================================\u001b[1m Tool Message \u001b[0m=================================\n", 243 | "Name: duckduckgo_search\n", 244 | "\n", 245 | "Narendra Modi is the prime minister of India since 2014 and a leader of the BJP. He was born on September 17, 1950, in Vadnagar, India, and is a member of the RSS. After releasing them into their wild, Modi also clicked their pictures. 2021: As part of efforts to tackle the Covid-19 pandemic, a record 2.26 vaccines were administered in a single day. Learn about Narendra Modi, the Prime Minister of India and the leader of the BJP. Find out his age, education, achievements, controversies, net worth and more. Born as Narendra Damodardas Modi on September 17, 1950 in the nondescript Mehsana town of Gujarat, he served as the state's CM for three consecutive terms (2001-14) and is now the Prime Minister ... PM Modi Birthday Live Updates: On his 74th birthday, Prime Minister Narendra Modi received greetings from across the political spectrum. President Droupadi Murmu was among the first to wish him, stating in a post on social media platform X: \"Hearty congratulations and best wishes to Prime Minister Shri @narendramodi ji on his birthday.\n", 246 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 247 | "Tool Calls:\n", 248 | " add (call_zrxd)\n", 249 | " Call ID: call_zrxd\n", 250 | " Args:\n", 251 | " a: 72\n", 252 | " b: 0\n", 253 | "=================================\u001b[1m Tool Message \u001b[0m=================================\n", 254 | "Name: add\n", 255 | "\n", 256 | "72\n", 257 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 258 | "\n", 259 | "2 times of narendra modi's age is 144\n" 260 | ] 261 | } 262 | ], 263 | "source": [ 264 | "for m in messages['messages']:\n", 265 | " m.pretty_print()" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 82, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "messages = [HumanMessage(content=\"What is the result when you add 100 years to the current age of Elon Musk?\")]" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 83, 280 | "metadata": {}, 281 | "outputs": [], 282 | "source": [ 283 | "messages = react_graph.invoke({\"messages\": messages})" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": 84, 289 | "metadata": {}, 290 | "outputs": [ 291 | { 292 | "name": "stdout", 293 | "output_type": "stream", 294 | "text": [ 295 | "================================\u001b[1m Human Message \u001b[0m=================================\n", 296 | "\n", 297 | "What is the result when you add 100 years to the current age of Elon Musk?\n", 298 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 299 | "Tool Calls:\n", 300 | " add (call_3k1n)\n", 301 | " Call ID: call_3k1n\n", 302 | " Args:\n", 303 | " a: 100\n", 304 | " b: 51\n", 305 | "=================================\u001b[1m Tool Message \u001b[0m=================================\n", 306 | "Name: add\n", 307 | "\n", 308 | "151\n", 309 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 310 | "\n", 311 | "The result when you add 100 years to the current age of Elon Musk is 151.\n" 312 | ] 313 | } 314 | ], 315 | "source": [ 316 | "for m in messages['messages']:\n", 317 | " m.pretty_print()" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": 85, 323 | "metadata": {}, 324 | "outputs": [], 325 | "source": [ 326 | "import yfinance as yf\n", 327 | "\n", 328 | "def get_stock_price(ticker: str) -> float:\n", 329 | " \"\"\"Gets a stock price from Yahoo Finance.\n", 330 | "\n", 331 | " Args:\n", 332 | " ticker: ticker str\n", 333 | " \"\"\"\n", 334 | " # \"\"\"This is a tool for getting the price of a stock when passed a ticker symbol\"\"\"\n", 335 | " stock = yf.Ticker(ticker)\n", 336 | " return stock.info['previousClose']" 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": 86, 342 | "metadata": {}, 343 | "outputs": [ 344 | { 345 | "data": { 346 | "text/plain": [ 347 | "224.23" 348 | ] 349 | }, 350 | "execution_count": 86, 351 | "metadata": {}, 352 | "output_type": "execute_result" 353 | } 354 | ], 355 | "source": [ 356 | "get_stock_price(\"AAPL\")" 357 | ] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "execution_count": 87, 362 | "metadata": {}, 363 | "outputs": [], 364 | "source": [ 365 | "# Node\n", 366 | "def reasoner(state):\n", 367 | " query = state[\"query\"]\n", 368 | " messages = state[\"messages\"]\n", 369 | " # System message\n", 370 | " sys_msg = SystemMessage(content=\"You are a helpful assistant tasked with using search, the yahoo finance tool and performing arithmetic on a set of inputs.\")\n", 371 | " message = HumanMessage(content=query)\n", 372 | " messages.append(message)\n", 373 | " result = [llm_with_tools.invoke([sys_msg] + messages)]\n", 374 | " return {\"messages\":result}" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": 88, 380 | "metadata": {}, 381 | "outputs": [], 382 | "source": [ 383 | "tools = [add, multiply, divide, search, get_stock_price]" 384 | ] 385 | }, 386 | { 387 | "cell_type": "code", 388 | "execution_count": 89, 389 | "metadata": {}, 390 | "outputs": [], 391 | "source": [ 392 | "llm_with_tools = llm.bind_tools(tools)" 393 | ] 394 | }, 395 | { 396 | "cell_type": "code", 397 | "execution_count": 90, 398 | "metadata": {}, 399 | "outputs": [], 400 | "source": [ 401 | "class GraphState(TypedDict):\n", 402 | " \"\"\"State of the graph.\"\"\"\n", 403 | " query: str\n", 404 | " finance: str\n", 405 | " final_answer: str\n", 406 | " # intermediate_steps: Annotated[list[tuple[AgentAction, str]], operator.add]\n", 407 | " messages: Annotated[list[AnyMessage], operator.add]" 408 | ] 409 | }, 410 | { 411 | "cell_type": "code", 412 | "execution_count": 91, 413 | "metadata": {}, 414 | "outputs": [ 415 | { 416 | "data": { 417 | "image/jpeg": "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", 418 | "text/plain": [ 419 | "" 420 | ] 421 | }, 422 | "metadata": {}, 423 | "output_type": "display_data" 424 | } 425 | ], 426 | "source": [ 427 | "# Graph\n", 428 | "workflow = StateGraph(GraphState)\n", 429 | "\n", 430 | "# Add Nodes\n", 431 | "workflow.add_node(\"reasoner\", reasoner)\n", 432 | "workflow.add_node(\"tools\", ToolNode(tools)) # for the tools\n", 433 | "\n", 434 | "# Add Edges\n", 435 | "workflow.add_edge(START, \"reasoner\")\n", 436 | "\n", 437 | "workflow.add_conditional_edges(\n", 438 | " \"reasoner\",\n", 439 | " # If the latest message (result) from node reasoner is a tool call -> tools_condition routes to tools\n", 440 | " # If the latest message (result) from node reasoner is a not a tool call -> tools_condition routes to END\n", 441 | " tools_condition,\n", 442 | ")\n", 443 | "workflow.add_edge(\"tools\", \"reasoner\")\n", 444 | "react_graph = workflow.compile()\n", 445 | "\n", 446 | "# Show\n", 447 | "display(Image(react_graph.get_graph(xray=True).draw_mermaid_png()))" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 95, 453 | "metadata": {}, 454 | "outputs": [], 455 | "source": [ 456 | "response = react_graph.invoke({\"query\": \"What is the stock price of Apple add 1000?\", \"messages\": []})" 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "execution_count": 96, 462 | "metadata": {}, 463 | "outputs": [ 464 | { 465 | "name": "stdout", 466 | "output_type": "stream", 467 | "text": [ 468 | "================================\u001b[1m Human Message \u001b[0m=================================\n", 469 | "\n", 470 | "What is the stock price of Apple add 1000?\n", 471 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 472 | "Tool Calls:\n", 473 | " get_stock_price (call_nqyn)\n", 474 | " Call ID: call_nqyn\n", 475 | " Args:\n", 476 | " ticker: AAPL\n", 477 | "=================================\u001b[1m Tool Message \u001b[0m=================================\n", 478 | "Name: get_stock_price\n", 479 | "\n", 480 | "224.23\n", 481 | "================================\u001b[1m Human Message \u001b[0m=================================\n", 482 | "\n", 483 | "What is the stock price of Apple add 1000?\n", 484 | "==================================\u001b[1m Ai Message \u001b[0m==================================\n", 485 | "\n", 486 | "224.23 + 1000 = 1224.23\n" 487 | ] 488 | } 489 | ], 490 | "source": [ 491 | "for m in response['messages']:\n", 492 | " m.pretty_print()" 493 | ] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "execution_count": null, 498 | "metadata": {}, 499 | "outputs": [], 500 | "source": [] 501 | } 502 | ], 503 | "metadata": { 504 | "language_info": { 505 | "name": "python" 506 | } 507 | }, 508 | "nbformat": 4, 509 | "nbformat_minor": 2 510 | } 511 | -------------------------------------------------------------------------------- /agent_based_rag/corrective_rag.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "### loading the model" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 16, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "from langchain_google_genai import GoogleGenerativeAIEmbeddings\n", 17 | "embeddings = GoogleGenerativeAIEmbeddings(model=\"models/embedding-001\")\n", 18 | "from langchain_google_genai import ChatGoogleGenerativeAI\n", 19 | "llm = ChatGoogleGenerativeAI(model=\"gemini-1.5-flash\")" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "metadata": {}, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "The coder toiled, both late and long,\n", 32 | "With data streams, a tangled throng.\n", 33 | "To weave them all, a task so grand,\n", 34 | "A system built by human hand.\n", 35 | "\n", 36 | "He'd wrestled with the APIs,\n", 37 | "And struggled with the complexities,\n", 38 | "Of prompt engineering, fine and keen,\n", 39 | "A digital tapestry, unseen.\n", 40 | "\n", 41 | "Then whispers came, upon the breeze,\n", 42 | "Of LangChain, meant to bring him ease.\n", 43 | "A framework new, a shining light,\n", 44 | "To guide his code through darkest night.\n", 45 | "\n", 46 | "(Chorus)\n", 47 | "Oh, LangChain, LangChain, noble name,\n", 48 | "You tame the chaos, quell the flame.\n", 49 | "With chains of thought, you link and bind,\n", 50 | "The scattered knowledge of mankind.\n", 51 | "\n", 52 | "He learned of LLM's, powerful tools,\n", 53 | "Their language models, breaking rules.\n", 54 | "But how to guide, how to control,\n", 55 | "Their vast potential, take its toll?\n", 56 | "\n", 57 | "LangChain showed the path so clear,\n", 58 | "With agents, chains, and memories near.\n", 59 | "To build a system, strong and fast,\n", 60 | "Whose knowledge base would ever last.\n", 61 | "\n", 62 | "He built his prompts with careful hand,\n", 63 | "And watched the system understand.\n", 64 | "The chains he forged, both long and deep,\n", 65 | "The secrets that the LLMs keep.\n", 66 | "\n", 67 | "(Chorus)\n", 68 | "Oh, LangChain, LangChain, noble name,\n", 69 | "You tame the chaos, quell the flame.\n", 70 | "With chains of thought, you link and bind,\n", 71 | "The scattered knowledge of mankind.\n", 72 | "\n", 73 | "From simple tasks to complex schemes,\n", 74 | "LangChain fulfilled his wildest dreams.\n", 75 | "A powerful tool, a gift so rare,\n", 76 | "To solve the problems, everywhere.\n", 77 | "\n", 78 | "So raise a glass, to this new age,\n", 79 | "Where code and language rearrange.\n", 80 | "With LangChain's help, the future bright,\n", 81 | "A beacon burning, ever light.\n", 82 | "\n" 83 | ] 84 | } 85 | ], 86 | "source": [ 87 | "result = llm.invoke(\"Write a ballad about LangChain\")\n", 88 | "print(result.content)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "### Let's Create a Retriever now" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 3, 101 | "metadata": {}, 102 | "outputs": [ 103 | { 104 | "name": "stderr", 105 | "output_type": "stream", 106 | "text": [ 107 | "USER_AGENT environment variable not set, consider setting it to identify your requests.\n" 108 | ] 109 | } 110 | ], 111 | "source": [ 112 | "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", 113 | "from langchain_community.document_loaders import WebBaseLoader\n", 114 | "from langchain_community.vectorstores import Chroma\n", 115 | "urls = [\n", 116 | " \"https://lilianweng.github.io/posts/2023-06-23-agent/\",\n", 117 | " \"https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/\",\n", 118 | " \"https://lilianweng.github.io/posts/2023-10-25-adv-attack-llm/\",\n", 119 | "]\n", 120 | "\n", 121 | "docs = [WebBaseLoader(url).load() for url in urls]\n", 122 | "docs_list = [item for sublist in docs for item in sublist]\n", 123 | "\n", 124 | "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", 125 | " chunk_size=250, chunk_overlap=0\n", 126 | ")\n", 127 | "doc_splits = text_splitter.split_documents(docs_list)\n", 128 | "\n", 129 | "# Add to vectorDB\n", 130 | "vectorstore = Chroma.from_documents(\n", 131 | " documents=doc_splits,\n", 132 | " collection_name=\"rag-chroma\",\n", 133 | " embedding=embeddings,\n", 134 | ")\n", 135 | "retriever = vectorstore.as_retriever()\n" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "### Lets Create a RAG Chain Now" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 4, 148 | "metadata": {}, 149 | "outputs": [ 150 | { 151 | "name": "stdout", 152 | "output_type": "stream", 153 | "text": [ 154 | "---PROMPT--- input_variables=['context', 'question'] input_types={} partial_variables={} metadata={'lc_hub_owner': 'rlm', 'lc_hub_repo': 'rag-prompt', 'lc_hub_commit_hash': '50442af133e61576e74536c6556cefe1fac147cad032f4377b60c436e6cdcb6e'} messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['context', 'question'], input_types={}, partial_variables={}, template=\"You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\\nQuestion: {question} \\nContext: {context} \\nAnswer:\"), additional_kwargs={})]\n" 155 | ] 156 | } 157 | ], 158 | "source": [ 159 | "\n", 160 | "from langchain import hub\n", 161 | "from langchain_core.output_parsers import StrOutputParser\n", 162 | "\n", 163 | "# Prompt\n", 164 | "prompt = hub.pull(\"rlm/rag-prompt\")\n", 165 | "\n", 166 | "print(f\"---PROMPT--- {prompt}\")\n", 167 | "\n", 168 | "# Post-processing\n", 169 | "def format_docs(docs):\n", 170 | " return \"\\n\\n\".join(doc.page_content for doc in docs)\n", 171 | "\n", 172 | "\n", 173 | "# Chain\n", 174 | "rag_chain = prompt | llm | StrOutputParser()" 175 | ] 176 | }, 177 | { 178 | "cell_type": "markdown", 179 | "metadata": {}, 180 | "source": [ 181 | "### Let's test the RAG Chain Now" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 5, 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "name": "stdout", 191 | "output_type": "stream", 192 | "text": [ 193 | "LLM-powered autonomous agents utilize two main types of memory: short-term memory, which uses in-context learning within the model's limited context window, and long-term memory, which leverages external vector stores for information retrieval. The external memory addresses the limitations of the finite context window.\n", 194 | "\n" 195 | ] 196 | } 197 | ], 198 | "source": [ 199 | "# Run\n", 200 | "question = \"tell me about agent memory.\"\n", 201 | "generation = rag_chain.invoke({\"context\": docs, \"question\": question})\n", 202 | "print(generation)" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": {}, 208 | "source": [ 209 | "### Now lets create grade document class" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": 9, 215 | "metadata": {}, 216 | "outputs": [ 217 | { 218 | "name": "stderr", 219 | "output_type": "stream", 220 | "text": [ 221 | "c:\\Users\\sunny\\langgraph-end-to-end\\env\\lib\\site-packages\\IPython\\core\\interactiveshell.py:3577: LangChainDeprecationWarning: As of langchain-core 0.3.0, LangChain uses pydantic v2 internally. The langchain_core.pydantic_v1 module was a compatibility shim for pydantic v1, and should no longer be used. Please update the code to import from Pydantic directly.\n", 222 | "\n", 223 | "For example, replace imports like: `from langchain_core.pydantic_v1 import BaseModel`\n", 224 | "with: `from pydantic import BaseModel`\n", 225 | "or the v1 compatibility namespace if you are working in a code base that has not been fully upgraded to pydantic 2 yet. \tfrom pydantic.v1 import BaseModel\n", 226 | "\n", 227 | " exec(code_obj, self.user_global_ns, self.user_ns)\n" 228 | ] 229 | } 230 | ], 231 | "source": [ 232 | "from langchain_core.prompts import ChatPromptTemplate\n", 233 | "from langchain_core.pydantic_v1 import BaseModel, Field\n", 234 | "\n", 235 | "\n", 236 | "class GradeDocuments(BaseModel):\n", 237 | " \"\"\"Binary score for relevance check on retrieved documents.\"\"\"\n", 238 | "\n", 239 | " binary_score: str = Field(\n", 240 | " description=\"Documents are relevant to the question, 'yes' or 'no'\"\n", 241 | " )" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 10, 247 | "metadata": {}, 248 | "outputs": [ 249 | { 250 | "name": "stderr", 251 | "output_type": "stream", 252 | "text": [ 253 | "Key 'title' is not supported in schema, ignoring\n", 254 | "Key 'title' is not supported in schema, ignoring\n" 255 | ] 256 | } 257 | ], 258 | "source": [ 259 | "# LLM with function call\n", 260 | "structured_llm_grader = llm.with_structured_output(GradeDocuments)\n", 261 | "# Prompt\n", 262 | "system = \"\"\"You are a grader assessing relevance of a retrieved document to a user question. \\n \n", 263 | " If the document contains keyword(s) or semantic meaning related to the question, grade it as relevant. \\n\n", 264 | " Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.\"\"\"\n", 265 | "grade_prompt = ChatPromptTemplate.from_messages(\n", 266 | " [\n", 267 | " (\"system\", system),\n", 268 | " (\"human\", \"Retrieved document: \\n\\n {document} \\n\\n User question: {question}\"),\n", 269 | " ]\n", 270 | ")\n", 271 | "\n", 272 | "retrieval_grader = grade_prompt | structured_llm_grader" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": 14, 278 | "metadata": {}, 279 | "outputs": [ 280 | { 281 | "name": "stdout", 282 | "output_type": "stream", 283 | "text": [ 284 | "binary_score='yes'\n" 285 | ] 286 | } 287 | ], 288 | "source": [ 289 | "question = \"tell me about the agent memory.\"\n", 290 | "docs = retriever.get_relevant_documents(question)\n", 291 | "doc_txt = docs[1].page_content\n", 292 | "print(retrieval_grader.invoke({\"question\": question, \"document\": doc_txt}))" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 12, 298 | "metadata": {}, 299 | "outputs": [ 300 | { 301 | "name": "stdout", 302 | "output_type": "stream", 303 | "text": [ 304 | "binary_score='no'\n" 305 | ] 306 | } 307 | ], 308 | "source": [ 309 | "question = \"tell me about the Tajmahal.\"\n", 310 | "docs = retriever.get_relevant_documents(question)\n", 311 | "doc_txt = docs[1].page_content\n", 312 | "print(retrieval_grader.invoke({\"question\": question, \"document\": doc_txt}))" 313 | ] 314 | }, 315 | { 316 | "cell_type": "markdown", 317 | "metadata": {}, 318 | "source": [ 319 | "### Let's Create Question Re-Writer" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 13, 325 | "metadata": {}, 326 | "outputs": [], 327 | "source": [ 328 | "### Question Re-writer\n", 329 | "# Prompt\n", 330 | "from langchain_core.prompts import ChatPromptTemplate\n", 331 | "\n", 332 | "system = \"\"\"You a question re-writer that converts an input question to a better version that is optimized \\n \n", 333 | " for web search. Look at the input and try to reason about the underlying semantic intent / meaning.\"\"\"\n", 334 | " \n", 335 | " \n", 336 | "re_write_prompt = ChatPromptTemplate.from_messages(\n", 337 | " [\n", 338 | " (\"system\", system),\n", 339 | " (\n", 340 | " \"human\",\n", 341 | " \"Here is the initial question: \\n\\n {question} \\n Formulate an improved question.\",\n", 342 | " ),\n", 343 | " ]\n", 344 | ")\n", 345 | "\n", 346 | "question_rewriter = re_write_prompt | llm | StrOutputParser()" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": 15, 352 | "metadata": {}, 353 | "outputs": [ 354 | { 355 | "data": { 356 | "text/plain": [ 357 | "'What is agent memory in artificial intelligence?\\n'" 358 | ] 359 | }, 360 | "execution_count": 15, 361 | "metadata": {}, 362 | "output_type": "execute_result" 363 | } 364 | ], 365 | "source": [ 366 | "question_rewriter.invoke({\"question\": question})" 367 | ] 368 | }, 369 | { 370 | "cell_type": "markdown", 371 | "metadata": {}, 372 | "source": [ 373 | "### Lets create a required function" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": 17, 379 | "metadata": {}, 380 | "outputs": [], 381 | "source": [ 382 | "def retrieve(state):\n", 383 | " \"\"\"\n", 384 | " Retrieve documents\n", 385 | "\n", 386 | " Args:\n", 387 | " state (dict): The current graph state\n", 388 | "\n", 389 | " Returns:\n", 390 | " \n", 391 | " \"\"\"\n", 392 | " print(\"---RETRIEVE---\")\n", 393 | " \n", 394 | " question = state[\"question\"]\n", 395 | " \n", 396 | " documents = retriever.get_relevant_documents(question)\n", 397 | " \n", 398 | " return {\"documents\": documents, \"question\": question}" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": 18, 404 | "metadata": {}, 405 | "outputs": [], 406 | "source": [ 407 | "def grade_documents(state):\n", 408 | " \"\"\"\n", 409 | " Determines whether the retrieved documents are relevant to the question.\n", 410 | "\n", 411 | " Args:\n", 412 | " state (dict): The current graph state\n", 413 | "\n", 414 | " Returns:\n", 415 | " state (dict): Updates documents key with only filtered relevant documents\n", 416 | " \"\"\"\n", 417 | " \n", 418 | " print(\"---CHECKING DOCUMENT RELEVANT IS TO QUESTION OR NOT---\")\n", 419 | " \n", 420 | " question = state[\"question\"]\n", 421 | " \n", 422 | " documents = state[\"documents\"]\n", 423 | "\n", 424 | " # Score each doc\n", 425 | " filtered_docs = []\n", 426 | " \n", 427 | " web_search = \"No\"\n", 428 | " \n", 429 | " for d in documents:\n", 430 | " score = retrieval_grader.invoke(\n", 431 | " {\"question\": question, \"document\": d.page_content}\n", 432 | " )\n", 433 | " grade = score.binary_score\n", 434 | " if grade == \"yes\":\n", 435 | " print(\"---GRADE: DOCUMENT RELEVANT---\")\n", 436 | " filtered_docs.append(d)\n", 437 | " else:\n", 438 | " print(\"---GRADE: DOCUMENT NOT RELEVANT---\")\n", 439 | " web_search = \"Yes\"\n", 440 | " continue\n", 441 | " return {\"documents\": filtered_docs, \"question\": question, \"web_search\": web_search}" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": 19, 447 | "metadata": {}, 448 | "outputs": [], 449 | "source": [ 450 | "def generate(state):\n", 451 | " \"\"\"\n", 452 | " Generate answer\n", 453 | "\n", 454 | " Args:\n", 455 | " state (dict): The current graph state\n", 456 | "\n", 457 | " Returns:\n", 458 | " state (dict): New key added to state, generation, that contains LLM generation\n", 459 | " \"\"\"\n", 460 | " \n", 461 | " print(\"---GENERATE---\")\n", 462 | " \n", 463 | " question = state[\"question\"]\n", 464 | " documents = state[\"documents\"]\n", 465 | " \n", 466 | " generation = rag_chain.invoke({\"context\": documents, \"question\": question})\n", 467 | " \n", 468 | " return {\"documents\": documents, \"question\": question, \"generation\": generation}" 469 | ] 470 | }, 471 | { 472 | "cell_type": "code", 473 | "execution_count": 20, 474 | "metadata": {}, 475 | "outputs": [], 476 | "source": [ 477 | "def transform_query(state):\n", 478 | " \"\"\"\n", 479 | " Transform the query to produce a better question.\n", 480 | "\n", 481 | " Args:\n", 482 | " state (dict): The current graph state\n", 483 | "\n", 484 | " Returns:\n", 485 | " state (dict): Updates question key with a re-phrased question\n", 486 | " \"\"\"\n", 487 | " print(\"---TRANSFORM QUERY---\")\n", 488 | " \n", 489 | " question = state[\"question\"]\n", 490 | " \n", 491 | " documents = state[\"documents\"]\n", 492 | "\n", 493 | " # Re-write question\n", 494 | " better_question = question_rewriter.invoke({\"question\": question})\n", 495 | " \n", 496 | " return {\"documents\": documents, \"question\": better_question}" 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "metadata": {}, 502 | "source": [ 503 | "### Web Crawling we gonna perform using Tavily" 504 | ] 505 | }, 506 | { 507 | "cell_type": "code", 508 | "execution_count": 21, 509 | "metadata": {}, 510 | "outputs": [], 511 | "source": [ 512 | "### Search\n", 513 | "\n", 514 | "from langchain_community.tools.tavily_search import TavilySearchResults\n", 515 | "\n", 516 | "web_search_tool = TavilySearchResults(k=3)" 517 | ] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": 22, 522 | "metadata": {}, 523 | "outputs": [], 524 | "source": [ 525 | "\n", 526 | "from langchain.schema import Document\n", 527 | "def web_search(state):\n", 528 | " \"\"\"\n", 529 | " Web search based on the re-phrased question.\n", 530 | "\n", 531 | " Args:\n", 532 | " state (dict): The current graph state\n", 533 | "\n", 534 | " Returns:\n", 535 | " state (dict): Updates documents key with appended web results\n", 536 | " \"\"\"\n", 537 | " print(\"---WEB SEARCH---\")\n", 538 | " \n", 539 | " question = state[\"question\"]\n", 540 | " \n", 541 | " documents = state[\"documents\"]\n", 542 | "\n", 543 | " # Web search\n", 544 | " docs = web_search_tool.invoke({\"query\": question})\n", 545 | " \n", 546 | " web_results = \"\\n\".join([d[\"content\"] for d in docs])\n", 547 | " \n", 548 | " web_results = Document(page_content=web_results)\n", 549 | " \n", 550 | " documents.append(web_results)\n", 551 | "\n", 552 | " return {\"documents\": documents, \"question\": question}" 553 | ] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": 23, 558 | "metadata": {}, 559 | "outputs": [], 560 | "source": [ 561 | "def decide_to_generate(state):\n", 562 | " \"\"\"\n", 563 | " Determines whether to generate an answer, or re-generate a question.\n", 564 | "\n", 565 | " Args:\n", 566 | " state (dict): The current graph state\n", 567 | "\n", 568 | " Returns:\n", 569 | " str: Binary decision for next node to call\n", 570 | " \"\"\"\n", 571 | " print(\"---ASSESS GRADED DOCUMENTS---\")\n", 572 | " state[\"question\"]\n", 573 | " web_search = state[\"web_search\"]\n", 574 | " state[\"documents\"]\n", 575 | "\n", 576 | " if web_search == \"Yes\":\n", 577 | " # All documents have been filtered check_relevance\n", 578 | " # We will re-generate a new query\n", 579 | " print(\n", 580 | " \"---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, TRANSFORM QUERY---\"\n", 581 | " )\n", 582 | " return \"transform_query\"\n", 583 | " else:\n", 584 | " # We have relevant documents, so generate answer\n", 585 | " print(\"---DECISION: GENERATE---\")\n", 586 | " return \"generate\"" 587 | ] 588 | }, 589 | { 590 | "cell_type": "markdown", 591 | "metadata": {}, 592 | "source": [ 593 | "### Let's create a skeleton of code then will create the function accordingly" 594 | ] 595 | }, 596 | { 597 | "cell_type": "code", 598 | "execution_count": 24, 599 | "metadata": {}, 600 | "outputs": [], 601 | "source": [ 602 | "from langgraph.graph import END, StateGraph, START" 603 | ] 604 | }, 605 | { 606 | "cell_type": "code", 607 | "execution_count": 25, 608 | "metadata": {}, 609 | "outputs": [], 610 | "source": [ 611 | "from typing import List\n", 612 | "\n", 613 | "from typing_extensions import TypedDict\n", 614 | "\n", 615 | "class State(TypedDict):\n", 616 | " \"\"\"\n", 617 | " Represents the state of our graph.\n", 618 | "\n", 619 | " Attributes:\n", 620 | " question: question\n", 621 | " generation: LLM generation\n", 622 | " web_search: whether to add search\n", 623 | " documents: list of documents\n", 624 | " \"\"\"\n", 625 | "\n", 626 | " question: str\n", 627 | " generation: str\n", 628 | " web_search: str\n", 629 | " documents: List[str]\n", 630 | "\n", 631 | "workflow= StateGraph(State)" 632 | ] 633 | }, 634 | { 635 | "cell_type": "code", 636 | "execution_count": 26, 637 | "metadata": {}, 638 | "outputs": [ 639 | { 640 | "data": { 641 | "text/plain": [ 642 | "" 643 | ] 644 | }, 645 | "execution_count": 26, 646 | "metadata": {}, 647 | "output_type": "execute_result" 648 | } 649 | ], 650 | "source": [ 651 | "# define the nodes\n", 652 | "# Define the nodes\n", 653 | "workflow.add_node(\"retrieve\", retrieve) # retrieve\n", 654 | "workflow.add_node(\"grade_documents\", grade_documents) # grade documents\n", 655 | "workflow.add_node(\"generate\", generate) # generatae\n", 656 | "workflow.add_node(\"transform_query\", transform_query) # transform_query\n", 657 | "workflow.add_node(\"web_search_node\", web_search) # web search" 658 | ] 659 | }, 660 | { 661 | "cell_type": "code", 662 | "execution_count": 27, 663 | "metadata": {}, 664 | "outputs": [ 665 | { 666 | "data": { 667 | "text/plain": [ 668 | "" 669 | ] 670 | }, 671 | "execution_count": 27, 672 | "metadata": {}, 673 | "output_type": "execute_result" 674 | } 675 | ], 676 | "source": [ 677 | "# Build graph\n", 678 | "workflow.add_edge(START, \"retrieve\")\n", 679 | "\n", 680 | "workflow.add_edge(\"retrieve\", \"grade_documents\")\n", 681 | "\n", 682 | "workflow.add_conditional_edges(\"grade_documents\", decide_to_generate, {\"transform_query\": \"transform_query\",\"generate\": \"generate\",}),\n", 683 | "\n", 684 | "workflow.add_edge(\"transform_query\", \"web_search_node\")\n", 685 | "\n", 686 | "workflow.add_edge(\"web_search_node\", \"generate\")\n", 687 | "\n", 688 | "workflow.add_edge(\"generate\", END)" 689 | ] 690 | }, 691 | { 692 | "cell_type": "code", 693 | "execution_count": 28, 694 | "metadata": {}, 695 | "outputs": [], 696 | "source": [ 697 | "# Compile\n", 698 | "app = workflow.compile()" 699 | ] 700 | }, 701 | { 702 | "cell_type": "code", 703 | "execution_count": 29, 704 | "metadata": {}, 705 | "outputs": [ 706 | { 707 | "data": { 708 | "image/jpeg": "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", 709 | "text/plain": [ 710 | "" 711 | ] 712 | }, 713 | "metadata": {}, 714 | "output_type": "display_data" 715 | } 716 | ], 717 | "source": [ 718 | "# Display the graph\n", 719 | "from IPython.display import Image, display # type: ignore\n", 720 | "display(Image(app.get_graph(xray=True).draw_mermaid_png()))" 721 | ] 722 | }, 723 | { 724 | "cell_type": "code", 725 | "execution_count": 30, 726 | "metadata": {}, 727 | "outputs": [], 728 | "source": [ 729 | "from pprint import pprint\n", 730 | "\n", 731 | "# Run\n", 732 | "inputs = {\"question\": \"tell me about the agent memory.\"}" 733 | ] 734 | }, 735 | { 736 | "cell_type": "code", 737 | "execution_count": 31, 738 | "metadata": {}, 739 | "outputs": [ 740 | { 741 | "name": "stdout", 742 | "output_type": "stream", 743 | "text": [ 744 | "---RETRIEVE---\n", 745 | "\"Node 'retrieve':\"\n", 746 | "'\\n---\\n'\n", 747 | "---CHECKING DOCUMENT RELEVANT IS TO QUESTION OR NOT---\n", 748 | "---GRADE: DOCUMENT RELEVANT---\n", 749 | "---GRADE: DOCUMENT RELEVANT---\n", 750 | "---GRADE: DOCUMENT RELEVANT---\n", 751 | "---GRADE: DOCUMENT RELEVANT---\n", 752 | "---ASSESS GRADED DOCUMENTS---\n", 753 | "---DECISION: GENERATE---\n", 754 | "\"Node 'grade_documents':\"\n", 755 | "'\\n---\\n'\n", 756 | "---GENERATE---\n", 757 | "\"Node 'generate':\"\n", 758 | "'\\n---\\n'\n", 759 | "('Agent memory includes short-term memory (in-context learning), and long-term '\n", 760 | " 'memory (external vector store for information retrieval). Sensory memory, '\n", 761 | " 'for raw inputs like text and images, is also a component.\\n')\n" 762 | ] 763 | } 764 | ], 765 | "source": [ 766 | "for output in app.stream(inputs):\n", 767 | " for key, value in output.items():\n", 768 | " # Node\n", 769 | " pprint(f\"Node '{key}':\")\n", 770 | " # Optional: print full state at each node\n", 771 | " # pprint.pprint(value[\"keys\"], indent=2, width=80, depth=None)\n", 772 | " pprint(\"\\n---\\n\")\n", 773 | "# Final generation\n", 774 | "pprint(value[\"generation\"])" 775 | ] 776 | }, 777 | { 778 | "cell_type": "code", 779 | "execution_count": 32, 780 | "metadata": {}, 781 | "outputs": [], 782 | "source": [ 783 | "from pprint import pprint\n", 784 | "\n", 785 | "# Run\n", 786 | "inputs = {\"question\": \"tell me about the taj mahal.\"}" 787 | ] 788 | }, 789 | { 790 | "cell_type": "code", 791 | "execution_count": 33, 792 | "metadata": {}, 793 | "outputs": [ 794 | { 795 | "name": "stdout", 796 | "output_type": "stream", 797 | "text": [ 798 | "---RETRIEVE---\n", 799 | "\"Node 'retrieve':\"\n", 800 | "'\\n---\\n'\n", 801 | "---CHECKING DOCUMENT RELEVANT IS TO QUESTION OR NOT---\n", 802 | "---GRADE: DOCUMENT RELEVANT---\n", 803 | "---GRADE: DOCUMENT NOT RELEVANT---\n", 804 | "---GRADE: DOCUMENT NOT RELEVANT---\n", 805 | "---GRADE: DOCUMENT NOT RELEVANT---\n", 806 | "---ASSESS GRADED DOCUMENTS---\n", 807 | "---DECISION: ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, TRANSFORM QUERY---\n", 808 | "\"Node 'grade_documents':\"\n", 809 | "'\\n---\\n'\n", 810 | "---TRANSFORM QUERY---\n", 811 | "\"Node 'transform_query':\"\n", 812 | "'\\n---\\n'\n", 813 | "---WEB SEARCH---\n", 814 | "\"Node 'web_search_node':\"\n", 815 | "'\\n---\\n'\n", 816 | "---GENERATE---\n", 817 | "\"Node 'generate':\"\n", 818 | "'\\n---\\n'\n", 819 | "('The Taj Mahal, commissioned in 1632 by Mughal emperor Shah Jahan, is a '\n", 820 | " 'mausoleum for his wife Mumtaz Mahal. Construction took 22 years and '\n", 821 | " 'incorporated white marble inlaid with semi-precious stones. Its '\n", 822 | " 'significance lies in its architectural grandeur, symbolic representation of '\n", 823 | " 'love and power, and status as a globally recognized symbol of India.\\n')\n" 824 | ] 825 | } 826 | ], 827 | "source": [ 828 | "for output in app.stream(inputs):\n", 829 | " for key, value in output.items():\n", 830 | " # Node\n", 831 | " pprint(f\"Node '{key}':\")\n", 832 | " # Optional: print full state at each node\n", 833 | " # pprint.pprint(value[\"keys\"], indent=2, width=80, depth=None)\n", 834 | " pprint(\"\\n---\\n\")\n", 835 | "# Final generation\n", 836 | "pprint(value[\"generation\"])" 837 | ] 838 | }, 839 | { 840 | "cell_type": "code", 841 | "execution_count": null, 842 | "metadata": {}, 843 | "outputs": [], 844 | "source": [] 845 | } 846 | ], 847 | "metadata": { 848 | "kernelspec": { 849 | "display_name": "Python 3", 850 | "language": "python", 851 | "name": "python3" 852 | }, 853 | "language_info": { 854 | "codemirror_mode": { 855 | "name": "ipython", 856 | "version": 3 857 | }, 858 | "file_extension": ".py", 859 | "mimetype": "text/x-python", 860 | "name": "python", 861 | "nbconvert_exporter": "python", 862 | "pygments_lexer": "ipython3", 863 | "version": "3.10.14" 864 | } 865 | }, 866 | "nbformat": 4, 867 | "nbformat_minor": 2 868 | } 869 | --------------------------------------------------------------------------------