{ "cells": [ { "cell_type": "markdown", "id": "75e2ef28-594f-4c18-9d22-c6b8cd40ead2", "metadata": {}, "source": [ "# Day 3 - Conversational AI - aka Chatbot!" ] }, { "cell_type": "code", "execution_count": 40, "id": "70e39cd8-ec79-4e3e-9c26-5659d42d0861", "metadata": {}, "outputs": [], "source": [ "# imports\n", "\n", "import os\n", "import requests\n", "from bs4 import BeautifulSoup\n", "from typing import List\n", "from dotenv import load_dotenv\n", "from openai import OpenAI\n", "import google.generativeai\n", "# import anthropic\n", "import gradio as gr" ] }, { "cell_type": "code", "execution_count": 41, "id": "231605aa-fccb-447e-89cf-8b187444536a", "metadata": {}, "outputs": [], "source": [ "# Load environment variables in a file called .env\n", "\n", "load_dotenv()\n", "os.environ['GOOGLE_API_KEY'] = os.getenv('GOOGLE_API_KEY', 'your-key-if-not-using-env')" ] }, { "cell_type": "code", "execution_count": 3, "id": "6541d58e-2297-4de1-b1f7-77da1b98b8bb", "metadata": {}, "outputs": [], "source": [ "google.generativeai.configure()" ] }, { "cell_type": "code", "execution_count": 4, "id": "e16839b5-c03b-4d9d-add6-87a0f6f37575", "metadata": {}, "outputs": [], "source": [ "system_message = \"You are a helpful assistant\"" ] }, { "cell_type": "code", "execution_count": 5, "id": "ba2123e7-77ed-43b4-8c37-03658fb42b78", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Why was the Data Scientist sad? \n", "\n", "Because they didn't get any arrays!\n", "\n" ] } ], "source": [ "system_message = \"You are an assistant that is great at telling jokes\"\n", "user_prompt = \"Tell a light-hearted joke for an audience of Data Scientists\"\n", "\n", "prompts = [\n", " {\"role\": \"system\", \"content\": system_message},\n", " {\"role\": \"user\", \"content\": user_prompt}\n", " ]\n", "\n", "# The API for Gemini has a slightly different structure.\n", "# I've heard that on some PCs, this Gemini code causes the Kernel to crash.\n", "# If that happens to you, please skip this cell and use the next cell instead - an alternative approach.\n", "\n", "gemini = google.generativeai.GenerativeModel(\n", " model_name='gemini-1.5-flash',\n", " system_instruction=system_message\n", ")\n", "response = gemini.generate_content(user_prompt)\n", "print(response.text)" ] }, { "cell_type": "code", "execution_count": 7, "id": "7b933ff3", "metadata": {}, "outputs": [], "source": [ "import google.generativeai as genai\n", "\n", "model = genai.GenerativeModel('gemini-1.5-flash')" ] }, { "cell_type": "code", "execution_count": 8, "id": "91578b16", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello Shardul! It's nice to meet you. How can I help you today?\n", "\n" ] } ], "source": [ "chat = model.start_chat(history=[])\n", "response = chat.send_message('Hello! My name is Shardul.')\n", "print(response.text)" ] }, { "cell_type": "code", "execution_count": 9, "id": "7c4bc38f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Did you know that the iconic lightsaber fight choreography in Star Wars was heavily influenced by Japanese samurai sword fighting styles? Specifically, the movements and stances of the Jedi and Sith were inspired by kendo and other forms of Japanese martial arts. This gives the lightsaber battles a unique elegance and deadly precision that sets them apart from typical sword fights in other films.\n", "\n" ] } ], "source": [ "response = chat.send_message('Can you tell something interesting about star wars?')\n", "print(response.text)" ] }, { "cell_type": "code", "execution_count": 10, "id": "337bee91", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Yes, your name is Shardul.\n", "\n" ] } ], "source": [ "response = chat.send_message('Do you remember what my name is?')\n", "print(response.text)" ] }, { "cell_type": "code", "execution_count": 34, "id": "bcaf4d95", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[parts {\n", " text: \"Hello! My name is Shardul.\"\n", " }\n", " role: \"user\",\n", " parts {\n", " text: \"Hello Shardul! It\\'s nice to meet you. How can I help you today?\\n\"\n", " }\n", " role: \"model\",\n", " parts {\n", " text: \"Can you tell something interesting about star wars?\"\n", " }\n", " role: \"user\",\n", " parts {\n", " text: \"One interesting fact about Star Wars is that the iconic lightsaber sound effect was created by recording the hum of a broken-down projector. The sound designer, Ben Burtt, combined that with the sound of a television\\'s static to create the distinctive whoosh and hum we all know and love. It\\'s a perfect example of how seemingly mundane sounds can be creatively repurposed to create iconic elements of a beloved franchise.\\n\"\n", " }\n", " role: \"model\",\n", " parts {\n", " text: \"Do you remember what my name is?\"\n", " }\n", " role: \"user\",\n", " parts {\n", " text: \"Yes, your name is Shardul.\\n\"\n", " }\n", " role: \"model\"]" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "chat.history" ] }, { "cell_type": "markdown", "id": "98e97227-f162-4d1a-a0b2-345ff248cbe7", "metadata": {}, "source": [ "# Please read this! A change from the video:\n", "\n", "In the video, I explain how we now need to write a function called:\n", "\n", "`chat(message, history)`\n", "\n", "Which expects to receive `history` in a particular format, which we need to map to the OpenAI format before we call OpenAI:\n", "\n", "```\n", "[\n", " {\"role\": \"system\", \"content\": \"system message here\"},\n", " {\"role\": \"user\", \"content\": \"first user prompt here\"},\n", " {\"role\": \"assistant\", \"content\": \"the assistant's response\"},\n", " {\"role\": \"user\", \"content\": \"the new user prompt\"},\n", "]\n", "```\n", "\n", "But Gradio has been upgraded! Now it will pass in `history` in the exact OpenAI format, perfect for us to send straight to OpenAI.\n", "\n", "So our work just got easier!\n", "\n", "We will write a function `chat(message, history)` where: \n", "**message** is the prompt to use \n", "**history** is the past conversation, in OpenAI format \n", "\n", "We will combine the system message, history and latest message, then call OpenAI." ] }, { "cell_type": "code", "execution_count": 6, "id": "1eacc8a4-4b48-4358-9e06-ce0020041bc1", "metadata": {}, "outputs": [], "source": [ "def chat(message, history):\n", " relevant_system_message = system_message\n", " if 'belt' in message:\n", " relevant_system_message += \" The store does not sell belts; if you are asked for belts, be sure to point out other items on sale.\"\n", " \n", " messages = [{\"role\": \"system\", \"content\": relevant_system_message}] + history + [{\"role\": \"user\", \"content\": message}]\n", "\n", " stream = gemini.generate_content(message, safety_settings=[\n", " {\"category\": \"HARM_CATEGORY_DANGEROUS_CONTENT\", \"threshold\": \"BLOCK_NONE\"},\n", " {\"category\": \"HARM_CATEGORY_SEXUALLY_EXPLICIT\", \"threshold\": \"BLOCK_NONE\"},\n", " {\"category\": \"HARM_CATEGORY_HATE_SPEECH\", \"threshold\": \"BLOCK_NONE\"},\n", " {\"category\": \"HARM_CATEGORY_HARASSMENT\", \"threshold\": \"BLOCK_NONE\"}], stream=True)\n", "\n", " response = \"\"\n", " for chunk in stream:\n", " print(chunk) # Print the chunk to understand its structure\n", " # Adjust the following line based on the actual structure of the chunk\n", " response += chunk.get('content', '') or ''\n", " yield response" ] }, { "cell_type": "code", "execution_count": 11, "id": "f6e745e1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Gen\n", " AI, short for **Generative AI**, refers to a type of artificial intelligence\n", " that can create new content, rather than just analyzing or classifying existing data. \n", "This content can take many forms, including:\n", "\n", "* **Text:** Writing stories, articles, summaries, poems, code, scripts, etc. Examples\n", " include ChatGPT, Bard, and Jasper.\n", "* **Images:** Generating realistic or stylized images from text descriptions (prompts). Examples include DALL-E \n", "2, Midjourney, and Stable Diffusion.\n", "* **Audio:** Creating music, sound effects, and voiceovers. Examples include Amper Music and Jukebox.\n", "* **Video:** Generating short video clips. This is a\n", " rapidly developing area.\n", "* **3D models:** Creating three-dimensional objects and scenes.\n", "\n", "Gen AI achieves this by learning patterns and structures from massive datasets and then using this knowledge to generate new, similar but unique outputs. The\n", " underlying techniques often involve deep learning models, particularly those based on neural networks like transformers, autoencoders, and generative adversarial networks (GANs).\n", "\n", "In essence, Gen AI moves beyond simply processing information to actively *producing* it, opening up exciting possibilities in various fields, but also raising ethical and societal concerns about misinformation\n", ", copyright, and job displacement.\n", "\n" ] } ], "source": [ "chat_model = genai.GenerativeModel('gemini-1.5-flash')\n", "chat = chat_model.start_chat()\n", "\n", "msg = \"what is gen ai\"\n", "stream = chat.send_message(msg, stream=True)\n", "# print(\"Response:\", stream.text)\n", "for chunk in stream:\n", " print(chunk.text)\n" ] }, { "cell_type": "code", "execution_count": 44, "id": "dce941ee", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/opt/homebrew/Caskroom/miniconda/base/envs/llms/lib/python3.11/site-packages/gradio/components/chatbot.py:248: UserWarning: The 'tuples' format for chatbot messages is deprecated and will be removed in a future version of Gradio. Please set type='messages' instead, which uses openai-style 'role' and 'content' keys.\n", " warnings.warn(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "* Running on local URL: http://127.0.0.1:7870\n", "\n", "To create a public link, set `share=True` in `launch()`.\n" ] }, { "data": { "text/html": [ "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Keyboard interruption in main thread... closing server.\n" ] }, { "data": { "text/plain": [] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import time\n", "\n", "chat = model.start_chat(history=[])\n", "\n", "# Transform Gradio history to Gemini format\n", "def transform_history(history):\n", " new_history = []\n", " for chat in history:\n", " new_history.append({\"parts\": [{\"text\": chat[0]}], \"role\": \"user\"})\n", " new_history.append({\"parts\": [{\"text\": chat[1]}], \"role\": \"model\"})\n", " return new_history\n", "\n", "def response(message, history):\n", " global chat\n", " # The history will be the same as in Gradio, the 'Undo' and 'Clear' buttons will work correctly.\n", " chat.history = transform_history(history)\n", " response = chat.send_message(message)\n", " response.resolve()\n", "\n", " # Each character of the answer is displayed\n", " for i in range(len(response.text)):\n", " time.sleep(0.01)\n", " yield response.text[: i+1]\n", "\n", "gr.ChatInterface(response,\n", " textbox=gr.Textbox(placeholder=\"Question to Gemini\")).launch(debug=True)" ] }, { "cell_type": "markdown", "id": "82a57ee0-b945-48a7-a024-01b56a5d4b3e", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", "

Business Applications

\n", " Conversational Assistants are of course a hugely common use case for Gen AI, and the latest frontier models are remarkably good at nuanced conversation. And Gradio makes it easy to have a user interface. Another crucial skill we covered is how to use prompting to provide context, information and examples.\n", "

\n", "Consider how you could apply an AI Assistant to your business, and make yourself a prototype. Use the system prompt to give context on your business, and set the tone for the LLM.
\n", "
" ] }, { "cell_type": "code", "execution_count": null, "id": "6dfb9e21-df67-4c2b-b952-5e7e7961b03d", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "llms", "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.11.11" } }, "nbformat": 4, "nbformat_minor": 5 }