{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Welcome to the start of your adventure in Agentic AI" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", "

Are you ready for action??

\n", " Have you completed all the setup steps in the setup folder?
\n", " Have you checked out the guides in the guides folder?
\n", " Well in that case, you're ready!!\n", "
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", "

Treat these labs as a resource

\n", " I push updates to the code regularly. When people ask questions or have problems, I incorporate it in the code, adding more examples or improved commentary. As a result, you'll notice that the code below isn't identical to the videos. Everything from the videos is here; but in addition, I've added more steps and better explanations. Consider this like an interactive book that accompanies the lectures.\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### And please do remember to contact me if I can help\n", "\n", "And I love to connect: https://www.linkedin.com/in/eddonner/\n", "\n", "\n", "### New to Notebooks like this one? Head over to the guides folder!\n", "\n", "Just to check you've already added the Python and Jupyter extensions to Cursor, if not already installed:\n", "- Open extensions (View >> extensions)\n", "- Search for python, and when the results show, click on the ms-python one, and Install it if not already installed\n", "- Search for jupyter, and when the results show, click on the Microsoft one, and Install it if not already installed \n", "Then View >> Explorer to bring back the File Explorer.\n", "\n", "And then:\n", "1. Click where it says \"Select Kernel\" near the top right, and select the option called `.venv (Python 3.12.9)` or similar, which should be the first choice or the most prominent choice. You may need to choose \"Python Environments\" first.\n", "2. Click in each \"cell\" below, starting with the cell immediately below this text, and press Shift+Enter to run\n", "3. Enjoy!\n", "\n", "After you click \"Select Kernel\", if there is no option like `.venv (Python 3.12.9)` then please do the following: \n", "1. On Mac: From the Cursor menu, choose Settings >> VS Code Settings (NOTE: be sure to select `VSCode Settings` not `Cursor Settings`); \n", "On Windows PC: From the File menu, choose Preferences >> VS Code Settings(NOTE: be sure to select `VSCode Settings` not `Cursor Settings`) \n", "2. In the Settings search bar, type \"venv\" \n", "3. In the field \"Path to folder with a list of Virtual Environments\" put the path to the project root, like C:\\Users\\username\\projects\\agents (on a Windows PC) or /Users/username/projects/agents (on Mac or Linux). \n", "And then try again.\n", "\n", "Having problems with missing Python versions in that list? Have you ever used Anaconda before? It might be interferring. Quit Cursor, bring up a new command line, and make sure that your Anaconda environment is deactivated: \n", "`conda deactivate` \n", "And if you still have any problems with conda and python versions, it's possible that you will need to run this too: \n", "`conda config --set auto_activate_base false` \n", "and then from within the Agents directory, you should be able to run `uv python list` and see the Python 3.12 version." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# My practice code" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from dotenv import load_dotenv" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "load_dotenv(override=True)\n", "# override = True means read the most .env values" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "OpenAI API Key exists and begins with sk-proj-\n" ] } ], "source": [ "import os\n", "openai_api_key = os.getenv('OPENAI_API_KEY')\n", "\n", "if openai_api_key:\n", " print(f\"OpenAI API Key exists and begins with {openai_api_key[:8]}\")\n", "else:\n", " print(\"cannot load\")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from openai import OpenAI" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "open_ai = OpenAI()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "messages = [{\"role\": \"user\", \"content\": \"What is 2 + 2?\"}]\n", "# Message format for LLM. Learn the LLM course for more details" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 + 2 equals 4.\n" ] } ], "source": [ "# chat completions with OpenAI\n", "# sample code for connecting to OpenAI\n", "# learn LLM course for more details\n", "\n", "res = open_ai.chat.completions.create(\n", " model=\"gpt-4o-mini\",\n", " messages=messages\n", ")\n", "\n", "print(res.choices[0].message.content)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# more challenge question\n", "\n", "question = \"Please propose a hard, challenging question to assess someone's IQ. Respond only with the question.\"\n", "messages = [{\"role\": \"user\", \"content\": question}]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "If you have a 3x3 grid filled with eight tiles numbered 1 to 8 and one empty space, your goal is to arrange the tiles in numerical order by sliding them into the empty space. What is the minimum number of moves required to reach the goal state from the configuration where the tiles are arranged in the following order: \n", "\n", "```\n", "1 2 3\n", "5 6 4\n", "8 7 \n", "```\n", "\n", "Assume that you can only slide tiles that are adjacent to the empty space.\n" ] } ], "source": [ "res = open_ai.chat.completions.create(\n", " model=\"gpt-4o-mini\",\n", " messages=messages\n", ")\n", "\n", "question = res.choices[0].message.content\n", "print(question)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "If you have a 3x3 grid filled with eight tiles numbered 1 to 8 and one empty space, your goal is to arrange the tiles in numerical order by sliding them into the empty space. What is the minimum number of moves required to reach the goal state from the configuration where the tiles are arranged in the following order: \n", "\n", "```\n", "1 2 3\n", "5 6 4\n", "8 7 \n", "```\n", "\n", "Assume that you can only slide tiles that are adjacent to the empty space.\n" ] } ], "source": [ "messages = [{\"role\": \"user\", \"content\": question}]\n", "\n", "res = open_ai.chat.completions.create(\n", " model=\"gpt-4o-mini\",\n", " messages=messages\n", ")\n", "\n", "answer = res.choices[0].message.content" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "To determine the minimum number of moves required to sort the 3x3 grid from the given configuration:\n", "\n", "```\n", "1 2 3\n", "5 6 4\n", "8 7\n", "```\n", "\n", "to the goal configuration:\n", "\n", "```\n", "1 2 3\n", "4 5 6\n", "7 8\n", "```\n", "\n", "we can analyze the steps needed.\n", "\n", "1. The empty space is currently located at the bottom right corner (often represented as an empty spot). We can represent the empty space as `(i, j)` coordinates in the grid, where `i` is the row index and `j` is the column index.\n", "\n", "2. The current configuration can be viewed as:\n", "\n", "```\n", "(0,0) (0,1) (0,2)\n", "(1,0) (1,1) (1,2)\n", "(2,0) (2,1) (2,2)\n", "```\n", "\n", "Given this grid:\n", "\n", "```\n", "1 2 3\n", "5 6 4\n", "8 7 _\n", "```\n", "\n", "Starting with the empty space on `(2, 2)`, we need to slide tiles into this space to achieve the goal configuration. \n", "\n", "From the given arrangement, we can take the following steps to reach the target state:\n", "\n", "1. **Move 1**: Slide `7` into the empty space.\n", "```\n", "1 2 3\n", "5 6 4\n", "8 _ 7\n", "```\n", "\n", "2. **Move 2**: Slide `4` into the empty space.\n", "```\n", "1 2 3\n", "5 6 _\n", "8 7 4\n", "```\n", "\n", "3. **Move 3**: Slide `6` into the empty space.\n", "```\n", "1 2 3\n", "5 _ 6\n", "8 7 4\n", "```\n", "\n", "4. **Move 4**: Slide `5` into the empty space.\n", "```\n", "1 2 3\n", "_ 5 6\n", "8 7 4\n", "```\n", "\n", "5. **Move 5**: Slide `4` into the empty space.\n", "```\n", "1 2 3\n", "4 5 6\n", "8 7 _\n", "```\n", "\n", "6. **Move 6**: Slide `7` into the empty space.\n", "```\n", "1 2 3\n", "4 5 6\n", "8 _ 7\n", "```\n", "\n", "7. **Move 7**: Slide `8` into the empty space.\n", "```\n", "1 2 3\n", "4 5 6\n", "_ 7 8\n", "```\n", "\n", "After sorting them out, we reach the following configuration:\n", "```\n", "1 2 3\n", "4 5 6\n", "7 8 _\n", "```\n", "\n", "Thus, it takes a total of **7 moves** to arrange the tiles in numerical order from the initial state. However, depending on the context of the moves or how specifically the moves are defined to be optimal (especially if there could potentially be shortcuts), the above provisional strategy generally holds true for the puzzle structure given it allows for systematic tile movement.\n", "\n", "So the minimum number of moves required is **7 moves**.\n" ] } ], "source": [ "print(answer)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Sample code" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# First let's do an import\n", "from dotenv import load_dotenv\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Next it's time to load the API keys into environment variables\n", "\n", "load_dotenv(override=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Check the keys\n", "\n", "import os\n", "openai_api_key = os.getenv('OPENAI_API_KEY')\n", "\n", "if openai_api_key:\n", " print(f\"OpenAI API Key exists and begins {openai_api_key[:8]}\")\n", "else:\n", " print(\"OpenAI API Key not set - please head to the troubleshooting guide in the setup folder\")\n", " \n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# And now - the all important import statement\n", "# If you get an import error - head over to troubleshooting guide\n", "\n", "from openai import OpenAI" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# And now we'll create an instance of the OpenAI class\n", "# If you're not sure what it means to create an instance of a class - head over to the guides folder!\n", "# If you get a NameError - head over to the guides folder to learn about NameErrors\n", "\n", "openai = OpenAI()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# Create a list of messages in the familiar OpenAI format\n", "\n", "messages = [{\"role\": \"user\", \"content\": \"What is 2+2?\"}]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# And now call it! Any problems, head to the troubleshooting guide\n", "# This uses GPT 4.1 nano, the incredibly cheap model\n", "\n", "response = openai.chat.completions.create(\n", " model=\"gpt-4.1-nano\",\n", " messages=messages\n", ")\n", "\n", "print(response.choices[0].message.content)\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# And now - let's ask for a question:\n", "\n", "question = \"Please propose a hard, challenging question to assess someone's IQ. Respond only with the question.\"\n", "messages = [{\"role\": \"user\", \"content\": question}]\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ask it - this uses GPT 4.1 mini, still cheap but more powerful than nano\n", "\n", "response = openai.chat.completions.create(\n", " model=\"gpt-4.1-mini\",\n", " messages=messages\n", ")\n", "\n", "question = response.choices[0].message.content\n", "\n", "print(question)\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "# form a new messages list\n", "messages = [{\"role\": \"user\", \"content\": question}]\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Ask it again\n", "\n", "response = openai.chat.completions.create(\n", " model=\"gpt-4.1-mini\",\n", " messages=messages\n", ")\n", "\n", "answer = response.choices[0].message.content\n", "print(answer)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import Markdown, display\n", "\n", "display(Markdown(answer))\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Congratulations!\n", "\n", "That was a small, simple step in the direction of Agentic AI, with your new environment!\n", "\n", "Next time things get more interesting..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", "

Exercise

\n", " Now try this commercial application:
\n", " First ask the LLM to pick a business area that might be worth exploring for an Agentic AI opportunity.
\n", " Then ask the LLM to present a pain-point in that industry - something challenging that might be ripe for an Agentic solution.
\n", " Finally have 3 third LLM call propose the Agentic AI solution.\n", "
\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# First create the messages:\n", "\n", "messages = [{\"role\": \"user\", \"content\": \"Something here\"}]\n", "\n", "# Then make the first call:\n", "\n", "response =\n", "\n", "# Then read the business idea:\n", "\n", "business_idea = response.\n", "\n", "# And repeat!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": ".venv", "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.12.10" } }, "nbformat": 4, "nbformat_minor": 2 }