{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "161d84fa-d7a3-404b-954f-ce0b69e44269",
   "metadata": {},
   "source": [
    "## LangChain v0.1.0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "083dd195-2b13-4a31-82cd-011624b79f6b",
   "metadata": {},
   "source": [
    "#### LangChain's Blog Post and Video about the new release\n",
    "* Released Jan 8, 2024.\n",
    "* [LangChain v0.1.0](https://blog.langchain.dev/langchain-v0-1-0/)\n",
    "* [YouTube Walkthroug](https://www.youtube.com/watch?v=Fk_zZr2DbQY&list=PLfaIDFEXuae0gBSJ9T0w7cu7iJZbH3T31)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "456940d3-ef3c-418b-a76b-311b728b3789",
   "metadata": {},
   "source": [
    "#### Summary\n",
    "* First stable version.\n",
    "* Fully backwards compatible.\n",
    "* Both in Python and Javascript.\n",
    "* Improved functionality.\n",
    "* Improved documentation."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27e79128-0f85-432e-9df3-a4b6ae17fc35",
   "metadata": {},
   "source": [
    "#### Main change: the old LangChain package is splitted\n",
    "* lanchain-core: core functionality.\n",
    "* langchain-community: third-party integrations\n",
    "* standalone partner packages\n",
    "    * example: langchain-openai"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cfbbb0e6-a2bf-4b80-89c1-49c8d16ab791",
   "metadata": {},
   "source": [
    "#### In theory, all previous LangChain projects should work\n",
    "* In practice, this does not seem credible."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9114f6aa-6372-400d-827c-ef4983af8946",
   "metadata": {},
   "source": [
    "#### Example using langchain-core"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1bb9937e-a606-4a53-b60a-aa2233dbacd9",
   "metadata": {},
   "source": [
    "#### Example using langchain-community"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "276f0d5d-7924-4a0c-bff3-6c280910cce4",
   "metadata": {},
   "source": [
    "#### Example using langchain-openai"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5afe8b2f-77d7-4ce8-ae3b-2811f7b21597",
   "metadata": {},
   "source": [
    "## New Quickstart\n",
    "* Setup LangChain, LangSmith and LangServe.\n",
    "* Use basic componets:\n",
    "    * Prompt templates.\n",
    "    * Models.\n",
    "    * Output parsers.\n",
    "* Use LCEL.\n",
    "* Build a simple app.\n",
    "* Trace your app with LangSmith.\n",
    "* Serve your app with LangServe. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66c0007f-0e53-4de2-aab8-c88e36d73ab4",
   "metadata": {},
   "source": [
    "#### Create a new virtual environment"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33fef60e-113f-4643-8b4d-9b0e7c9f04be",
   "metadata": {},
   "source": [
    "#### Create a .env file with the OpenAI credentials"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db2a36ec-078b-4327-824f-19c4f45a073d",
   "metadata": {},
   "source": [
    "#### LangChain Installation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "cbf7b2be-7981-4d6f-b054-f3bdb69ae5a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "#!pip install langchain"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7421ad0f-5088-40b1-9be8-d70f36354172",
   "metadata": {},
   "source": [
    "#### If you set the LangSmith credentials in the .env file, LangChain will start logging traces."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d02c379a-8a7e-4b3c-9dfc-01a7985f0558",
   "metadata": {},
   "source": [
    "If you do want to use LangSmith, after you sign up at LangSmith, make sure to set your environment variables in your .env file to start logging traces:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7cadab91-2761-47aa-89e7-98283d079e2c",
   "metadata": {},
   "source": [
    "LANGCHAIN_TRACING_V2=true\n",
    "LANGCHAIN_ENDPOINT=https://api.smith.langchain.com\n",
    "LANGCHAIN_API_KEY=..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd99b11a-8d20-4c75-8743-a386d7b15de1",
   "metadata": {},
   "source": [
    "#### What we will cover\n",
    "* Simple LLM chain.\n",
    "* Retrieval chain.\n",
    "* Conversation Retrieval chain.\n",
    "* Agent."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73f21331-17b6-4496-8070-9a9c927fcc17",
   "metadata": {},
   "source": [
    "#### Use the new langchain_openai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d6de78a4-11db-46bd-b64e-28a712d7d442",
   "metadata": {},
   "outputs": [],
   "source": [
    "#!pip install langchain-openai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "90938d17-d3ff-4709-bced-35711537ef63",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv, find_dotenv\n",
    "_ = load_dotenv(find_dotenv())\n",
    "openai_api_key = os.environ[\"OPENAI_API_KEY\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2845f0b2-7159-43cb-8e29-9ae43672013c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "0c3a62f9-aadd-47db-9e94-59e1337acfca",
   "metadata": {},
   "outputs": [],
   "source": [
    "llm = ChatOpenAI()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "24be1ce6-c7b3-408d-baaf-d2167b06421e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content=\"Napoleon's wife's name was Joséphine de Beauharnais.\")"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "llm.invoke(\"What was the name of Napoleon's wife?\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5340f395-57c9-4d88-9622-b0d79ab5306f",
   "metadata": {},
   "source": [
    "#### Use the new lanchain_core"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "e25a4939-124a-4382-baa0-1e45922de0ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "9a7e8db6-bf68-4ac3-98d0-c4033d6297c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_prompt_template = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", \"You are friendly assisstant.\"),\n",
    "    (\"user\", \"{input}\")\n",
    "])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee71012f-e6ba-48ec-b69a-18cf3e7c63ec",
   "metadata": {},
   "source": [
    "#### Create a chain with LCEL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "7b27fea6-66f7-4d72-ab4d-ddb3caa90dec",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_chain = my_prompt_template | llm "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ee8a3f3e-55af-43e7-b37c-a722fcf99b3b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='Napoleon was famously defeated at the Battle of Waterloo, which took place near the town of Waterloo in present-day Belgium on June 18, 1815.')"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_chain.invoke({\"input\": \"Where was Napoleon defeated?\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2de5fc72-fd08-4934-9ae5-1d09501d32dc",
   "metadata": {},
   "source": [
    "#### Create an Output Parser to convert the chat message to a string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "06b2a9b2-30a4-4ed8-93fc-ba6e5538ef74",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.output_parsers import StrOutputParser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "a7405de3-c0fd-4dbc-b794-e243ac8e07f1",
   "metadata": {},
   "outputs": [],
   "source": [
    "to_string_output_parser = StrOutputParser()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "76b0ba7b-a432-42b8-82b6-d888482d8e17",
   "metadata": {},
   "source": [
    "#### Add the Output Parser to the Chain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "6171bdc9-bb39-4f40-a672-7a05c9518b3b",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_chain = my_prompt_template | llm | to_string_output_parser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "dbc2b97a-6f18-4597-a7cc-c306de208ac7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"One of Napoleon's most significant victories was the Battle of Austerlitz, also known as the Battle of the Three Emperors, which took place on December 2, 1805. The battle was fought near the town of Austerlitz in the present-day Czech Republic. Napoleon's French forces defeated a combined army of Russian and Austrian troops, securing a decisive victory for the French Empire.\""
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_chain.invoke({\"input\": \"Where was the main victory of Napoleon?\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d0d5b38-06f5-476b-8727-e473f246b413",
   "metadata": {},
   "source": [
    "#### Simple RAG: Private Document, Splitter, Vector Database and Retrieval Chain."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92b10308-f838-4b54-b223-c9af918cb9dd",
   "metadata": {},
   "source": [
    "We can load our private document from different sources (from a file, from the web, etc). In this example we will load our private data from the web using WebBaseLoader. In order to use WebBaseLoader we will need to install BeautifulSoup:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "dc6d5c9a-815f-421c-91d5-c31c7d84b5e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "#!pip install beautifulsoup4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2746a720-0f25-4d0e-8594-76df7d67a7c5",
   "metadata": {},
   "source": [
    "To import WebBaseLoader, we will **use the new langchain_community**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "c1330f70-0f3f-4c78-8db5-9050de789b53",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.document_loaders import WebBaseLoader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "5589381a-833c-434d-9028-00ad53703894",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_loader = WebBaseLoader(\"https://aiaccelera.com/ai-consulting-for-businesses/\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "7fabe1a2-ef73-44e5-91c9-444a678e13dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_private_docs = my_loader.load()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c54ab81-de7d-4371-bf23-1733deecb303",
   "metadata": {},
   "source": [
    "We will use OpenAIEmbeddings to convert our private docs to numbers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "8b3be3c2-fcd5-4195-b64c-b38e8283914e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import OpenAIEmbeddings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "f7460a69-6c8a-4a98-b1d8-a36cb36a52d3",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_embeddings = OpenAIEmbeddings()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e035cb31-0c20-4219-abe6-b20ce726e464",
   "metadata": {},
   "source": [
    "We will use FAISS as vector database:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "754eb94c-5207-41bc-b75b-ab5867f0e255",
   "metadata": {},
   "outputs": [],
   "source": [
    "#!pip install faiss-cpu"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "45d65051-3013-42f1-a78d-5acddc5170a7",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.vectorstores import FAISS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5b7bb27-34d8-46be-8f77-639ecb65af04",
   "metadata": {},
   "source": [
    "We will use RecursiveCharacterTextSplitter to divide the private docs into smaller text chunks:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "1c372e64-b70e-4cdf-bf5c-7fdc28864f00",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.text_splitter import RecursiveCharacterTextSplitter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "4c3eacc2-463d-4255-b794-327400daf00b",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_text_splitter = RecursiveCharacterTextSplitter()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "91420129-a90b-4506-bfb3-02518b843d36",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_text_chunks = my_text_splitter.split_documents(my_private_docs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "9ed2ffb3-1fb2-40eb-bea4-97e2a2779f6e",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_vector_database = FAISS.from_documents(my_text_chunks, my_embeddings)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a1f42020-99d1-4e42-92b4-751a64254d16",
   "metadata": {},
   "source": [
    "Now we will create a chain that takes the question and the retrieved documents and generates an answer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "4cf6f8be-c56b-443a-90ed-04d2f211228a",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains.combine_documents import create_stuff_documents_chain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "ba84eef5-6433-4f19-af9f-dbd5ab293593",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_prompt_template = ChatPromptTemplate.from_template(\n",
    "    \"\"\"Answer the following question based only on the \n",
    "    provided context:\n",
    "\n",
    "    <context>\n",
    "    {context}\n",
    "    </context>\n",
    "\n",
    "    Question: {input}\"\"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "f165888b-3c73-4359-95f1-9426f4fdea48",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_document_answering_chain = create_stuff_documents_chain(llm, my_prompt_template)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea80d6f6-a711-4324-9468-7ff265b1f652",
   "metadata": {},
   "source": [
    "Next we will create the retrieval chain:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "fc7c72c8-262c-47d2-884b-9c20700bfdb1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains import create_retrieval_chain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "cd3171f4-4333-4be7-912a-1403111c2eeb",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_retriever = my_vector_database.as_retriever()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "c4c7ece5-1fc1-4b4a-a968-b473b01cbafb",
   "metadata": {},
   "outputs": [],
   "source": [
    "my_retrieval_chain = create_retrieval_chain(my_retriever, my_document_answering_chain)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42fff3e5-240c-4f5a-b904-351d66c95e51",
   "metadata": {},
   "source": [
    "We can now start using the retrieval chain:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "2568a1b9-579e-4671-b776-7454f05ef96d",
   "metadata": {},
   "outputs": [],
   "source": [
    "response = my_retrieval_chain.invoke({\n",
    "    \"input\": \"Summarize the provided context in less than 100 words\"\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "06d12f40-be6a-40ca-8622-d95b0208b83b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The provided context describes a company that offers AI consulting and development services. They help businesses identify use cases for AI and develop LLM (Generative AI) applications. The company follows a comprehensive approach, starting from idea validation to deployment and ongoing support. They emphasize the benefits of using generative AI, such as increased creativity, efficiency, enhanced decision making, and personalized experiences. The company also offers maintenance and support for AI products. Overall, their goal is to help businesses harness the power of AI and unlock its potential for growth and innovation.\n"
     ]
    }
   ],
   "source": [
    "print(response[\"answer\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4fe5b7b6-e8f8-4f78-bf75-9b86e2a3a139",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
