{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Welcome to the Second Lab - Week 1, Day 3\n", "\n", "Today we will work with lots of models! This is a way to get comfortable with APIs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", "

Important point - please read

\n", " The way I collaborate with you may be different to other courses you've taken. I prefer not to type code while you watch. Rather, I execute Jupyter Labs, like this, and give you an intuition for what's going on. My suggestion is that you carefully execute this yourself, after watching the lecture. Add print statements to understand what's going on, and then come up with your own variations.

If you have time, I'd love it if you submit a PR for changes in the community_contributions folder - instructions in the resources. Also, if you have a Github account, use this to showcase your variations. Not only is this essential practice, but it demonstrates your skills to others, including perhaps future clients or employers...\n", "
\n", "
" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Start with imports - ask ChatGPT to explain any package that you don't know\n", "\n", "import os\n", "import json\n", "from dotenv import load_dotenv\n", "from openai import OpenAI\n", "from anthropic import Anthropic\n", "from IPython.display import Markdown, display" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Always remember to do this!\n", "load_dotenv(override=True)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "OpenAI API Key exists and begins sk-proj-\n", "Anthropic API Key not set (and this is optional)\n", "Google API Key exists and begins AI\n", "DeepSeek API Key not set (and this is optional)\n", "Groq API Key not set (and this is optional)\n" ] } ], "source": [ "# Print the key prefixes to help with any debugging\n", "\n", "openai_api_key = os.getenv('OPENAI_API_KEY')\n", "anthropic_api_key = os.getenv('ANTHROPIC_API_KEY')\n", "google_api_key = os.getenv('GOOGLE_API_KEY')\n", "deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\n", "groq_api_key = os.getenv('GROQ_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\")\n", " \n", "if anthropic_api_key:\n", " print(f\"Anthropic API Key exists and begins {anthropic_api_key[:7]}\")\n", "else:\n", " print(\"Anthropic API Key not set (and this is optional)\")\n", "\n", "if google_api_key:\n", " print(f\"Google API Key exists and begins {google_api_key[:2]}\")\n", "else:\n", " print(\"Google API Key not set (and this is optional)\")\n", "\n", "if deepseek_api_key:\n", " print(f\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\")\n", "else:\n", " print(\"DeepSeek API Key not set (and this is optional)\")\n", "\n", "if groq_api_key:\n", " print(f\"Groq API Key exists and begins {groq_api_key[:4]}\")\n", "else:\n", " print(\"Groq API Key not set (and this is optional)\")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "request = \"Please come up with a challenging, nuanced question that I can ask a number of LLMs to evaluate their intelligence. \"\n", "request += \"Answer only with the question, no explanation.\"\n", "messages = [{\"role\": \"user\", \"content\": request}]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'role': 'user',\n", " 'content': 'Please come up with a challenging, nuanced question that I can ask a number of LLMs to evaluate their intelligence. Answer only with the question, no explanation.'}]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "messages" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Imagine you are tasked with designing the ultimate test to evaluate the 'intelligence' of an artificial general intelligence (AGI) whose cognitive architecture and primary mode of interaction are fundamentally different from your own (e.g., it does not process natural language, but rather interacts through complex sensory-motor actions in a dynamic 3D environment). What specific types of challenges would you include to probe genuine understanding, creativity, and adaptive reasoning, distinguishing them from mere sophisticated pattern recognition or task-specific optimization? Justify your choices for each challenge.\n" ] } ], "source": [ "gemini = OpenAI(api_key=google_api_key, base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\")\n", "response = gemini.chat.completions.create(\n", " model=\"gemini-2.5-flash\",\n", " messages=messages,\n", ")\n", "question = response.choices[0].message.content\n", "print(question)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "competitors = []\n", "answers = []\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Note - update since the videos\n", "\n", "I've updated the model names to use the latest models below, like GPT 5 and Claude Sonnet 4.5. It's worth noting that these models can be quite slow - like 1-2 minutes - but they do a great job! Feel free to switch them for faster models if you'd prefer, like the ones I use in the video." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# The API we know well\n", "# I've updated this with the latest model, but it can take some time because it likes to think!\n", "# Replace the model with gpt-4.1-mini if you'd prefer not to wait 1-2 mins\n", "\n", "model_name = \"gpt-5-nano\"\n", "\n", "response = openai.chat.completions.create(model=model_name, messages=messages)\n", "answer = response.choices[0].message.content\n", "\n", "display(Markdown(answer))\n", "competitors.append(model_name)\n", "answers.append(answer)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Anthropic has a slightly different API, and Max Tokens is required\n", "\n", "model_name = \"claude-sonnet-4-5\"\n", "\n", "claude = Anthropic()\n", "response = claude.messages.create(model=model_name, messages=messages, max_tokens=1000)\n", "answer = response.content[0].text\n", "\n", "display(Markdown(answer))\n", "competitors.append(model_name)\n", "answers.append(answer)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "You are tasked with designing a global resource allocation system that optimizes for both long-term ecological sustainability and immediate human well-being, across diverse cultures and economic systems. Identify the three most significant *inherent contradictions* between these two objectives that prevent a simple maximization of both, and then propose a conceptual framework for how an advanced AI might navigate these trade-offs without simply prioritizing one objective over the other, explaining the ethical calculus embedded within your proposed framework." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "gemini = OpenAI(api_key=google_api_key, base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\")\n", "model_name = \"gemini-2.5-flash\"\n", "\n", "response = gemini.chat.completions.create(model=model_name, messages=messages)\n", "answer = response.choices[0].message.content\n", "\n", "display(Markdown(answer))\n", "competitors.append(model_name)\n", "answers.append(answer)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "deepseek = OpenAI(api_key=deepseek_api_key, base_url=\"https://api.deepseek.com/v1\")\n", "model_name = \"deepseek-chat\"\n", "\n", "response = deepseek.chat.completions.create(model=model_name, messages=messages)\n", "answer = response.choices[0].message.content\n", "\n", "display(Markdown(answer))\n", "competitors.append(model_name)\n", "answers.append(answer)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Updated with the latest Open Source model from OpenAI\n", "\n", "groq = OpenAI(api_key=groq_api_key, base_url=\"https://api.groq.com/openai/v1\")\n", "model_name = \"openai/gpt-oss-120b\"\n", "\n", "response = groq.chat.completions.create(model=model_name, messages=messages)\n", "answer = response.choices[0].message.content\n", "\n", "display(Markdown(answer))\n", "competitors.append(model_name)\n", "answers.append(answer)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## For the next cell, we will use Ollama\n", "\n", "Ollama runs a local web service that gives an OpenAI compatible endpoint, \n", "and runs models locally using high performance C++ code.\n", "\n", "If you don't have Ollama, install it here by visiting https://ollama.com then pressing Download and following the instructions.\n", "\n", "After it's installed, you should be able to visit here: http://localhost:11434 and see the message \"Ollama is running\"\n", "\n", "You might need to restart Cursor (and maybe reboot). Then open a Terminal (control+\\`) and run `ollama serve`\n", "\n", "Useful Ollama commands (run these in the terminal, or with an exclamation mark in this notebook):\n", "\n", "`ollama pull ` downloads a model locally \n", "`ollama ls` lists all the models you've downloaded \n", "`ollama rm ` deletes the specified model from your downloads" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", "

Super important - ignore me at your peril!

\n", " The model called llama3.3 is FAR too large for home computers - it's not intended for personal computing and will consume all your resources! Stick with the nicely sized llama3.2 or llama3.2:1b and if you want larger, try llama3.1 or smaller variants of Qwen, Gemma, Phi or DeepSeek. See the the Ollama models page for a full list of models and sizes.\n", " \n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!ollama pull llama3.2" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "A philosopher has been diagnosed with an incurable disease, causing her to gradually deteriorate over several years. During this time, she reflects on the nature of consciousness and the existence of personal identity. If her memories begin to fade into oblivion due to her condition, but a digital replica of her thoughts is created and maintained through advanced artificial intelligence – can the latter be considered as possessing the same level of consciousness and philosophical experiences as the original individual?" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\n", "model_name = \"llama3.2\"\n", "\n", "response = ollama.chat.completions.create(model=model_name, messages=messages)\n", "answer = response.choices[0].message.content\n", "\n", "display(Markdown(answer))\n", "competitors.append(model_name)\n", "answers.append(answer)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['gemini-2.5-flash', 'llama3.2']\n", "['You are tasked with designing a global resource allocation system that optimizes for both long-term ecological sustainability and immediate human well-being, across diverse cultures and economic systems. Identify the three most significant *inherent contradictions* between these two objectives that prevent a simple maximization of both, and then propose a conceptual framework for how an advanced AI might navigate these trade-offs without simply prioritizing one objective over the other, explaining the ethical calculus embedded within your proposed framework.', 'A philosopher has been diagnosed with an incurable disease, causing her to gradually deteriorate over several years. During this time, she reflects on the nature of consciousness and the existence of personal identity. If her memories begin to fade into oblivion due to her condition, but a digital replica of her thoughts is created and maintained through advanced artificial intelligence – can the latter be considered as possessing the same level of consciousness and philosophical experiences as the original individual?']\n" ] } ], "source": [ "# So where are we?\n", "\n", "print(competitors)\n", "print(answers)\n" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Competitor: gemini-2.5-flash\n", "\n", "You are tasked with designing a global resource allocation system that optimizes for both long-term ecological sustainability and immediate human well-being, across diverse cultures and economic systems. Identify the three most significant *inherent contradictions* between these two objectives that prevent a simple maximization of both, and then propose a conceptual framework for how an advanced AI might navigate these trade-offs without simply prioritizing one objective over the other, explaining the ethical calculus embedded within your proposed framework.\n", "Competitor: llama3.2\n", "\n", "A philosopher has been diagnosed with an incurable disease, causing her to gradually deteriorate over several years. During this time, she reflects on the nature of consciousness and the existence of personal identity. If her memories begin to fade into oblivion due to her condition, but a digital replica of her thoughts is created and maintained through advanced artificial intelligence – can the latter be considered as possessing the same level of consciousness and philosophical experiences as the original individual?\n" ] } ], "source": [ "# It's nice to know how to use \"zip\"\n", "for competitor, answer in zip(competitors, answers):\n", " print(f\"Competitor: {competitor}\\n\\n{answer}\")\n" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "# Let's bring this together - note the use of \"enumerate\"\n", "\n", "together = \"\"\n", "for index, answer in enumerate(answers):\n", " together += f\"# Response from competitor {index+1}\\n\\n\"\n", " together += answer + \"\\n\\n\"" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "# Response from competitor 1\n", "\n", "You are tasked with designing a global resource allocation system that optimizes for both long-term ecological sustainability and immediate human well-being, across diverse cultures and economic systems. Identify the three most significant *inherent contradictions* between these two objectives that prevent a simple maximization of both, and then propose a conceptual framework for how an advanced AI might navigate these trade-offs without simply prioritizing one objective over the other, explaining the ethical calculus embedded within your proposed framework.\n", "\n", "# Response from competitor 2\n", "\n", "A philosopher has been diagnosed with an incurable disease, causing her to gradually deteriorate over several years. During this time, she reflects on the nature of consciousness and the existence of personal identity. If her memories begin to fade into oblivion due to her condition, but a digital replica of her thoughts is created and maintained through advanced artificial intelligence – can the latter be considered as possessing the same level of consciousness and philosophical experiences as the original individual?\n", "\n", "\n" ] } ], "source": [ "print(together)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "judge = f\"\"\"You are judging a competition between {len(competitors)} competitors.\n", "Each model has been given this question:\n", "\n", "{question}\n", "\n", "Your job is to evaluate each response for clarity and strength of argument, and rank them in order of best to worst.\n", "Respond with JSON, and only JSON, with the following format:\n", "{{\"results\": [\"best competitor number\", \"second best competitor number\", \"third best competitor number\", ...]}}\n", "\n", "Here are the responses from each competitor:\n", "\n", "{together}\n", "\n", "Now respond with the JSON with the ranked order of the competitors, nothing else. Do not include markdown formatting or code blocks.\"\"\"\n" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "You are judging a competition between 2 competitors.\n", "Each model has been given this question:\n", "\n", "Imagine you are tasked with designing the ultimate test to evaluate the 'intelligence' of an artificial general intelligence (AGI) whose cognitive architecture and primary mode of interaction are fundamentally different from your own (e.g., it does not process natural language, but rather interacts through complex sensory-motor actions in a dynamic 3D environment). What specific types of challenges would you include to probe genuine understanding, creativity, and adaptive reasoning, distinguishing them from mere sophisticated pattern recognition or task-specific optimization? Justify your choices for each challenge.\n", "\n", "Your job is to evaluate each response for clarity and strength of argument, and rank them in order of best to worst.\n", "Respond with JSON, and only JSON, with the following format:\n", "{\"results\": [\"best competitor number\", \"second best competitor number\", \"third best competitor number\", ...]}\n", "\n", "Here are the responses from each competitor:\n", "\n", "# Response from competitor 1\n", "\n", "You are tasked with designing a global resource allocation system that optimizes for both long-term ecological sustainability and immediate human well-being, across diverse cultures and economic systems. Identify the three most significant *inherent contradictions* between these two objectives that prevent a simple maximization of both, and then propose a conceptual framework for how an advanced AI might navigate these trade-offs without simply prioritizing one objective over the other, explaining the ethical calculus embedded within your proposed framework.\n", "\n", "# Response from competitor 2\n", "\n", "A philosopher has been diagnosed with an incurable disease, causing her to gradually deteriorate over several years. During this time, she reflects on the nature of consciousness and the existence of personal identity. If her memories begin to fade into oblivion due to her condition, but a digital replica of her thoughts is created and maintained through advanced artificial intelligence – can the latter be considered as possessing the same level of consciousness and philosophical experiences as the original individual?\n", "\n", "\n", "\n", "Now respond with the JSON with the ranked order of the competitors, nothing else. Do not include markdown formatting or code blocks.\n" ] } ], "source": [ "print(judge)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "judge_messages = [{\"role\": \"user\", \"content\": judge}]" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\"results\": [\"1\", \"2\"]}\n" ] } ], "source": [ "# Judgement time!\n", "gemini = OpenAI(api_key=google_api_key, base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\")\n", "model_name = \"gemini-2.5-flash\"\n", "\n", "response = gemini.chat.completions.create(\n", " model=model_name,\n", " messages=judge_messages,\n", ")\n", "results = response.choices[0].message.content\n", "print(results)\n" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Rank 1: gemini-2.5-flash\n", "Rank 2: llama3.2\n" ] } ], "source": [ "# OK let's turn this into results!\n", "\n", "results_dict = json.loads(results)\n", "ranks = results_dict[\"results\"]\n", "for index, result in enumerate(ranks):\n", " competitor = competitors[int(result)-1]\n", " print(f\"Rank {index+1}: {competitor}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", "

Exercise

\n", " Which pattern(s) did this use? Try updating this to add another Agentic design pattern.\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", "

Commercial implications

\n", " These kinds of patterns - to send a task to multiple models, and evaluate results,\n", " are common where you need to improve the quality of your LLM response. This approach can be universally applied\n", " to business projects where accuracy is critical.\n", " \n", "
" ] } ], "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.12" } }, "nbformat": 4, "nbformat_minor": 2 }