├── Blog_to_chatbot.ipynb ├── Caching.ipynb ├── Code_Interpreter.ipynb ├── Falcon7b_Langchain.ipynb ├── LICENSE ├── Langchain_agents.ipynb ├── Llama2_langchain.ipynb ├── LocalGPT.ipynb ├── README.md └── Summarization.ipynb /Blog_to_chatbot.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "authorship_tag": "ABX9TyOVvn6lfex8xyevRbi5evCu", 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "view-in-github", 23 | "colab_type": "text" 24 | }, 25 | "source": [ 26 | "\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "source": [ 32 | "!pip install requests langchain trafilatura openai BeautifulSoup" 33 | ], 34 | "metadata": { 35 | "id": "ygUPNWVWMMO1" 36 | }, 37 | "execution_count": null, 38 | "outputs": [] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "source": [ 43 | "import requests\n", 44 | "from bs4 import BeautifulSoup\n", 45 | "wunder = requests.get(\"https://uuki.live/sitemap.xml\")\n", 46 | "parcala = BeautifulSoup(wunder.content, \"xml\")\n", 47 | "\n", 48 | "urls = []\n", 49 | "\n", 50 | "loc_tags = parcala.find_all('loc')\n", 51 | "\n", 52 | "for loc in loc_tags:\n", 53 | " if 'learn/' in loc.get_text():\n", 54 | " urls.append(loc.get_text().strip())\n", 55 | "\n", 56 | "print(urls)\n" 57 | ], 58 | "metadata": { 59 | "colab": { 60 | "base_uri": "https://localhost:8080/" 61 | }, 62 | "id": "Y6sO5E9sMKk1", 63 | "outputId": "07e689bc-cb48-4c8f-d337-360fa3d78d15" 64 | }, 65 | "execution_count": 12, 66 | "outputs": [ 67 | { 68 | "output_type": "stream", 69 | "name": "stdout", 70 | "text": [ 71 | "['https://uuki.live/learn/10-best-ai-image-generators-in-2023', 'https://uuki.live/learn/10-best-discord-alternatives-for-better-experience', 'https://uuki.live/learn/5-best-online-community-platforms-for-2023', 'https://uuki.live/learn/5-tips-for-building-a-stronger-brand-community', 'https://uuki.live/learn/6-steps-to-hack-your-way-to-a-great-producthunt-launch', 'https://uuki.live/learn/7-best-solana-nft-marketplaces', 'https://uuki.live/learn/7-examples-of-captivating-community-welcome-emails', 'https://uuki.live/learn/7-tips-for-online-community-moderators', 'https://uuki.live/learn/8-tips-for-the-perfect-community-newsletter', 'https://uuki.live/learn/autogpt-vs-babyagi', 'https://uuki.live/learn/best-discord-servers-for-web3-developers', 'https://uuki.live/learn/community-app-the-text-messaging-app-for-creators-and-influencers', 'https://uuki.live/learn/create-your-own-social-network-like-facebook', 'https://uuki.live/learn/creative-membership-level-names-how-to-name-your-memberships-with-examples', 'https://uuki.live/learn/differences-between-social-media-manager-and-community-manager', 'https://uuki.live/learn/everything-you-need-to-know-about-ko-fi', 'https://uuki.live/learn/facebook-group-and-page-badges-explained', 'https://uuki.live/learn/how-can-moderators-make-your-community-a-better-place', 'https://uuki.live/learn/how-to-add-binance-smart-chain-to-metamask', 'https://uuki.live/learn/how-to-add-cronos-to-metamask', 'https://uuki.live/learn/how-to-add-polygon-matic-network-to-metamask', 'https://uuki.live/learn/how-to-add-slp-to-metamask', 'https://uuki.live/learn/how-to-build-a-community-of-practice', 'https://uuki.live/learn/how-to-build-an-online-community', 'https://uuki.live/learn/how-to-connect-uniswap-to-metamask', 'https://uuki.live/learn/how-to-create-a-ronin-wallet-to-play-axie-infinity', 'https://uuki.live/learn/how-to-get-your-community-indexed-on-google-faster', 'https://uuki.live/learn/how-to-grow-a-discord-community', 'https://uuki.live/learn/how-to-start-an-online-school', 'https://uuki.live/learn/how-to-transfer-bnb-from-trust-wallet-to-binance', 'https://uuki.live/learn/how-to-transfer-crypto-from-trust-wallet-to-coinbase', 'https://uuki.live/learn/how-to-transfer-ethereum-from-coinbase-to-metamask', 'https://uuki.live/learn/how-to-transfer-ethereum-from-metamask-to-coinbase', 'https://uuki.live/learn/how-to-write-guidelines-for-your-online-community-platform-forum', 'https://uuki.live/learn/kajabi-vs-thinkific', 'https://uuki.live/learn/messaging-app-vs-community-platform', 'https://uuki.live/learn/minigpt-4-open-source-model-for-complex-vision-language-tasks-like-gpt-4', 'https://uuki.live/learn/seo-tips-to-increase-traffic-to-your-community-and-forum', 'https://uuki.live/learn/should-you-use-slack-for-your-community', 'https://uuki.live/learn/the-5-best-online-community-management-courses', 'https://uuki.live/learn/the-best-guide-to-circle-so-and-the-5-best-alternatives-for-your-community', 'https://uuki.live/learn/the-best-gumroad-alternatives-for-2023', 'https://uuki.live/learn/the-best-tribe-alternatives-for-2023', 'https://uuki.live/learn/the-essential-seo-guide-for-online-community-and-forums', 'https://uuki.live/learn/the-top-20-side-hustles-to-make-extra-money-in-2022', 'https://uuki.live/learn/the-ultimate-guide-to-building-a-customer-community', 'https://uuki.live/learn/the-ultimate-guide-to-community-management', 'https://uuki.live/learn/twitter-vs-mastodon', 'https://uuki.live/learn/username-with-only-letters-numbers-and-underscore', 'https://uuki.live/learn/what-are-poap-nfts-and-why-are-they-important', 'https://uuki.live/learn/what-is-an-online-course-in-2022', 'https://uuki.live/learn/what-is-auto-gpt-and-what-can-it-do', 'https://uuki.live/learn/what-is-huggingchat-everything-you-need-to-know-about-this-open-source-ai-chatbot', 'https://uuki.live/learn/what-is-prompt-engineering-how-to-write-an-effective-gpt-3-5-or-gpt-4-prompt', 'https://uuki.live/learn/white-label-online-courses']\n" 72 | ] 73 | } 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 19, 79 | "metadata": { 80 | "colab": { 81 | "base_uri": "https://localhost:8080/" 82 | }, 83 | "id": "ZQ6gKwYlIhjm", 84 | "outputId": "e3d716e2-21b5-4e48-dd03-3bdbd9616354" 85 | }, 86 | "outputs": [ 87 | { 88 | "output_type": "stream", 89 | "name": "stdout", 90 | "text": [ 91 | "{'output_text': 'According to a list compiled by Uuki.live, the best AI image generators include DALL-E 2, MidJourney, and WOMBO Dream.\\nSOURCES: https://uuki.live/learn/10-best-ai-image-generators-in-2023'}\n" 92 | ] 93 | } 94 | ], 95 | "source": [ 96 | "from langchain.tools import BaseTool\n", 97 | "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", 98 | "from pydantic import Field\n", 99 | "from langchain.chains.qa_with_sources.loading import load_qa_with_sources_chain, BaseCombineDocumentsChain\n", 100 | "from langchain.chat_models import ChatOpenAI\n", 101 | "import os, asyncio, trafilatura\n", 102 | "from langchain.docstore.document import Document\n", 103 | "\n", 104 | "def _get_text_splitter():\n", 105 | " return RecursiveCharacterTextSplitter(\n", 106 | " # Set a really small chunk size, just to show.\n", 107 | " chunk_size = 500,\n", 108 | " chunk_overlap = 20,\n", 109 | " length_function = len,\n", 110 | " )\n", 111 | "\n", 112 | "class WebpageQATool(BaseTool):\n", 113 | " name = \"query_webpage\"\n", 114 | " description = \"Browse a webpage and retrieve the information relevant to the question.\"\n", 115 | " text_splitter: RecursiveCharacterTextSplitter = Field(default_factory=_get_text_splitter)\n", 116 | " qa_chain: BaseCombineDocumentsChain\n", 117 | "\n", 118 | " def _run(self, question: str) -> str:\n", 119 | " docs = []\n", 120 | " for url in urls[:2]:\n", 121 | " result = trafilatura.extract(trafilatura.fetch_url(url))\n", 122 | " docs.append(Document(page_content=result, metadata={\"source\": url}))\n", 123 | " #docs = [Document(page_content=result, metadata={\"source\": url})]\n", 124 | " web_docs = self.text_splitter.split_documents(docs)\n", 125 | " results = []\n", 126 | " for i in range(0, len(web_docs), 4):\n", 127 | " input_docs = web_docs[i:i+4]\n", 128 | " window_result = self.qa_chain({\"input_documents\": input_docs, \"question\": question}, return_only_outputs=True)\n", 129 | " results.append(f\"Response from window {i} - {window_result}\")\n", 130 | " results_docs = [Document(page_content=\"\\n\".join(results), metadata={\"source\": url})]\n", 131 | " return self.qa_chain({\"input_documents\": results_docs, \"question\": question}, return_only_outputs=True)\n", 132 | "\n", 133 | " async def _arun(self, url: str, question: str) -> str:\n", 134 | " raise NotImplementedError\n", 135 | "\n", 136 | "llm = ChatOpenAI(temperature=1.0, openai_api_key=\"your-openai-key\")\n", 137 | "query_website_tool = WebpageQATool(qa_chain=load_qa_with_sources_chain(llm))\n", 138 | "print(query_website_tool.run(\"What are the best AI image generators ?\"))" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "source": [], 144 | "metadata": { 145 | "id": "IBCjAOk1NJuN" 146 | }, 147 | "execution_count": null, 148 | "outputs": [] 149 | } 150 | ] 151 | } -------------------------------------------------------------------------------- /Caching.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "authorship_tag": "ABX9TyOLHnR40BXyt6FenhWQ1cXr", 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "view-in-github", 23 | "colab_type": "text" 24 | }, 25 | "source": [ 26 | "\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "source": [ 32 | "!pip install langchain gptcache openai" 33 | ], 34 | "metadata": { 35 | "id": "Mh4Z79kYT444" 36 | }, 37 | "execution_count": null, 38 | "outputs": [] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 5, 43 | "metadata": { 44 | "id": "9aNFhMWzTZTp" 45 | }, 46 | "outputs": [], 47 | "source": [ 48 | "from gptcache import Cache\n", 49 | "from gptcache.adapter.api import init_similar_cache\n", 50 | "from langchain.cache import GPTCache\n", 51 | "import hashlib\n", 52 | "import langchain\n", 53 | "from langchain.llms import OpenAI\n", 54 | "\n", 55 | "def get_hashed_name(name):\n", 56 | " return hashlib.sha256(name.encode()).hexdigest()\n", 57 | "\n", 58 | "\n", 59 | "def init_gptcache(cache_obj: Cache, llm: str):\n", 60 | " hashed_llm = get_hashed_name(llm)\n", 61 | " init_similar_cache(cache_obj=cache_obj, data_dir=f\"similar_cache_{hashed_llm}\")\n", 62 | "\n", 63 | "\n", 64 | "langchain.llm_cache = GPTCache(init_gptcache)" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "source": [ 70 | "llm = OpenAI(model_name=\"text-davinci-002\", n=2, best_of=2, openai_api_key=\"api-key\")" 71 | ], 72 | "metadata": { 73 | "id": "8xL3ionzTzSZ" 74 | }, 75 | "execution_count": 6, 76 | "outputs": [] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "source": [ 81 | "import time\n", 82 | "start = time.time()\n", 83 | "llm(\"Tell me one rhyme\")\n", 84 | "print(\"Time taken\", time.time()-start)" 85 | ], 86 | "metadata": { 87 | "colab": { 88 | "base_uri": "https://localhost:8080/" 89 | }, 90 | "id": "oi5s5gnqUKeN", 91 | "outputId": "a1aca235-1e6f-479e-d654-87a92185d30c" 92 | }, 93 | "execution_count": 18, 94 | "outputs": [ 95 | { 96 | "output_type": "stream", 97 | "name": "stdout", 98 | "text": [ 99 | "Time taken 4.124613285064697\n" 100 | ] 101 | } 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "source": [ 107 | "start = time.time()\n", 108 | "llm(\"Tell me a rhyme\")\n", 109 | "print(\"Time taken\", time.time()-start)" 110 | ], 111 | "metadata": { 112 | "colab": { 113 | "base_uri": "https://localhost:8080/" 114 | }, 115 | "id": "K53Hsor_URzq", 116 | "outputId": "f8a9fd6f-2342-445b-eab2-1e22411ace60" 117 | }, 118 | "execution_count": 19, 119 | "outputs": [ 120 | { 121 | "output_type": "stream", 122 | "name": "stdout", 123 | "text": [ 124 | "Time taken 0.9025411605834961\n" 125 | ] 126 | } 127 | ] 128 | } 129 | ] 130 | } -------------------------------------------------------------------------------- /Code_Interpreter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "authorship_tag": "ABX9TyMk6p8iX97m7kJp+TCezjZE", 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "view-in-github", 23 | "colab_type": "text" 24 | }, 25 | "source": [ 26 | "\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": null, 32 | "metadata": { 33 | "id": "YMFnPWjWXAY5" 34 | }, 35 | "outputs": [], 36 | "source": [ 37 | "!pip install codeinterpreterapi" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "source": [ 43 | "from codeinterpreterapi import CodeInterpreterSession\n", 44 | "import os\n", 45 | "\n", 46 | "async def main():\n", 47 | " # create a session\n", 48 | " session = CodeInterpreterSession(openai_api_key=\"openai-api-key\")\n", 49 | " await session.astart()\n", 50 | "\n", 51 | " # generate a response based on user input\n", 52 | " output = await session.generate_response(\n", 53 | " \"Plot the Tesla stock for 2023 YTD\"\n", 54 | " )\n", 55 | "\n", 56 | " # ouput the response (text + image)\n", 57 | " print(\"AI: \", output.content)\n", 58 | " for file in output.files:\n", 59 | " file.show_image()\n", 60 | "\n", 61 | " # terminate the session\n", 62 | " await session.astop()\n", 63 | "\n", 64 | "await main()" 65 | ], 66 | "metadata": { 67 | "colab": { 68 | "base_uri": "https://localhost:8080/", 69 | "height": 544 70 | }, 71 | "id": "fx5_omcfXLJm", 72 | "outputId": "4ec25f23-8ef9-42b3-d422-fac54b02a797" 73 | }, 74 | "execution_count": 13, 75 | "outputs": [ 76 | { 77 | "output_type": "stream", 78 | "name": "stdout", 79 | "text": [ 80 | "INFO: Using a LocalBox which is not isolated.\n", 81 | " This is only for testing and development.\n", 82 | " Make sure to put an API-Key in production.\n", 83 | "\n", 84 | "AI: Here is the plot of Tesla's stock price for the year 2023. Please note that the data might not be available if the current year is not 2023 or beyond.\n" 85 | ] 86 | }, 87 | { 88 | "output_type": "display_data", 89 | "data": { 90 | "text/plain": [ 91 | "" 92 | ], 93 | "image/png": "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hgR1pr5OlgDwtICfW1FdJpIwaBRcbRrpGkw/XapMWLfgm5kRTduxIEPmZWtuzKCKpYpTCQUA0NvR0piB/+WQbsH006VK61vesF8XdSo6jernaAkAh2NyASAIN5FCugfTT5cqx44f1FXI7h+yrzHIha3laBBqAtNPl6of9oajrlGnI7t/SP1aHXeAkFZg+ulSOOwNdZm+TmzygY0508mqE7flRqhjMP10KUw/qMu4W5uRa5IGubCxrxHpIEw/Xao+/WDjG+p0VCrFv4clYMcP0lWYfroUOfAaJ/2grrFqnM+MYKc5Ia7aDgShZuCqB12qTIyNb6jrBLtaBbvioAOko9So/dy5c+e1115zdHSkUChnz55VHV+wYAGlgYiICNWpioqKOXPmWFhYsNnshQsXikQiDYauj8qE2PiGEEIAaqUfsVgcEBCwffv2pqciIiKK6h05ckR1fM6cOc+ePYuKirpw4cKdO3cWL16sgZD1lkSuENTKAWs/CCGkVuPb+PHjx48f3+wpJpNpb2/f6ODz588vX74cGxvbv39/APj1118nTJjwww8/ODo6djhcvVYukgIAg0Yhd5xECKHuTDNDD27dusXlcn18fD788MPy8nLyYHR0NJvNJnMPAIwePZpKpcbExDR9uUQiETSgkZB0EDnszdoMV9xBCCFNpJ+IiIj9+/dfv37922+/vX379vjx4xUKBQDweDwul6u6jE6nczgcHo/X9A6bN2+2rOfs7PzqIemmulHXLOz4QQghTYx8mzVrFvnA39+/b9++np6et27dGjVqVPvvsHr16pUrV5KPBQKBoWagulHX2PGDEEIan/fj4eFhY2OTnp4OAPb29iUlJapTcrm8oqKiaRcRADCZTIsGNBuS7iir22Yb0w9CCGk6/eTn55eXlzs4OABAWFhYVVVVfHw8eerGjRtKpTI0NFSz76hH6uecYuMbQgip0/gmEonIag0AZGVlJSYmcjgcDoezfv36adOm2dvbZ2RkfPbZZ15eXuPGjQOAXr16RURELFq06Pfff5fJZEuXLp01a1a3HfYG9X0/ttj4hhBCatV+4uLigoKCgoKCAGDlypVBQUFr166l0WjJycmTJ0/u2bPnwoULg4OD7969y2TWfcIeOnTI19d31KhREyZMGDJkyB9//NEphdATuN4oQgipqFH7CQ8PJwii6fErV6609BIOh3P48OGOxGWIMP0ghJAKLjnader2msO+H4QQwiVHO1tVtbSIX5tTLj6XWFghlgKOfEMIIQDA9NOp/nsn85uLzxseGeFji+uNIoQQYPrpPFK5ctedDACwMmXYW5oM9ODMCHbu7Wiws5oQQkgtmH46y+VnvDKR1M6Cef/zkXQa9rEhhNC/4MdiZzkYnQMAswa4YO5BCKGm8JOxU7zgCR9lV9ColLdCXLQdC0II6SJMP53iUEwOAIzpZWdvaaztWBBCSBdh+tE8sUR+OqEAAOYOdNV2LAghpKMw/WjeucRCkUTubmM2yNNa27EghJCOwvSjYQRBHHyYAwBzQl2oVNzVFCGEmofpR8Me51WlFAmYdOr0YCdtx4IQQroL04+GkVWfSX0d2aa4ugFCCLUI048mVYqlF5KLAGDuQBxvjRBCrcH0o0kn4/OlcmUfR4tAZ7a2Y0EIIZ2G6UdjlEqCnO4zd6ArhYKDDhBCqDWYfjTmfkZZdnk1i0l/PbD7biiOEELthOlHY8hBB1P79TA1woVcEUKoDZh+NKOIXxOVUgwAc3ClA4QQagdMP5pxOqFASUCIO6enHUvbsSCEkB7A9KMZDzPLAWBSXwdtB4IQQvoB009H1MoUBEGoniqURGJuFQAEu1ppLSaEENIrmH7UdvlpUZ+vrvxyPV11JK1EKJTIzYxoPtjyhhBC7YPpRz38atkXZ58qlMT2W+lF/BryYHxOJQAEurBxY1OEEGon/LhUz7dXUstEUgCQypW/3qirAJHpJ9gFW94QQqi9MP2oIT6n4nBMLgB8Os4HAI7H5mWXiQHgcW4VAARhxw9CCLUbpp/2kimUa04/BYAZwU6RI7yG97SVK4mtUS/LRZKsMjEA9HPG9IMQQu2F8/Pba/e9rBfFQo6Z0ZoJvQBg1Vif2y9LzycV1kjlAODNNbc0ZWg7RoQQ0htY+2mXvIrqn669BIA1E3pZmRkBgL+T5WcRPgBw7XkJ4JBrhBBSE6afthEEsfbc01qZcqAHZ1q/HqrjHw73nB1at69PP0w/CCGkDjXSz507d1577TVHR0cKhXL27FnyoEwm+/zzz/39/c3MzBwdHefNm1dYWKh6iZubG6WBLVu2aDb6rnHpKe/mi1IGjbJxin/DnRQoFMqGyX1eD3TswTYZ6cvVYoQIIaR31Oj7EYvFAQEB77777tSpU1UHq6urExISvvzyy4CAgMrKyo8//njy5MlxcXGqCzZs2LBo0SLyMYulf7MyhbWy9eefAcCHwz29uOaNztJp1J9nBREEgRv8IISQWtRIP+PHjx8/fnyjg5aWllFRUaqnv/32W0hISG5urotLXasUi8Wyt7d/9UC1ZevVl8UCiZu16ZIRXi1dg7kHIYTUpeG+Hz6fT6FQ2Gy26siWLVusra2DgoK+//57uVze7KskEomgAc2G9CqS8qr+is4GgI1T/I0ZNG2HgxBChkOTA69ra2s///zzt956y8LCgjyybNmyfv36cTicBw8erF69uqioaNu2bU1fuHnz5vXr12swkldRLpKYGNFMjehyhXLNmScEAVMCHYd422g7LoQQMiiUhis3t/c1FMqZM2emTJnS8KBMJps2bVp+fv6tW7dU6aehPXv2vP/++yKRiMlkNjolkUgkEgn5WCAQODs78/n8Zm/SeWQK5beXUm+8KMksFTPp1C3T/CvEsq8vpFgY069/Em7LahwzQgih1gkEAktLy5Y+zzVT+5HJZDNnzszJyblx40ZLaSM0NFQul2dnZ/v4+DQ6xWQym+akLhaVUvznvSzysUSuXHEsiUGjAMDqCb0w9yCEkMZpoO+HzD1paWnXrl2ztrZu6bLExEQqlcrl6ugA5UtPeQAwI9gp4csxkSM8AUCmIPq7Wr3Z31nboSGEkAFSo/YjEonS0+vWeM7KykpMTORwOA4ODtOnT09ISLhw4YJCoeDxeADA4XCMjIyio6NjYmJGjBjBYrGio6NXrFgxd+5cKytdnJ5ZK1PceF4MALNDXThmRp+O8+3jaHnxSdGn43yoVBzVhhBCmqdG38+tW7dGjBjR8Mj8+fPXrVvn7u7e6MqbN2+Gh4cnJCQsWbIkNTVVIpG4u7u//fbbK1eubLORrfW2wk5yLaX4vf1x9hbGD/5vJOYbhBDSCI31/YSHhzebq1pKYP369Xv48GH779/1VNNFLz/jAUCEnz3mHoQQ6hrdd8VrgiBWnUi+m1a6fHTPqJRiAIjw0+PpsQghpF+6b/q5kFx0KiEfANaceQIANuZGA9w42g4KIYS6i2664jW/um4lt6HeNkw6FQDG9bGnYcsbQgh1lW5a+9l86XmZSOrFNf9zfv/CqtobqSUz+jtpOyiEEOpGumP6icksPxqbBwCbp/oz6TR3G7OFQxoP3kMIIdSpul3jm0SuWH3mCQC8FeKCnT0IIaQt3S797LiZkVkqtmUx/2+8r7ZjQQih7qt7pZ/0EuGOW+kAsO61PpYmDG2HgxBC3Vc3Sj9KJbH69BOZghjpy53gj1N8EEJIm7pR+jkWlxebXWlqRNvweh/cnxQhhLTLYNNPeokocMPVrVdfkE9LBLWbLj4HgE/G+jhZmWo1NIQQQoabfs4lFlRVy3bdySwXSQBg08Xnwlp5XyfLBYPctB0aQgghw00/0RnlACCVK4/G5j0vEpxNLASAb6b449IGCCGkCwxz2mm1VJ6YV0U+PhCdE59TCQAT+zr4O1lqMyyEEEL1DDP9xGZXypWEg6WxTKHkCWp5gloqBVaM7qntuBBCCNUxzMY3suVtsJfN7FBX8sjUfk5eXHOtBoUQQugfBpp+MssBIMzDem6oC5NONaJTPx7lre2gEEII/cMAG98EtbIn+VUAEOZpzbUwPvXhIAoFnDk42BohhHSIAaaf2KwKJQFu1qaObBMA8OuBww0QQkjnGGDjG9nxE+Zpre1AEEIItcgA0092eTUADPTA9IMQQrrLABvf/pzfv7CqxgIXtEYIIR1mgOkHAMheH4QQQjrLABvfEEII6T5MPwghhLQA0w9CCCEtwPSDEEJICzD9IIQQ0gJMPwghhLQA0w9CCCEtUCP93Llz57XXXnN0dKRQKGfPnlUdJwhi7dq1Dg4OJiYmo0ePTktLU52qqKiYM2eOhYUFm81euHChSCTSYOgIIYT0lxrpRywWBwQEbN++vdHx77777pdffvn9999jYmLMzMzGjRtXW1tLnpozZ86zZ8+ioqIuXLhw586dxYsXayxwhBBC+oxCEITar6FQzpw5M2XKFAAgCMLR0fGTTz5ZtWoVAPD5fDs7u3379s2aNev58+e9e/eOjY3t378/AFy+fHnChAn5+fmOjo6NbiiRSCQSCflYIBA4Ozvz+XwLC4tXLBtCCCEtEggElpaWLX2ev2rfT1ZWFo/HGz16NPnU0tIyNDQ0OjoaAKKjo9lsNpl7AGD06NFUKjUmJqbpTTZv3mxZz9nZ+RVDQgghpPtedc03Ho8HAHZ2dqojdnZ25EEej8flcv95Jzqdw+GQpxpZvXr1ypUrycd8Pt/FxUUgELxiYAghhLSL/CRvqY1NJ5YcZTKZTCaTfEyGi3UghBAyDEKh0NKymW0/XzX92NvbA0BxcbGDgwN5pLi4ODAwkDxVUlKiulIul1dUVJDXt8LR0TEvL4/FYlEolPaHQfYY5eXlGVKPkQEUygCK0JSBFcrAikMysELpb3EIghAKhU37+0mvmn7c3d3t7e2vX79OphyBQBATE/Phhx8CQFhYWFVVVXx8fHBwMADcuHFDqVSGhoa2fkMqlerk5NSxYCwsLPTu19MmAyiUARShKQMrlIEVh2RghdLT4jRb7yGpkX5EIlF6ejr5OCsrKzExkcPhuLi4LF++fOPGjd7e3u7u7l9++aWjoyM5KK5Xr14RERGLFi36/fffZTLZ0qVLZ82a1VIaRAgh1K2okX7i4uJGjBhBPiZHCsyfP3/fvn2fffaZWCxevHhxVVXVkCFDLl++bGxsTF526NChpUuXjho1ikqlTps27ZdfftF4ARBCCOkjNdJPeHh4swMYKBTKhg0bNmzY0PQUh8M5fPhwx6NrNyaT+dVXX6nGLxgGAyiUARShKQMrlIEVh2RghTKw4qh0ZNopQggh9IpwyVGEEEJagOkHIYSQFmD6QQghpAWYfhBCCGkBph+EEEJagOlH+3DwIUKI1K325NSb9KNUKgFAoVBoOxANEwqFMpmMfKyPeaiioqK4uFgqlUL978gw5OXlXb58WdtRaExGRsa6detUq5YYhuzs7A8//PDKlSvaDkQzcnJyxo0b9/nnn4Nh/Sm1Qj/Sz8qVK+fOnQsANBpN27FoDEEQK1asGDdu3IQJE9auXVtTU0Oh6NM0LIIgli1bFhYWNnny5PHjx1dVVVGpVD2KvxVpaWmurq5Tp05tuHO8niII4sMPP/T29i4qKurwaoo6aM2aNb169SorK6uurtb3/3UEQbz//vteXl4PHz68ffu2UqmkUvXjk/kV6XohHz9+PGbMmIMHDx47doz8mmMYFaA7d+74+fk9fPhw1apVHh4ep0+fXr16tbaDUsPff//du3fvuLi43377bfHixTwe76OPPgIAtdYp11kymWzcuHHW1tYbN27Udiyv5MiRIzY2No8ePXr06NGuXbvI1bD0/cMaAG7cuHH79u2zZ8+eOHHijTfe0Ov/ddu2bWOz2YmJiQkJCZs2bWIwGMXFxdoOqovoxH4/rYiNje3Ro8eKFSuOHDmyatWqcePG0Wg0giD0+j9cdXX1iRMnwsLCfv31VxMTk9dff33r1q2XLl3i8/mtrA6rU27dujVp0qRvvvnGyMgIAB4/fqxqQjQASUlJRkZGJ06cGDx48DvvvBMeHq7tiDror7/+srCwuHDhgoODw9OnTwsLC728vOzt7U1NTfX6j2jfvn2enp7jxo17+PDhhQsXPD09hwwZ4u3tre241JaWlnbu3Lmff/55wYIFAFBZWZmUlER+w9brX1B7EbqNx+MlJycTBHHz5k0HB4dt27YRBCGXy7Ud1yupqqo6cODAo0ePCIJQKBQEQWzcuDE4OFipVCqVSm1H1y4lJSVZWVnkYx6PN2DAgI0bNz548ECrQb0q8ndBEMSJEyc++ugjgiDGjBkzbNgwgiBEIpE2I+uopKQkDw+PL774Ytq0aW5ubn5+fg4ODrNnz9Z2XB2nUCjEYvGoUaMOHDiwbds2Lpf7+uuve3h4ODk5nTx5UtvRqU0ikaj+5JVKZVJSkqen5/79+7UbVZfRudrP5s2bS0pKfH1933nnHSMjIzs7O3In78DAwPnz53/77bfvvfcei8XSu+bRhuWytLQku7KgviWEz+e7u7vr8pedRr8XW1tbW1tbANi9e/cHH3zQv3//a9eu/fjjj+++++769etNTEy0HW97NSoXeTA5OZncdffQoUM9evQYP358aWnpn3/+SW5qpcsaFadv374TJkz47rvvpk2bduLECQaDkZqa+u67727cuPGLL74g9OT7daNCmZqaAsCePXtcXFyOHDkybNgwOp3++uuv79mzx8vLKyAgQNvxtqHpfzny04xCodja2kokEolEAlj76WKpqam9e/f29/d/8803rayswsPDHz58SBCE6tvB48eP/fz8Fi9eTDT4oqr7mpYrOjqaqC8C+W94eDhZsdPB2k9LvxfSgQMHrl+/Tob9v//9j06np6SkaC9YNbRSrnfeeef06dMEQRw6dMjc3JxGo+n+F9Kmxbl37x5BEHw+f82aNZmZmaorv//+ezabLZPJtBdsezUtFFnDPnLkCIPBcHZ2zs/PJ6+Mj493cHC4du2aVuNtQ+t/SuRHwZAhQ+bPn0/o5EeBxulQ+tm6dWtYWBj5V1FUVBQQEDBz5sz09HSCIMiDtbW1v/32G4vFevbsGUEQt27dqqio0G7M7dFKucj/cDwez9bWNj4+nrw+IyOD0KX82kr8xL//SLKzs42MjMgPbt3XbLlSU1MJgli0aNHs2bOHDh1qZWW1bt06Lpe7bt06bcfbhmaL8+LFC4Ig+Hx+wysPHz7M5XLJNm0d17RQM2bMyMnJKS4uHjNmjLu7e05ODkEQZKs1h8PZs2ePtkNuTZsfBRKJ5N13350wYYJQKNRyrF1CV9qv5HL5s2fPuFwuObTa3t7+P//5T25u7u7duwGATqcTBMFkMidMmDBkyJA5c+YMGTJkwoQJJSUl2g68Da2Xi2w/vHbtmo2NTb9+/VJSUsLDw/39/WtqanSkabH1+OHfQ93Onj0bFhY2cuRI7cSqjpbKdeDAAQCorq7++++/fXx8Hj9+/NVXX3311Vfr169PTU3VdtQtaqk4+/btA4BGOzRHR0cPHDjQ399fK6G2X0uF+u9//8vlcj/55JPi4uJff/01Ly+PQqFcvHjRy8tr9OjR2o66RW1+FCiVSiMjIxsbm6KiInNzc0L/Byi2SSc+4wCATqdLJJKamhqlUkkO/JgxY0ZwcHBMTMzjx4+hvo9ELpdXVFQkJSX5+vryeDwfHx8tx92WNssFACkpKd7e3qtXr+7bt6+Tk1NRUZHu9J20J/68vLysrKyPPvpoy5Yts2bNsrS01P2/nJbKdffu3ezs7LVr196+ffuPP/5wdXUFgA8++ODbb7/18PDQdtQtas+vKTc3Nzs7e+nSpWfPnp03bx7o/AjsZgvVv3//e/fuJScnjxs37pdffjl8+PDIkSOnT58+a9as0aNH9+jRQ9tRt6jN3xE51XTUqFFJSUkZGRmG3/EDutH3Q45ku3nzJpVKffz4MVHf2nbr1i0vL6/jx4+Tl8XGxvbs2TMwMJBsfNN97SyXn58fhUIZNGiQqv1NR7Qn/rS0tNWrV7u4uAwaNCgpKUmr8bZXK+Xy8PA4ceKEdsNTV3t+TS9fvvzkk0/s7e3DwsL0otmtlUJ5enoeO3aMvCw2NnbXrl2ff/65jv/fa+dHAUEQJ0+eXLhwYVlZGfb9aF7DNk3Vz5f8TdTU1AwfPnz06NENT3l6em7YsIF8XFZWRvam6qAOlGv9+vUEQQgEgh9++OH8+fNdHfG/dTj+mpqa+/fv3759u6sjbp8O/3/TzT/+Dv+aqqurb968ef369a6OuB1e5TNBB3W4OGSK0s3/eJ2k69KPRCJZunTpqFGj3njjjaNHj5I/ZalUSp6Vy+U8Hu/WrVsMBmPnzp1kR1xFRUXfvn1/++03Qod/K69YLq3T9/hbYmDlMrDikAysUAZWnC7QReln//79Dg4O4eHh+/fvHz16dFhY2KVLl1Rnf/75ZyMjo3379hEEsXHjRi6X+9577925c2fFihXu7u7Pnz/vmiA7QN/Lpe/xt8TAymVgxSEZWKEMrDhdoyvSz4sXL6ZPn/7jjz+ST7Ozs+3s7KKiogiCqKqqmj17tqOj419//aWq3/zyyy9Dhw719/cPCAiIiYnpggg7Rt/Lpe/xt8TAymVgxSEZWKEMrDhdpivST0VFRUxMTGVlJfk0ISFh7Nix0dHRZHtoTEyMal6CarKLQqFoOFFON+l7ufQ9/pYYWLkMrDgkAyuUgRWny3RW+jlx4kRUVFRhYWGj45GRkXQ6PTAw0MbGZvz48Xfv3iX0ag03fS+XvsffEgMrl4EVh2RghTKw4miF5tPP/v37uVxuSEiIra3t4MGDyTnwqpw/a9asy5cvi0Si+/fvz5w5MywsTOMBdBJ9L5e+x98SAyuXgRWHZGCFMrDiaJEm049MJvvpp5969er1559/SiSS+/fvz5s3b/z48bW1tUT90MOGA9i++OKLoKCggoICDcbQGfS9XPoef0sMrFwGVhySgRXKwIqjdZpc9UAsFpeWls6fP59cyXXQoEG9e/cWCARyuRzqF85RTeVVKBQZGRnBwcGOjo4ajKEz6Hu59D3+lhhYuQysOCQDK5SBFUf7Xj2DvXz5suGi1GQrJ1kVPXToUGBgoEQiaXh9dXV1fn7+e++95+Pjc/PmTUJX5/Toe7n0Pf6WGFi5DKw4JAMrlIEVR3e8Uvo5duyYm5ubj49PSEjIn3/+qTquagadPXv2ggULiAY9b6dOnVq2bJmdnV14eHhaWtqrvHvn0fdy6Xv8LTGwchlYcUgGVigDK46u6Xj6uXr1qpub2/bt2y9fvrxy5UoGg/HHH3/U1NQQ9euf19TU9O3b98CBAw1f9ezZsx9++EGXt+XQ93Lpe/wtMbByGVhxSAZWKAMrjg7qSPohK5Lr168PDg5WLSmxZMmS/v37N9zrpaCgwM3N7eXLlwRBvHz5cvny5ZoIuBPpe7n0Pf6WGFi5DKw4JAMrlIEVR2d1ZOgB2beWkpLi6enJYDBkMhkAbNy40djY+Ny5czwej7zs2rVrzs7ODg4OH3/8ce/evXNzc8mRIRrsuNIsfS+XvsffEgMrl4EVh2RghTKw4uiudqapq1evfvTRRz/++KNqiYg//viDxWKRLZ7kF4Q//vijZ8+eqq62GTNmWFlZWVtb9+nTJzY2VrNpU1P0vVz6Hn9LDKxcBlYckoEVysCKoxfaTj+FhYWTJk3icrlz5szx9/e3tLQkfz0vXrzo0aPHl19+SRCEauCHvb09ufCRWCyeNGmSk5PT0aNHOzH8V6Dv5dL3+FtiYOUysOKQDKxQBlYcPdJG+hGLxfPnz3/zzTdVyxOFhISQIz0EAsHGjRtNTExyc3OJ+tbS4cOHv/fee+SVcXFxnRj4q9H3cul7/C0xsHIZWHFIBlYoAyuOfmmj78fU1JTJZC5YsMDd3Z2cWjVhwgRyeXAWizV79ux+/frNnDkzJyeHQqHk5uaWlJRMmTKFfG1wcHBntxx2mL6XS9/jb4mBlcvAikMysEIZWHH0TJsJSjXwgxzqPnv27EWLFqnO5ufne3l5ubm5TZ8+3dHRceTIkTweT9M5slPoe7n0Pf6WGFi5DKw4JAMrlIEVR49QCDXHaQwZMmTRokXz589XKpUAQKVS09PT4+PjY2JiAgIC5s+f3zlZstPpe7n0Pf6WGFi5DKw4JAMrlIEVR6eplawyMjLs7OxULZ6NlprQX/peLn2PvyUGVi4DKw7JwAplYMXRce2d90MQBADcu3fP3NycbPFcv379xx9/XFJS0om5sfPpe7n0Pf6WGFi5DKw4JAMrlIEVRy/Q23kdOQ/r0aNH06ZNi4qKWrx4cXV19YEDB7hcbmeG1+n0vVz6Hn9LDKxcBlYckoEVysCKox/aX1Gqqanx8vKiUChMJnPLli2dUBXTDn0vl77H3xIDK5eBFYdkYIUysOLoPvWGHowZM8bb23vbtm3GxsadlxG7nr6XS9/jb4mBlcvAikMysEIZWHF0nHrpR6FQ0Gi0zotGW/S9XPoef0sMrFwGVhySgRXKwIqj49QeeI0QQgi9Ok1uto0QQgi1E6YfhBBCWoDpByGEkBZg+kEIIaQFmH4QQghpAaYfhBBCWoDpByGEkBZg+kFIYxYsWEChUCgUCoPBsLOzGzNmzJ49e8h1+1uxb98+NpvdJQEipEMw/SCkSREREUVFRdnZ2ZcuXRoxYsTHH388adIkchtNhFBDmH4Q0iQmk2lvb9+jR49+/fqtWbPm3Llzly5d2rdvHwBs27bN39/fzMzM2dl5yZIlIpEIAG7duvXOO+/w+Xyy2rRu3ToAkEgkq1at6tGjh5mZWWho6K1bt7RZJIQ6B6YfhDrRyJEjAwICTp8+DQBUKvWXX3559uzZX3/9dePGjc8++wwABg0a9NNPP1lYWBQVFRUVFa1atQoAli5dGh0dffTo0eTk5BkzZkRERKSlpWm5JAhpGq75hpDGLFiwoKqq6uzZsw0Pzpo1Kzk5OSUlpeHBkydPfvDBB2VlZQCwb9++5cuXV1VVkadyc3M9PDxyc3MdHR3JI6NHjw4JCdm0aVMXFAGhLtPe7eYQQh1DEAS5ldm1a9c2b96cmpoqEAjkcnltbW11dbWpqWmj6588eaJQKHr27Kk6IpFIrK2tuzRohDofph+EOtfz58/d3d2zs7MnTZr04YcffvPNNxwO5969ewsXLpRKpU3Tj0gkotFo8fHxDVf+Nzc379qoEep0mH4Q6kQ3btx48uTJihUr4uPjlUrl1q1bqVQqABw/flx1jZGRkUKhUD0NCgpSKBQlJSVDhw7VQsQIdRVMPwhpkkQi4fF4CoWiuLj48uXLmzdvnjRp0rx5854+fSqTyX799dfXXnvt/v37v//+u+olbm5uIpHo+vXrAQEBpqamPXv2nDNnzrx587Zu3RoUFFRaWnr9+vW+fftOnDhRi+VCSPO0utU3QgZl/vz55J8VnU63tbUdPXr0nj17FAoFeXbbtm0ODg4mJibjxo3bv38/AFRWVpKnPvjgA7J356uvviIIQiqVrl271s3NjcFgODg4vPHGG8nJyVoqE0KdBUe+IYQQ0gKc94MQQkgLMP0ghBDSAkw/CCGEtADTD0IIIS3A9IMQQkgLMP0ghBDSAkw/CCGEtADTD0IIIS3A9IMQQkgLMP0ghBDSAkw/CCGEtOD/ARqKDcgx2IrjAAAAAElFTkSuQmCC\n" 94 | }, 95 | "metadata": {} 96 | } 97 | ] 98 | } 99 | ] 100 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Anil Chandra Naidu Matcha 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Langchain_agents.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "authorship_tag": "ABX9TyOugElqxWYoP/G87VltE6pO", 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "view-in-github", 23 | "colab_type": "text" 24 | }, 25 | "source": [ 26 | "\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "source": [ 32 | "!pip install langchain openai duckpy" 33 | ], 34 | "metadata": { 35 | "id": "UO_dU6ABp0wl" 36 | }, 37 | "execution_count": null, 38 | "outputs": [] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 18, 43 | "metadata": { 44 | "colab": { 45 | "base_uri": "https://localhost:8080/" 46 | }, 47 | "id": "SQGXtJlgpra6", 48 | "outputId": "f1b9de5b-9200-4ba6-af77-aee34638853d" 49 | }, 50 | "outputs": [ 51 | { 52 | "output_type": "stream", 53 | "name": "stdout", 54 | "text": [ 55 | "\n", 56 | "\n", 57 | "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", 58 | "\u001b[32;1m\u001b[1;3m I need to find out who the Wimbledon 2023 champion is first.\n", 59 | "Action: search\n", 60 | "Action Input: Wimbledon 2023 champion\u001b[0m\n", 61 | "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Carlos Alcaraz overcomes Novak Djokovic in five-set thriller to win ...', 'description': 'Updated 3:31 PM EDT, Sun July 16, 2023 Link Copied! Ad Feedback The final lasted nearly five hours. Clive Brunskill/Getty Images CNN — World No. 1 Carlos Alcaraz beat reigning champion Novak...', 'url': 'https://www.cnn.com/2023/07/15/sport/wimbledon-mens-final-novak-djokovic-carlos-alcaraz-spt-intl/index.html'}, {'title': 'Wimbledon 2023: Scores, results, how to watch, notable matches ...', 'description': 'The 2023 Wimbledon Championships have come to an end with Carlos Alcaraz and Markéta Vondroušová becoming the latest winners of the iconic grass tournament singles events in England. Alcaraz,...', 'url': 'https://www.cbssports.com/tennis/news/wimbledon-2023-scores-results-how-to-watch-notable-matches-schedule-from-the-all-england-club-in-london/'}, {'title': '2023 Wimbledon Championships - How to watch - ESPN', 'description': 'Grass court season is officially back with the 2023 Wimbledon Championships. The 136th edition takes place July 3-16 at the All England Club in London. Defending champion Novak Djokovic is seeking ...', 'url': 'https://www.espn.com/tennis/story/_/id/37906741/how-watch-2023-wimbledon-championships'}, {'title': \"Wimbledon men's singles final 2023: Carlos Alcaraz beats Novak Djokovic ...\", 'description': \"Wimbledon men's singles final 2023: Carlos Alcaraz beats Novak Djokovic - as it happened Carlos Alcaraz recovered from a set down to topple Djokovic 1-6, 7-6 (6), 6-1, 3-6, 6-4 and win his...\", 'url': 'https://www.theguardian.com/sport/live/2023/jul/16/wimbledon-mens-singles-final-2023-carlos-alcaraz-v-novak-djokovic-live'}, {'title': \"Who won Wimbledon 2023? Full list of winners from this year's ... - Metro\", 'description': 'Carlos Alcaraz beat Novak Djokovic in an epic five set duel to clinch his second Grand Slam title following on from his US Open triumph last year. Alcaraz stunned Djokovic on Centre Court (Picture:...', 'url': 'https://metro.co.uk/2023/07/17/who-won-wimbledon-2023-full-list-of-winners-from-this-years-championships-19139566/'}]\u001b[0m\n", 62 | "Thought:\u001b[32;1m\u001b[1;3m I need to find out more information about Carlos Alcaraz.\n", 63 | "Action: search\n", 64 | "Action Input: Carlos Alcaraz hometown\u001b[0m\n", 65 | "Observation: \u001b[36;1m\u001b[1;3m[{'title': \"'This boy was born to be No 1': the making of Carlos Alcaraz\", 'description': \"The mural of Carlos Alcaraz in his hometown of El Palmar, and and him with his former coach Kiko Navarro. Composite: Getty Images Carlos Alcaraz 'This boy was born to be No 1': the making...\", 'url': 'https://www.theguardian.com/sport/2023/may/26/born-to-be-no-1-tennis-the-making-of-carlos-alcaraz'}, {'title': \"Carlos Alcaraz's hometown: Everything you need to know about ... - MSN\", 'description': \"Carlos Alcaraz's hometown: Everything you need to know about where the Wimbledon Champion lives Story by Ayush Vashistha • 52m ago C arlos Alcaraz, the 2023 Wimbledon champion, has taken...\", 'url': 'https://www.msn.com/en-us/sports/tennis/carlos-alcarazs-hometown-everything-you-need-to-know-about-where-the-wimbledon-champion-lives/ar-AA1e0bnp'}, {'title': \"Carlos Alcaraz's hometown: Everything you need to know ... - Sportskeeda\", 'description': \"The 20-year-old was born in El Palmar, a small village in Spain's Murcia region. It was the Real Sociedad Club de Campo Murcia where he started playing the sport. His father worked at the club as a...\", 'url': 'https://www.sportskeeda.com/tennis/carlos-alcaraz-s-hometown-everything-need-know-wimbledon-champion-lives'}, {'title': 'Carlos Alcaraz - Wikipedia', 'description': 'Early life Carlos Alcaraz Garfia was born on 5 May 2003, in El Palmar, Murcia, Spain to parents Carlos Alcaraz González and Virginia Garfia Escandón. He has three siblings. He started playing tennis at the Real Sociedad Club de Campo de Murcia ( Royal Society Murciashire Club) where his father was the tennis academy director.', 'url': 'https://en.wikipedia.org/wiki/Carlos_Alcaraz'}, {'title': 'Carlos Alcaraz Stats, News, Pictures, Bio, Videos - ESPN', 'description': 'ATP Rank #1 Birth Date May 5, 2003 (Age: 20) Hometown El Palmar, Murcia, Spain Height 6-0 Weight 163 lbs. 2023 Stats Go to Carlos Alcaraz Player Profile Results Videos Photos STATS CARLOS...', 'url': 'https://www.espn.com/tennis/player/_/id/3782/carlos-alcaraz'}]\u001b[0m\n", 66 | "Thought:\u001b[32;1m\u001b[1;3m Carlos Alcaraz is from El Palmar, Murcia, Spain.\n", 67 | "Final Answer: The hometown of the Wimbledon 2023 champion is El Palmar, Murcia, Spain.\u001b[0m\n", 68 | "\n", 69 | "\u001b[1m> Finished chain.\u001b[0m\n" 70 | ] 71 | }, 72 | { 73 | "output_type": "execute_result", 74 | "data": { 75 | "text/plain": [ 76 | "{'input': 'What is the hometown of the Wimbledon 2023 champion?',\n", 77 | " 'output': 'The hometown of the Wimbledon 2023 champion is El Palmar, Murcia, Spain.'}" 78 | ] 79 | }, 80 | "metadata": {}, 81 | "execution_count": 18 82 | } 83 | ], 84 | "source": [ 85 | "from langchain.utilities import GoogleSerperAPIWrapper\n", 86 | "from langchain.llms.openai import OpenAI\n", 87 | "from langchain.agents import initialize_agent, Tool\n", 88 | "from langchain.agents import AgentType\n", 89 | "import os\n", 90 | "\n", 91 | "os.environ[\"OPENAI_API_KEY\"] = \"openai-key\"\n", 92 | "from duckpy import Client\n", 93 | "duckduckgo_client = Client()\n", 94 | "\n", 95 | "from langchain.tools import tool\n", 96 | "\n", 97 | "@tool(\"search\")\n", 98 | "def search_api(query: str) -> str:\n", 99 | " \"\"\"Useful for when you need to answer questions about current events. You should ask targeted questions.\"\"\"\n", 100 | " output = duckduckgo_client.search(query)\n", 101 | " output = output[:5]\n", 102 | " return str(output)\n", 103 | "\n", 104 | "\n", 105 | "llm = OpenAI(temperature=0)\n", 106 | "\n", 107 | "tools = []\n", 108 | "tools.append(search_api)\n", 109 | "agent = initialize_agent(tools, llm, agent=\"zero-shot-react-description\", verbose=True)\n", 110 | "\n", 111 | "agent(\n", 112 | " \"What is the hometown of the Wimbledon 2023 champion?\"\n", 113 | ")" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "source": [], 119 | "metadata": { 120 | "id": "zuCTs2jwtJ52" 121 | }, 122 | "execution_count": null, 123 | "outputs": [] 124 | } 125 | ] 126 | } -------------------------------------------------------------------------------- /Llama2_langchain.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "gpuType": "T4", 8 | "authorship_tag": "ABX9TyNyKthUUCku8E5nOkZF/uSF", 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "name": "python3", 13 | "display_name": "Python 3" 14 | }, 15 | "language_info": { 16 | "name": "python" 17 | }, 18 | "accelerator": "GPU" 19 | }, 20 | "cells": [ 21 | { 22 | "cell_type": "markdown", 23 | "metadata": { 24 | "id": "view-in-github", 25 | "colab_type": "text" 26 | }, 27 | "source": [ 28 | "\"Open" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": { 35 | "id": "JvA14xp_3mFM" 36 | }, 37 | "outputs": [], 38 | "source": [ 39 | "!pip install langchain llama-cpp-python" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "source": [ 45 | "from langchain.llms import LlamaCpp\n", 46 | "from langchain.callbacks.manager import CallbackManager\n", 47 | "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler\n", 48 | "from langchain import LLMChain, PromptTemplate\n", 49 | "from langchain.memory import ConversationBufferWindowMemory" 50 | ], 51 | "metadata": { 52 | "id": "nW-A1rkE3p5l" 53 | }, 54 | "execution_count": 3, 55 | "outputs": [] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "source": [ 60 | "callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])\n", 61 | "!wget https://huggingface.co/TheBloke/Llama-2-13B-chat-GGML/resolve/main/llama-2-13b-chat.ggmlv3.q4_0.bin" 62 | ], 63 | "metadata": { 64 | "colab": { 65 | "base_uri": "https://localhost:8080/" 66 | }, 67 | "id": "5ow8LC6N3vy2", 68 | "outputId": "07dfe486-0334-43ec-b277-60a81c88e68f" 69 | }, 70 | "execution_count": 5, 71 | "outputs": [ 72 | { 73 | "output_type": "stream", 74 | "name": "stdout", 75 | "text": [ 76 | "--2023-07-27 15:04:12-- https://huggingface.co/TheBloke/Llama-2-13B-chat-GGML/resolve/main/llama-2-13b-chat.ggmlv3.q4_0.bin\n", 77 | "Resolving huggingface.co (huggingface.co)... 18.172.134.24, 18.172.134.4, 18.172.134.124, ...\n", 78 | "Connecting to huggingface.co (huggingface.co)|18.172.134.24|:443... connected.\n", 79 | "HTTP request sent, awaiting response... 302 Found\n", 80 | "Location: https://cdn-lfs.huggingface.co/repos/cd/43/cd4356b11767f5136b31b27dbb8863d6dd69a4010e034ef75be9c2c12fcd10f7/f79142715bc9539a2edbb4b253548db8b34fac22736593eeaa28555874476e30?response-content-disposition=attachment%3B+filename*%3DUTF-8%27%27llama-2-13b-chat.ggmlv3.q4_0.bin%3B+filename%3D%22llama-2-13b-chat.ggmlv3.q4_0.bin%22%3B&response-content-type=application%2Foctet-stream&Expires=1690729452&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTY5MDcyOTQ1Mn19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5odWdnaW5nZmFjZS5jby9yZXBvcy9jZC80My9jZDQzNTZiMTE3NjdmNTEzNmIzMWIyN2RiYjg4NjNkNmRkNjlhNDAxMGUwMzRlZjc1YmU5YzJjMTJmY2QxMGY3L2Y3OTE0MjcxNWJjOTUzOWEyZWRiYjRiMjUzNTQ4ZGI4YjM0ZmFjMjI3MzY1OTNlZWFhMjg1NTU4NzQ0NzZlMzA%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qJnJlc3BvbnNlLWNvbnRlbnQtdHlwZT0qIn1dfQ__&Signature=bVTsMyQlkiWwJigDmpnP1Np8SiPsf4eFzKeBLQrCpncZQwGKKC24dUpS2bd2pczif20DvqWV9w98feD9MtOT0JhChYEFZI1WKXXGWeM4XOG4CCxviS-1SgpEv0C6XHbUbKVIYjRJAhIXS6NAq2IG5y8zMa3b748gfFVfmiz1%7EUoWCQ9PXW4D25xcE9d7PAPyK909YuYSkpxLtkGePLEZpjkUAn9F1IdUccb4ZDBySYtvDNgi4JuP%7ERTZubbsdYF3TdOrm3V%7EhaM4WMxIRLV4CyYTHIEIIbOO8eBjTGFhKfKJGFyizRCom0sfkB6wasIsU-1JP3qQr-dk68Ug%7EiTGfg__&Key-Pair-Id=KVTP0A1DKRTAX [following]\n", 81 | "--2023-07-27 15:04:12-- https://cdn-lfs.huggingface.co/repos/cd/43/cd4356b11767f5136b31b27dbb8863d6dd69a4010e034ef75be9c2c12fcd10f7/f79142715bc9539a2edbb4b253548db8b34fac22736593eeaa28555874476e30?response-content-disposition=attachment%3B+filename*%3DUTF-8%27%27llama-2-13b-chat.ggmlv3.q4_0.bin%3B+filename%3D%22llama-2-13b-chat.ggmlv3.q4_0.bin%22%3B&response-content-type=application%2Foctet-stream&Expires=1690729452&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTY5MDcyOTQ1Mn19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5odWdnaW5nZmFjZS5jby9yZXBvcy9jZC80My9jZDQzNTZiMTE3NjdmNTEzNmIzMWIyN2RiYjg4NjNkNmRkNjlhNDAxMGUwMzRlZjc1YmU5YzJjMTJmY2QxMGY3L2Y3OTE0MjcxNWJjOTUzOWEyZWRiYjRiMjUzNTQ4ZGI4YjM0ZmFjMjI3MzY1OTNlZWFhMjg1NTU4NzQ0NzZlMzA%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qJnJlc3BvbnNlLWNvbnRlbnQtdHlwZT0qIn1dfQ__&Signature=bVTsMyQlkiWwJigDmpnP1Np8SiPsf4eFzKeBLQrCpncZQwGKKC24dUpS2bd2pczif20DvqWV9w98feD9MtOT0JhChYEFZI1WKXXGWeM4XOG4CCxviS-1SgpEv0C6XHbUbKVIYjRJAhIXS6NAq2IG5y8zMa3b748gfFVfmiz1%7EUoWCQ9PXW4D25xcE9d7PAPyK909YuYSkpxLtkGePLEZpjkUAn9F1IdUccb4ZDBySYtvDNgi4JuP%7ERTZubbsdYF3TdOrm3V%7EhaM4WMxIRLV4CyYTHIEIIbOO8eBjTGFhKfKJGFyizRCom0sfkB6wasIsU-1JP3qQr-dk68Ug%7EiTGfg__&Key-Pair-Id=KVTP0A1DKRTAX\n", 82 | "Resolving cdn-lfs.huggingface.co (cdn-lfs.huggingface.co)... 18.154.185.27, 18.154.185.94, 18.154.185.26, ...\n", 83 | "Connecting to cdn-lfs.huggingface.co (cdn-lfs.huggingface.co)|18.154.185.27|:443... connected.\n", 84 | "HTTP request sent, awaiting response... 200 OK\n", 85 | "Length: 7323305088 (6.8G) [application/octet-stream]\n", 86 | "Saving to: ‘llama-2-13b-chat.ggmlv3.q4_0.bin’\n", 87 | "\n", 88 | "llama-2-13b-chat.gg 100%[===================>] 6.82G 244MB/s in 29s \n", 89 | "\n", 90 | "2023-07-27 15:04:41 (240 MB/s) - ‘llama-2-13b-chat.ggmlv3.q4_0.bin’ saved [7323305088/7323305088]\n", 91 | "\n" 92 | ] 93 | } 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "source": [ 99 | "n_gpu_layers = 1 # Metal set to 1 is enough.\n", 100 | "n_batch = 512 # Should be between 1 and n_ctx, consider the amount of RAM of your Apple Silicon Chip.\n", 101 | "\n", 102 | "# Make sure the model path is correct for your system!\n", 103 | "llm = LlamaCpp(\n", 104 | " model_path=\"./llama-2-13b-chat.ggmlv3.q4_0.bin\",\n", 105 | " n_gpu_layers=n_gpu_layers,\n", 106 | " n_batch=n_batch,\n", 107 | " f16_kv=True, # MUST set to True, otherwise you will run into problem after a couple of calls\n", 108 | " callback_manager=callback_manager,\n", 109 | " verbose=True,\n", 110 | ")" 111 | ], 112 | "metadata": { 113 | "colab": { 114 | "base_uri": "https://localhost:8080/" 115 | }, 116 | "id": "F43qNzKf3zkT", 117 | "outputId": "50baf41c-ef17-4258-ddd7-843040e58178" 118 | }, 119 | "execution_count": 8, 120 | "outputs": [ 121 | { 122 | "output_type": "stream", 123 | "name": "stderr", 124 | "text": [ 125 | "AVX = 1 | AVX2 = 1 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 1 | VSX = 0 | \n" 126 | ] 127 | } 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "source": [ 133 | "template = \"\"\"Assistant is a powerful large language model.\n", 134 | "{history}\n", 135 | "Human: {human_input}\n", 136 | "Assistant:\"\"\"\n", 137 | "\n", 138 | "prompt = PromptTemplate(input_variables=[\"history\", \"human_input\"], template=template)\n", 139 | "\n", 140 | "chatbot = LLMChain(\n", 141 | " llm=llm,\n", 142 | " prompt=prompt,\n", 143 | " verbose=True,\n", 144 | " memory=ConversationBufferWindowMemory(k=2),\n", 145 | ")" 146 | ], 147 | "metadata": { 148 | "id": "d-7_mXzb4Sp1" 149 | }, 150 | "execution_count": 9, 151 | "outputs": [] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "source": [ 156 | "prompt = \"Write a tweet on AI.\"\n", 157 | "\n", 158 | "output = chatbot.predict(human_input=prompt)" 159 | ], 160 | "metadata": { 161 | "colab": { 162 | "base_uri": "https://localhost:8080/" 163 | }, 164 | "id": "TQ4ITMx64s0O", 165 | "outputId": "dd2135e5-f9c8-41d6-816e-b59ccd57827e" 166 | }, 167 | "execution_count": 10, 168 | "outputs": [ 169 | { 170 | "output_type": "stream", 171 | "name": "stdout", 172 | "text": [ 173 | "\n", 174 | "\n", 175 | "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n", 176 | "Prompt after formatting:\n", 177 | "\u001b[32;1m\u001b[1;3mAssistant is a powerful large language model.\n", 178 | "\n", 179 | "Human: Write a tweet on AI.\n", 180 | "Assistant:\u001b[0m\n", 181 | " \"AI is revolutionizing the way we live and work, enabling us to automate tasks, make decisions, and create new products and services. But let's not forget to use AI responsibly and ethically, as it can also have unintended consequences.\" #AI #responsibleai\n", 182 | "\u001b[1m> Finished chain.\u001b[0m\n" 183 | ] 184 | } 185 | ] 186 | } 187 | ] 188 | } -------------------------------------------------------------------------------- /LocalGPT.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "view-in-github", 7 | "colab_type": "text" 8 | }, 9 | "source": [ 10 | "\"Open" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "metadata": { 17 | "id": "rWXECyGfAtNo" 18 | }, 19 | "outputs": [], 20 | "source": [ 21 | "!pip install gpt4all langchain chromadb" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": { 28 | "id": "CtfGYS_dAyC6" 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "from langchain.document_loaders import WebBaseLoader\n", 33 | "\n", 34 | "loader = WebBaseLoader(\"https://uuki.live/\")\n", 35 | "data = loader.load()\n", 36 | "\n", 37 | "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", 38 | "\n", 39 | "text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)\n", 40 | "all_splits = text_splitter.split_documents(data)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 3, 46 | "metadata": { 47 | "colab": { 48 | "base_uri": "https://localhost:8080/" 49 | }, 50 | "id": "opIK5tZ0A3iW", 51 | "outputId": "ea9fe1af-3286-46ce-cd92-85e34db6850a" 52 | }, 53 | "outputs": [ 54 | { 55 | "output_type": "stream", 56 | "name": "stderr", 57 | "text": [ 58 | "100%|██████████| 45.5M/45.5M [00:00<00:00, 320MiB/s]\n" 59 | ] 60 | }, 61 | { 62 | "output_type": "stream", 63 | "name": "stdout", 64 | "text": [ 65 | "Model downloaded at: /root/.cache/gpt4all/ggml-all-MiniLM-L6-v2-f16.bin\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "from langchain.vectorstores import Chroma\n", 71 | "from langchain.embeddings import GPT4AllEmbeddings\n", 72 | "\n", 73 | "vectorstore = Chroma.from_documents(documents=all_splits, embedding=GPT4AllEmbeddings())" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": 4, 79 | "metadata": { 80 | "id": "7PfDiFmSA5tT" 81 | }, 82 | "outputs": [], 83 | "source": [ 84 | "question = \"What is UUKI ?\"\n", 85 | "docs = vectorstore.similarity_search(question)[:2]" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 5, 91 | "metadata": { 92 | "id": "u-C9VjzvCBIj", 93 | "colab": { 94 | "base_uri": "https://localhost:8080/" 95 | }, 96 | "outputId": "55335d42-c6d7-433e-a4b2-df0608118f53" 97 | }, 98 | "outputs": [ 99 | { 100 | "output_type": "stream", 101 | "name": "stdout", 102 | "text": [ 103 | "--2023-07-17 03:18:11-- https://gpt4all.io/models/ggml-gpt4all-j-v1.3-groovy.bin\n", 104 | "Resolving gpt4all.io (gpt4all.io)... 172.67.71.169, 104.26.1.159, 104.26.0.159, ...\n", 105 | "Connecting to gpt4all.io (gpt4all.io)|172.67.71.169|:443... connected.\n", 106 | "HTTP request sent, awaiting response... 200 OK\n", 107 | "Length: 3785248281 (3.5G)\n", 108 | "Saving to: ‘ggml-gpt4all-j-v1.3-groovy.bin’\n", 109 | "\n", 110 | "ggml-gpt4all-j-v1.3 100%[===================>] 3.52G 39.8MB/s in 75s \n", 111 | "\n", 112 | "2023-07-17 03:19:27 (48.5 MB/s) - ‘ggml-gpt4all-j-v1.3-groovy.bin’ saved [3785248281/3785248281]\n", 113 | "\n" 114 | ] 115 | } 116 | ], 117 | "source": [ 118 | "!wget https://gpt4all.io/models/ggml-gpt4all-j-v1.3-groovy.bin" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 6, 124 | "metadata": { 125 | "colab": { 126 | "base_uri": "https://localhost:8080/" 127 | }, 128 | "id": "cjKA3QHHEnK_", 129 | "outputId": "5528060c-2561-445b-870f-2d21907fc912" 130 | }, 131 | "outputs": [ 132 | { 133 | "output_type": "stream", 134 | "name": "stdout", 135 | "text": [ 136 | "Found model file at ./ggml-gpt4all-j-v1.3-groovy.bin\n" 137 | ] 138 | } 139 | ], 140 | "source": [ 141 | "from langchain.llms import GPT4All\n", 142 | "\n", 143 | "llm = GPT4All(\n", 144 | " model=\"./ggml-gpt4all-j-v1.3-groovy.bin\",\n", 145 | " max_tokens=2048,\n", 146 | ")" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 7, 152 | "metadata": { 153 | "id": "A0oX6hyWEuEP", 154 | "colab": { 155 | "base_uri": "https://localhost:8080/" 156 | }, 157 | "outputId": "f9c8f7e6-095d-471d-9a90-9ded9a0c5533" 158 | }, 159 | "outputs": [ 160 | { 161 | "output_type": "execute_result", 162 | "data": { 163 | "text/plain": [ 164 | "{'output_text': \" UUKI (Unified Universal Knowledge Infrastructure) is a web3-based community platform that empowers users to create their own content, build relationships with other members of the community, engage in discussions on various topics related to Web3 technology and products. It offers features such as live events, courses, coaching sessions, influencers' profiles, and one-time payment options for premium content creation. UUKI is designed specifically for creators, brands, and products built on web3 technologies like blockchain, decentralized applications (dApps), smart contracts, etc., making it an ideal platform to monetize their online presence or build a community around specific projects/products.\"}" 165 | ] 166 | }, 167 | "metadata": {}, 168 | "execution_count": 7 169 | } 170 | ], 171 | "source": [ 172 | "from langchain.chains.question_answering import load_qa_chain\n", 173 | "from langchain import PromptTemplate\n", 174 | "\n", 175 | "# Prompt\n", 176 | "template = \"\"\"Use the following pieces of context to answer the question at the end.\n", 177 | "If you don't know the answer, just say that you don't know, don't try to make up an answer.\n", 178 | "Use three sentences maximum and keep the answer as concise as possible.\n", 179 | "Always say \"thanks for asking!\" at the end of the answer.\n", 180 | "{context}\n", 181 | "Question: {question}\n", 182 | "Helpful Answer:\"\"\"\n", 183 | "QA_CHAIN_PROMPT = PromptTemplate(\n", 184 | " input_variables=[\"context\", \"question\"],\n", 185 | " template=template,\n", 186 | ")\n", 187 | "\n", 188 | "# Chain\n", 189 | "chain = load_qa_chain(llm, chain_type=\"stuff\", prompt=QA_CHAIN_PROMPT)\n", 190 | "\n", 191 | "# Run\n", 192 | "chain({\"input_documents\": docs, \"question\": question}, return_only_outputs=True)" 193 | ] 194 | } 195 | ], 196 | "metadata": { 197 | "colab": { 198 | "provenance": [], 199 | "authorship_tag": "ABX9TyNAfPSbYWK5cOSLtdj55ODH", 200 | "include_colab_link": true 201 | }, 202 | "kernelspec": { 203 | "display_name": "Python 3", 204 | "name": "python3" 205 | }, 206 | "language_info": { 207 | "name": "python" 208 | } 209 | }, 210 | "nbformat": 4, 211 | "nbformat_minor": 0 212 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Langchain tutorials 2 | 3 | Overview and tutorial of the LangChain Library 4 | 5 | ### Getting Started 6 | 7 | Videos coming soon https://www.youtube.com/@AnilChandraNaiduMatcha 8 | .Subscribe to the channel to get latest content 9 | 10 | Follow [Anil Chandra Naidu Matcha](https://twitter.com/matchaman11) on twitter for updates 11 | 12 | Join our discord server for support https://discord.gg/FBpafqbbYF 13 | 14 | ### Also check 15 | 16 | [Langchain Course](https://github.com/SamurAIGPT/langchain-course) 17 | -------------------------------------------------------------------------------- /Summarization.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "authorship_tag": "ABX9TyMin+NWCdFOwybOfhHDSD3z", 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "metadata": { 22 | "id": "view-in-github", 23 | "colab_type": "text" 24 | }, 25 | "source": [ 26 | "\"Open" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "source": [ 32 | "!pip install langchain openai tiktoken" 33 | ], 34 | "metadata": { 35 | "id": "SatfTti339p2" 36 | }, 37 | "execution_count": null, 38 | "outputs": [] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "source": [ 43 | "!wget https://raw.githubusercontent.com/hwchase17/chat-your-data/master/state_of_the_union.txt" 44 | ], 45 | "metadata": { 46 | "id": "OOLR7NIa4N4P" 47 | }, 48 | "execution_count": null, 49 | "outputs": [] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 13, 54 | "metadata": { 55 | "id": "z4Ms5Npv37Bn" 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "from langchain import OpenAI, PromptTemplate, LLMChain\n", 60 | "from langchain.text_splitter import CharacterTextSplitter\n", 61 | "from langchain.chains.mapreduce import MapReduceChain\n", 62 | "from langchain.prompts import PromptTemplate\n", 63 | "from langchain.document_loaders import TextLoader\n", 64 | "from langchain.docstore.document import Document\n", 65 | "\n", 66 | "text_splitter = CharacterTextSplitter()\n", 67 | "with open(\"state_of_the_union.txt\") as f:\n", 68 | " state_of_the_union = f.read()\n", 69 | "texts = text_splitter.split_text(state_of_the_union)\n", 70 | "docs = [Document(page_content=t) for t in texts[:3]]" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "source": [ 76 | "from langchain.chains.summarize import load_summarize_chain\n", 77 | "llm = OpenAI(temperature=0, openai_api_key=\"your-openai-key\")\n", 78 | "chain = load_summarize_chain(llm, chain_type=\"map_reduce\")\n", 79 | "chain.run(docs)" 80 | ], 81 | "metadata": { 82 | "colab": { 83 | "base_uri": "https://localhost:8080/", 84 | "height": 71 85 | }, 86 | "id": "CCzv8h_X4iuE", 87 | "outputId": "cd9eb0f3-3144-4ef3-85bb-b6e3b81903c8" 88 | }, 89 | "execution_count": 17, 90 | "outputs": [ 91 | { 92 | "output_type": "execute_result", 93 | "data": { 94 | "text/plain": [ 95 | "' In response to Russian aggression in Ukraine, the United States and its allies are taking action to hold Putin accountable, including economic sanctions, military assistance, and the release of oil from the Strategic Petroleum Reserve. President Biden has also passed the American Rescue Plan and the Bipartisan Infrastructure Law to help struggling Americans and create jobs. These plans will invest in America, modernize infrastructure, and promote environmental justice.'" 96 | ], 97 | "application/vnd.google.colaboratory.intrinsic+json": { 98 | "type": "string" 99 | } 100 | }, 101 | "metadata": {}, 102 | "execution_count": 17 103 | } 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "source": [], 109 | "metadata": { 110 | "id": "kwSm6myq4sOB" 111 | }, 112 | "execution_count": null, 113 | "outputs": [] 114 | } 115 | ] 116 | } --------------------------------------------------------------------------------