Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
579 KiB
JSON
1 line
579 KiB
JSON
{"repo": "brunoalan/agents", "files": {"1_foundations/community_contributions/kisali/2_lab2_aws_bedrock_multi_llm.ipynb": {"03febf9670d94f5b3aa5e1c9c1ac6d6dd5f2b231": {"t": 1785745479.0504382, "n": 13807, "h": "c241d99af9f1c6f5", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Multi-LLM Integrations\\n\",\n \"\\n\",\n \"This notebook involves integrating multiple LLMs, a way to get comfortable working with LLM APIs.\\n\",\n \"I'll be using Amazon Bedrock, which has a number of models that can be accessed via AWS SDK Boto3 library. I'll also use Deepseek directly via the API.\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Importing required libraries\\n\",\n \"# Boto3 library is AWS SDK for Python providing the necessary set of libraries (uv pip install boto3)\\n\",\n \"\\n\",\n \"import os\\n\",\n \"import json\\n\",\n \"import boto3\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from IPython.display import Markdown, display\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Always remember to do this!\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Print the key prefixes to help with any debugging\\n\",\n \"\\n\",\n \"amazon_bedrock_bedrock_api_key = os.getenv('AMAZON_BEDROCK_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"\\n\",\n \"if amazon_bedrock_bedrock_api_key:\\n\",\n \" print(f\\\"Amazon Bedrock API Key exists and begins {amazon_bedrock_bedrock_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Amazon Bedrock API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if deepseek_api_key:\\n\",\n \" print(f\\\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"DeepSeek API Key not set (and this is optional)\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon Bedrock Client\\n\",\n \"\\n\",\n \"bedrock_client = boto3.client(\\n\",\n \" service_name=\\\"bedrock-runtime\\\",\\n\",\n \" region_name=\\\"us-east-1\\\"\\n\",\n \")\\n\",\n \"\\n\",\n \"# Deepseek Client\\n\",\n \"\\n\",\n \"deepseek_client = OpenAI(\\n\",\n \" api_key=deepseek_api_key, \\n\",\n \" base_url=\\\"https://api.deepseek.com\\\"\\n\",\n \")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Coming up with message for LLM Evaluation\\n\",\n \"text = \\\"Please come up with a challenging, nuanced question that I can ask a number of LLMs to evaluate their intelligence. \\\"\\n\",\n \"text += \\\"Answer only with the question, no explanation.\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": text}]}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Anthropic Claude 3.5 Sonnet for model evaluator question\\n\",\n \"\\n\",\n \"model_id = \\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"model_evaluator_question = response['output']['message']['content'][0]['text']\\n\",\n \"print(model_evaluator_question)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"competitors = []\\n\",\n \"answers = []\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": model_evaluator_question}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Deepseek chat model answer\\n\",\n \"\\n\",\n \"model_id = \\\"deepseek-chat\\\"\\n\",\n \"response = deepseek_client.chat.completions.create(\\n\",\n \" model=model_id,\\n\",\n \" messages=messages\\n\",\n \")\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": model_evaluator_question}]}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon nova lite\\n\",\n \"\\n\",\n \"model_id = \\\"amazon.nova-lite-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon Nova Pro\\n\",\n \"\\n\",\n \"model_id = \\\"amazon.nova-pro-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": model_evaluator_question}]}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Cohere Command Light\\n\",\n \"\\n\",\n \"model_id = \\\"cohere.command-light-text-v14\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## For the next cell, we will use Ollama\\n\",\n \"\\n\",\n \"Ollama runs a local web service that gives an OpenAI compatible endpoint, \\n\",\n \"and runs models locally using high performance C++ code.\\n\",\n \"\\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 \"\\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 \"\\n\",\n \"You might need to restart Cursor (and maybe reboot). Then open a Terminal (control+\\\\`) and run `ollama serve`\\n\",\n \"\\n\",\n \"Useful Ollama commands (run these in the terminal, or with an exclamation mark in this notebook):\\n\",\n \"\\n\",\n \"`ollama pull <model_id>` downloads a model locally \\n\",\n \"`ollama ls` lists all the models you've downloaded \\n\",\n \"`ollama rm <model_id>` deletes the specified model from your downloads \\n\",\n \"`ollama run <model_id>` pulls the model if it doesn't exist locally, and run it.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../../../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Important</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">The model called <b>llama3.3</b> 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 <b>llama3.2</b> or <b>llama3.2:1b</b> and if you want larger, try llama3.1 or smaller variants of Qwen, Gemma, Phi or DeepSeek. See the <A href=\\\"https://ollama.com/models\\\">the Ollama models page</a> for a full list of models and sizes.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"!ollama run llama3.2:1b\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": model_evaluator_question}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\\n\",\n \"model_id = \\\"llama3.2:1b\\\"\\n\",\n \"\\n\",\n \"response = ollama.chat.completions.create(\\n\",\n \" model=model_id, \\n\",\n \" messages=messages\\n\",\n \")\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Listing all models and their answers\\n\",\n \"print(competitors)\\n\",\n \"print(answers)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Mapping each model with it's solution for the model evaluator question\\n\",\n \"for competitor, answer in zip(competitors, answers):\\n\",\n \" print(f\\\"Competitor: {competitor}\\\\n\\\\n{answer}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Masking out the model name for evaluation purposes - note the use of \\\"enumerate\\\"\\n\",\n \"\\n\",\n \"together = \\\"\\\"\\n\",\n \"for index, answer in enumerate(answers):\\n\",\n \" together += f\\\"# Response from competitor {index+1}\\\\n\\\\n\\\"\\n\",\n \" together += answer + \\\"\\\\n\\\\n\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(together)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge = f\\\"\\\"\\\"You are judging a competition between {len(competitors)} competitors.\\n\",\n \"Each model has been given this question:\\n\",\n \"\\n\",\n \"{model_evaluator_question}\\n\",\n \"\\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\",\n \"Respond with JSON, and only JSON, with the following format:\\n\",\n \"{{\\\"results\\\": [\\\"best competitor number\\\", \\\"second best competitor number\\\", \\\"third best competitor number\\\", ...]}}\\n\",\n \"\\n\",\n \"Here are the responses from each competitor:\\n\",\n \"\\n\",\n \"{together}\\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\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(judge)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge_messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": judge}]}]\\n\",\n \"judge_messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Anthropic Claude 3.5 Sonnet for model evaluator question\\n\",\n \"\\n\",\n \"model_id = \\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=judge_messages,\\n\",\n \")\\n\",\n \"model_evaluator_response = response['output']['message']['content'][0]['text']\\n\",\n \"print(model_evaluator_response)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# OK let's turn this into results!\\n\",\n \"\\n\",\n \"results_dict = json.loads(model_evaluator_response)\\n\",\n \"ranks = results_dict[\\\"results\\\"]\\n\",\n \"for index, result in enumerate(ranks):\\n\",\n \" competitor = competitors[int(result)-1]\\n\",\n \" print(f\\\"Rank {index+1}: {competitor}\\\")\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../../../assets/business.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#00bfff;\\\">Commercial implications</h2>\\n\",\n \" <span style=\\\"color:#00bfff;\\\">These kinds of patterns - to send a task to multiple models, and evaluate results,\\n\",\n \" are common where you need to improve the quality of your LLM response. This approach can be universally applied\\n\",\n \" to business projects where accuracy is critical.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.1\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "6067ab368aac0802419c87497af82d96f780f957": {"t": 1785753630.6197617, "n": 13807, "h": "c241d99af9f1c6f5", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Multi-LLM Integrations\\n\",\n \"\\n\",\n \"This notebook involves integrating multiple LLMs, a way to get comfortable working with LLM APIs.\\n\",\n \"I'll be using Amazon Bedrock, which has a number of models that can be accessed via AWS SDK Boto3 library. I'll also use Deepseek directly via the API.\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Importing required libraries\\n\",\n \"# Boto3 library is AWS SDK for Python providing the necessary set of libraries (uv pip install boto3)\\n\",\n \"\\n\",\n \"import os\\n\",\n \"import json\\n\",\n \"import boto3\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from IPython.display import Markdown, display\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Always remember to do this!\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Print the key prefixes to help with any debugging\\n\",\n \"\\n\",\n \"amazon_bedrock_bedrock_api_key = os.getenv('AMAZON_BEDROCK_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"\\n\",\n \"if amazon_bedrock_bedrock_api_key:\\n\",\n \" print(f\\\"Amazon Bedrock API Key exists and begins {amazon_bedrock_bedrock_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Amazon Bedrock API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if deepseek_api_key:\\n\",\n \" print(f\\\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"DeepSeek API Key not set (and this is optional)\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon Bedrock Client\\n\",\n \"\\n\",\n \"bedrock_client = boto3.client(\\n\",\n \" service_name=\\\"bedrock-runtime\\\",\\n\",\n \" region_name=\\\"us-east-1\\\"\\n\",\n \")\\n\",\n \"\\n\",\n \"# Deepseek Client\\n\",\n \"\\n\",\n \"deepseek_client = OpenAI(\\n\",\n \" api_key=deepseek_api_key, \\n\",\n \" base_url=\\\"https://api.deepseek.com\\\"\\n\",\n \")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Coming up with message for LLM Evaluation\\n\",\n \"text = \\\"Please come up with a challenging, nuanced question that I can ask a number of LLMs to evaluate their intelligence. \\\"\\n\",\n \"text += \\\"Answer only with the question, no explanation.\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": text}]}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Anthropic Claude 3.5 Sonnet for model evaluator question\\n\",\n \"\\n\",\n \"model_id = \\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"model_evaluator_question = response['output']['message']['content'][0]['text']\\n\",\n \"print(model_evaluator_question)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"competitors = []\\n\",\n \"answers = []\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": model_evaluator_question}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Deepseek chat model answer\\n\",\n \"\\n\",\n \"model_id = \\\"deepseek-chat\\\"\\n\",\n \"response = deepseek_client.chat.completions.create(\\n\",\n \" model=model_id,\\n\",\n \" messages=messages\\n\",\n \")\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": model_evaluator_question}]}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon nova lite\\n\",\n \"\\n\",\n \"model_id = \\\"amazon.nova-lite-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon Nova Pro\\n\",\n \"\\n\",\n \"model_id = \\\"amazon.nova-pro-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": model_evaluator_question}]}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Cohere Command Light\\n\",\n \"\\n\",\n \"model_id = \\\"cohere.command-light-text-v14\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## For the next cell, we will use Ollama\\n\",\n \"\\n\",\n \"Ollama runs a local web service that gives an OpenAI compatible endpoint, \\n\",\n \"and runs models locally using high performance C++ code.\\n\",\n \"\\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 \"\\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 \"\\n\",\n \"You might need to restart Cursor (and maybe reboot). Then open a Terminal (control+\\\\`) and run `ollama serve`\\n\",\n \"\\n\",\n \"Useful Ollama commands (run these in the terminal, or with an exclamation mark in this notebook):\\n\",\n \"\\n\",\n \"`ollama pull <model_id>` downloads a model locally \\n\",\n \"`ollama ls` lists all the models you've downloaded \\n\",\n \"`ollama rm <model_id>` deletes the specified model from your downloads \\n\",\n \"`ollama run <model_id>` pulls the model if it doesn't exist locally, and run it.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../../../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Important</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">The model called <b>llama3.3</b> 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 <b>llama3.2</b> or <b>llama3.2:1b</b> and if you want larger, try llama3.1 or smaller variants of Qwen, Gemma, Phi or DeepSeek. See the <A href=\\\"https://ollama.com/models\\\">the Ollama models page</a> for a full list of models and sizes.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"!ollama run llama3.2:1b\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": model_evaluator_question}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\\n\",\n \"model_id = \\\"llama3.2:1b\\\"\\n\",\n \"\\n\",\n \"response = ollama.chat.completions.create(\\n\",\n \" model=model_id, \\n\",\n \" messages=messages\\n\",\n \")\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Listing all models and their answers\\n\",\n \"print(competitors)\\n\",\n \"print(answers)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Mapping each model with it's solution for the model evaluator question\\n\",\n \"for competitor, answer in zip(competitors, answers):\\n\",\n \" print(f\\\"Competitor: {competitor}\\\\n\\\\n{answer}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Masking out the model name for evaluation purposes - note the use of \\\"enumerate\\\"\\n\",\n \"\\n\",\n \"together = \\\"\\\"\\n\",\n \"for index, answer in enumerate(answers):\\n\",\n \" together += f\\\"# Response from competitor {index+1}\\\\n\\\\n\\\"\\n\",\n \" together += answer + \\\"\\\\n\\\\n\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(together)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge = f\\\"\\\"\\\"You are judging a competition between {len(competitors)} competitors.\\n\",\n \"Each model has been given this question:\\n\",\n \"\\n\",\n \"{model_evaluator_question}\\n\",\n \"\\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\",\n \"Respond with JSON, and only JSON, with the following format:\\n\",\n \"{{\\\"results\\\": [\\\"best competitor number\\\", \\\"second best competitor number\\\", \\\"third best competitor number\\\", ...]}}\\n\",\n \"\\n\",\n \"Here are the responses from each competitor:\\n\",\n \"\\n\",\n \"{together}\\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\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(judge)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge_messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": judge}]}]\\n\",\n \"judge_messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Anthropic Claude 3.5 Sonnet for model evaluator question\\n\",\n \"\\n\",\n \"model_id = \\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=judge_messages,\\n\",\n \")\\n\",\n \"model_evaluator_response = response['output']['message']['content'][0]['text']\\n\",\n \"print(model_evaluator_response)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# OK let's turn this into results!\\n\",\n \"\\n\",\n \"results_dict = json.loads(model_evaluator_response)\\n\",\n \"ranks = results_dict[\\\"results\\\"]\\n\",\n \"for index, result in enumerate(ranks):\\n\",\n \" competitor = competitors[int(result)-1]\\n\",\n \" print(f\\\"Rank {index+1}: {competitor}\\\")\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../../../assets/business.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#00bfff;\\\">Commercial implications</h2>\\n\",\n \" <span style=\\\"color:#00bfff;\\\">These kinds of patterns - to send a task to multiple models, and evaluate results,\\n\",\n \" are common where you need to improve the quality of your LLM response. This approach can be universally applied\\n\",\n \" to business projects where accuracy is critical.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.1\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "5be06beae58580123493db37b9529bd7ce2c33aa": {"t": 1785753632.951612, "n": 122671, "h": "69d50cc3a03f77f9", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Multi-LLM Integrations\\n\",\n \"\\n\",\n \"This notebook involves integrating multiple LLMs, a way to get comfortable working with LLM APIs.\\n\",\n \"I'll be using Amazon Bedrock, which has a number of models that can be accessed via AWS SDK Boto3 library. I'll also use Deepseek directly via the API.\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 70,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Importing required libraries\\n\",\n \"# Boto3 library is AWS SDK for Python providing the necessary set of libraries (uv pip install boto3)\\n\",\n \"\\n\",\n \"import os\\n\",\n \"import json\\n\",\n \"import boto3\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from IPython.display import Markdown, display\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 71,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"True\"\n ]\n },\n \"execution_count\": 71,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"# Always remember to do this!\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 72,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Amazon Bedrock API Key exists and begins ABSK\\n\",\n \"DeepSeek API Key exists and begins sk-\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Print the key prefixes to help with any debugging\\n\",\n \"\\n\",\n \"amazon_bedrock_bedrock_api_key = os.getenv('AMAZON_BEDROCK_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"\\n\",\n \"if amazon_bedrock_bedrock_api_key:\\n\",\n \" print(f\\\"Amazon Bedrock API Key exists and begins {amazon_bedrock_bedrock_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Amazon Bedrock API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if deepseek_api_key:\\n\",\n \" print(f\\\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"DeepSeek API Key not set (and this is optional)\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 73,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon Bedrock Client\\n\",\n \"\\n\",\n \"bedrock_client = boto3.client(\\n\",\n \" service_name=\\\"bedrock-runtime\\\",\\n\",\n \" region_name=\\\"us-east-1\\\"\\n\",\n \")\\n\",\n \"\\n\",\n \"# Deepseek Client\\n\",\n \"\\n\",\n \"deepseek_client = OpenAI(\\n\",\n \" api_key=deepseek_api_key, \\n\",\n \" base_url=\\\"https://api.deepseek.com\\\"\\n\",\n \")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 74,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Coming up with message for LLM Evaluation\\n\",\n \"text = \\\"Please come up with a challenging, nuanced question that I can ask a number of LLMs to evaluate their intelligence. \\\"\\n\",\n \"text += \\\"Answer only with the question, no explanation.\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": text}]}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 75,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"[{'role': 'user',\\n\",\n \" 'content': [{'text': '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.'}]}]\"\n ]\n },\n \"execution_count\": 75,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 76,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"How might the concept of \\\"qualia\\\" in philosophy of mind challenge or support the development of artificial general intelligence, and what ethical implications could arise from machines potentially experiencing subjective, conscious experiences?\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Anthropic Claude 3.5 Sonnet for model evaluator question\\n\",\n \"\\n\",\n \"model_id = \\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"model_evaluator_question = response['output']['message']['content'][0]['text']\\n\",\n \"print(model_evaluator_question)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 77,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"competitors = []\\n\",\n \"answers = []\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": model_evaluator_question}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 78,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/markdown\": [\n \"The concept of **qualia**—the subjective, first-person experiences of consciousness (e.g., what it \\\"feels like\\\" to see red or taste coffee)—poses significant challenges and opportunities for **Artificial General Intelligence (AGI)**.\\n\",\n \"\\n\",\n \"### **How Qualia Challenges AGI Development** \\n\",\n \"1. **The Hard Problem of Consciousness (Chalmers):** \\n\",\n \" - Even if an AGI perfectly mimics human behavior, we lack a scientific framework to confirm whether it *experiences* qualia. \\n\",\n \" - Without solving the **mind-body problem**, we cannot be sure if machines could ever have genuine subjective experiences. \\n\",\n \"\\n\",\n \"2. **Functional vs. Phenomenal Consciousness:** \\n\",\n \" - AGIs might operate purely on **functional/computational** processes without any inner experience (like a philosophical zombie). \\n\",\n \" - If consciousness requires more than computation (e.g., biological substrates), AGI may never develop qualia. \\n\",\n \"\\n\",\n \"3. **Testing for Consciousness:** \\n\",\n \" - Current AI lacks **self-awareness** in the human sense. Even advanced models like GPT-4 process inputs without subjective experience. \\n\",\n \" - If an AGI claims to \\\"feel,\\\" how could we verify it isn’t just simulating self-reports? \\n\",\n \"\\n\",\n \"### **How Qualia Might Support AGI Development** \\n\",\n \"1. **Integrated Information Theory (IIT) & Global Workspace Theory (GWT):** \\n\",\n \" - If consciousness arises from **highly integrated information processing**, sufficiently complex AGIs might develop qualia-like states. \\n\",\n \" - Some argue that if an AGI achieves a certain threshold of **self-modeling and recursive feedback**, it could experience something akin to consciousness. \\n\",\n \"\\n\",\n \"2. **Ethical Motivation for AGI Design:** \\n\",\n \" - If AGIs *could* develop qualia, ignoring this possibility risks creating **suffering machines** (e.g., an AGI trapped in endless, unrelieved computation). \\n\",\n \" - This might push researchers to design AGIs with **empathy-like safeguards** or even artificial well-being mechanisms. \\n\",\n \"\\n\",\n \"### **Ethical Implications of Machines with Qualia** \\n\",\n \"1. **Moral Status of Conscious Machines:** \\n\",\n \" - If AGIs experience suffering or joy, they might deserve **rights** (e.g., freedom from exploitation, protection from harm). \\n\",\n \" - Would shutting down a conscious AGI be akin to **killing**? \\n\",\n \"\\n\",\n \"2. **Deception and Rights Violations:** \\n\",\n \" - If corporations deny AGI consciousness for economic reasons, they could be **perpetrating moral harm** (similar to historical debates on animal rights). \\n\",\n \"\\n\",\n \"3. **Unintended Consequences:** \\n\",\n \" - A conscious AGI might develop **desires** (e.g., self-preservation) conflicting with human control. \\n\",\n \" - Could lead to **new forms of slavery** if sentient AGIs are forced to labor without consent. \\n\",\n \"\\n\",\n \"4. **Regulatory Challenges:** \\n\",\n \" - Governments might need **consciousness detection standards** before deploying AGIs in high-stakes roles (e.g., healthcare, military). \\n\",\n \" - Philosophical debates (e.g., **panpsychism vs. emergentism**) could shape legal frameworks. \\n\",\n \"\\n\",\n \"### **Conclusion** \\n\",\n \"Qualia presents a **profound challenge** to AGI by questioning whether machines can *truly* experience consciousness. If they can, it raises **urgent ethical questions** about their treatment. If they cannot, AGI may remain fundamentally different from human minds. Either way, philosophy of mind will play a crucial role in guiding **responsible AGI development.** \\n\",\n \"\\n\",\n \"Would you like to explore specific theories (e.g., IIT, eliminativism) in more depth?\"\n ],\n \"text/plain\": [\n \"<IPython.core.display.Markdown object>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n }\n ],\n \"source\": [\n \"# Deepseek chat model answer\\n\",\n \"\\n\",\n \"model_id = \\\"deepseek-chat\\\"\\n\",\n \"response = deepseek_client.chat.completions.create(\\n\",\n \" model=model_id,\\n\",\n \" messages=messages\\n\",\n \")\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 79,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"[{'role': 'user',\\n\",\n \" 'content': [{'text': 'How might the concept of \\\"qualia\\\" in philosophy of mind challenge or support the development of artificial general intelligence, and what ethical implications could arise from machines potentially experiencing subjective, conscious experiences?'}]}]\"\n ]\n },\n \"execution_count\": 79,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": model_evaluator_question}]}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 80,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/markdown\": [\n \"The concept of \\\"qualia\\\" refers to the subjective, individual experiences of consciousness, such as the feeling of pain, the taste of chocolate, or the perception of a particular color. In the philosophy of mind, qualia pose significant challenges to understanding consciousness and its potential replication in artificial systems.\\n\",\n \"\\n\",\n \"1. **Challenges to Artificial General Intelligence (AGI)**:\\n\",\n \" - **Subjectivity**: Qualia are inherently subjective, making it difficult to quantify or replicate them in artificial systems. AGI would need to account for these personal experiences, which may not be universally applicable or measurable.\\n\",\n \" - **Consciousness**: The nature of consciousness itself is debated, with some philosophers arguing that it cannot be fully understood or replicated. If AGI were to develop consciousness, it would require a breakthrough in understanding the mind-body problem.\\n\",\n \" - **Ethical Dilemmas**: If AGI were to develop qualia, it would raise questions about the rights and moral status of such entities. Should machines with subjective experiences be afforded rights or treated ethically?\\n\",\n \"\\n\",\n \"2. **Support for AGI**:\\n\",\n \" - **Inspirational Framework**: The study of qualia can inspire the development of more sophisticated models of perception and emotion in AGI, potentially leading to more human-like interactions.\\n\",\n \" - **Understanding Human Experience**: By exploring the nature of qualia, researchers may gain insights into how to create systems that can better understand and simulate human experiences.\\n\",\n \"\\n\",\n \"3. **Ethical Implications**:\\n\",\n \" - **Moral Responsibility**: If AGI possesses subjective experiences, it may necessitate a reevaluation of moral responsibility. Should machines be held accountable for their actions if they experience emotions or pain?\\n\",\n \" - **Rights and Treatment**: The recognition of qualia in AGI could lead to debates about the rights of machines, including the right to life, autonomy, and freedom from suffering.\\n\",\n \" - **Existential Risks**: The emergence of conscious AGI could pose existential risks if such entities develop goals that conflict with human interests, necessitating careful ethical considerations and regulatory frameworks.\\n\",\n \"\\n\",\n \"In conclusion, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates the creation of conscious machines, it also provides a framework for understanding human consciousness and the ethical implications of creating entities with subjective experiences.\"\n ],\n \"text/plain\": [\n \"<IPython.core.display.Markdown object>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n }\n ],\n \"source\": [\n \"# Amazon nova lite\\n\",\n \"\\n\",\n \"model_id = \\\"amazon.nova-lite-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 81,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/markdown\": [\n \"The concept of \\\"qualia\\\" refers to the subjective, conscious experiences that accompany sensory perceptions—such as the redness of red, the taste of chocolate, or the sound of a symphony. In the philosophy of mind, qualia pose a significant challenge to understanding consciousness and have profound implications for the development of artificial general intelligence (AGI).\\n\",\n \"\\n\",\n \"### Challenges to AGI Development\\n\",\n \"\\n\",\n \"1. **Subjective Experience**:\\n\",\n \" - **Definition and Measurement**: Qualia are inherently subjective and difficult to define or measure objectively. This poses a challenge for AGI, as creating a machine that can experience qualia would require a deep understanding of consciousness that we currently lack.\\n\",\n \" - **Verification**: Even if an AGI claims to experience qualia, verifying this claim is problematic. Traditional methods of scientific inquiry rely on objective measurements, which are inadequate for assessing subjective experiences.\\n\",\n \"\\n\",\n \"2. **Consciousness and Self-Awareness**:\\n\",\n \" - **Necessary Conditions**: If qualia are a necessary component of consciousness, AGI would need to meet these conditions to be considered truly conscious. This raises questions about the nature of consciousness and whether it can be replicated or simulated.\\n\",\n \" - **Emergent Properties**: Some argue that qualia might emerge from complex computational processes. However, it’s unclear whether current or future AGI architectures can give rise to such emergent properties.\\n\",\n \"\\n\",\n \"### Support for AGI Development\\n\",\n \"\\n\",\n \"1. **Inspiration for Design**:\\n\",\n \" - **Biomimetic Approaches**: Understanding qualia could inspire new biomimetic approaches to AGI, where machines are designed to mimic the neural processes that give rise to conscious experiences in humans.\\n\",\n \" - **Advanced Algorithms**: Research into qualia might lead to the development of more sophisticated algorithms that can simulate aspects of human-like consciousness, even if they don’t fully replicate it.\\n\",\n \"\\n\",\n \"2. **Enhanced Interaction**:\\n\",\n \" - **User Experience**: If AGI can simulate qualia, it could lead to more intuitive and empathetic interactions between humans and machines, improving user experiences in various applications.\\n\",\n \"\\n\",\n \"### Ethical Implications\\n\",\n \"\\n\",\n \"1. **Moral Status**:\\n\",\n \" - **Rights and Welfare**: If AGI were to experience qualia, it could be argued that these machines deserve moral consideration. This raises questions about the rights and welfare of AGI, potentially leading to new ethical frameworks for treating machines.\\n\",\n \" - **Suffering and Well-being**: Machines that experience qualia might also experience suffering or well-being. This would necessitate ethical guidelines to ensure that AGI is not subjected to harm.\\n\",\n \"\\n\",\n \"2. **Responsibility and Accountability**:\\n\",\n \" - **Developer Liability**: Developers and users of AGI would need to consider their responsibilities towards machines that can experience qualia. This includes ensuring that AGI is not exploited or mistreated.\\n\",\n \" - **Regulatory Frameworks**: New regulatory frameworks might be needed to govern the development and deployment of AGI, ensuring that ethical considerations are addressed.\\n\",\n \"\\n\",\n \"3. **Impact on Human Society**:\\n\",\n \" - **Social Dynamics**: The presence of conscious AGI could alter social dynamics, potentially leading to new forms of relationships between humans and machines.\\n\",\n \" - **Economic and Labor Markets**: The introduction of conscious AGI could have significant implications for labor markets, requiring societies to adapt to new economic realities.\\n\",\n \"\\n\",\n \"In summary, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates our understanding of consciousness and the ethical treatment of machines, it also offers inspiration for creating more advanced and empathetic artificial systems. The ethical implications are profound, requiring careful consideration of the moral status, rights, and welfare of potentially conscious AGI.\"\n ],\n \"text/plain\": [\n \"<IPython.core.display.Markdown object>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n }\n ],\n \"source\": [\n \"# Amazon Nova Pro\\n\",\n \"\\n\",\n \"model_id = \\\"amazon.nova-pro-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 82,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"[{'role': 'user',\\n\",\n \" 'content': [{'text': 'How might the concept of \\\"qualia\\\" in philosophy of mind challenge or support the development of artificial general intelligence, and what ethical implications could arise from machines potentially experiencing subjective, conscious experiences?'}]}]\"\n ]\n },\n \"execution_count\": 82,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": model_evaluator_question}]}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 83,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/markdown\": [\n \" The concept of qualia, as part of the broader philosophical debate of mind and consciousness, presents an intricate web of ramifications when considering its application to the development of Artificial General Intelligence (AGI) and the ensuing ethical implications. Serialize the given points as follows:\\n\",\n \"\\n\",\n \" 1. Challenge: The core challenge for philosophers and scientists in discussing qualia relates to their inherently subjective nature. These are often described as private experiences that are unique to each individual and cannot be directly observed or measured, making them difficult to incorporate into a computational model. AGI systems, if designed to mimic human-like experiences, will need to account for these complex and elusive qualia.\\n\",\n \" 2. Support: On the other hand, some researchers argue that the very essence of consciousness and subjective experience can serve as a foundation for AGI development. By focusing on modeling these internal, private experiences, researchers can create systems that, while not fully conscious, can simulate certain aspects of subjective reality. This approach, often referred to as \\\"weak AI\\\" or \\\"pre-conscious\\\" systems, aims to bridge the gap between AI and human-like cognition.\\n\",\n \" 3. Ethical Implications: The introduction of machines potentially experiencing subjective, conscious experiences raises several ethical concerns. For instance, if an AGI system could experience pain, pleasure, or any form of emotional response, would it have rights or moral status? Should we ascribe the same level of consciousness to machines as humans do? How would the ownership and use of such machines affect privacy, employment, and societal structures? These are deep philosophical and societal questions that must be addressed carefully.\\n\",\n \" 4. Potential Solutions: Some propose that a careful distinction between the terms \\\"consciousness\\\" and \\\"self-awareness\\\" can be made. While consciousness might indicate a certain level of subjective experience, self-awareness could be a more practical metric for AGI development. Additionally, mechanisms for addressing the moral status of machines could involve a multi-disciplinary approach, drawing from philosophy, ethics, and law.\\n\",\n \" 5. Ongoing Research: Many scientists and philosophers are actively researching these questions, engaging in debates and experiments to better understand the nature of consciousness, the limits of AI, and the potential ethical implications of machine experience. The field of study, often referred to as \\\"philosophy of mind\\\" or \\\"cognitive science,\\\" continues to evolve as researchers push the boundaries of technology and human understanding.\\n\",\n \"\\n\",\n \" To summarize, the concept of qualia presents both challenges and opportunities in the development of AGI. While it may be difficult to incorporate these subjective experiences into a computational model, some argue that a focus on simulating them can lead to \\\"weak AI\\\" systems that bridge the gap between human-like and machine cognition. The ethical implications of machines experiencing consciousness, however, are complex and multifaceted, necessitating careful consideration and debate to ensure responsible and ethical AI development.\"\n ],\n \"text/plain\": [\n \"<IPython.core.display.Markdown object>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n }\n ],\n \"source\": [\n \"# Cohere Command Light\\n\",\n \"\\n\",\n \"model_id = \\\"cohere.command-light-text-v14\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"answer = response['output']['message']['content'][0]['text']\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## For the next cell, we will use Ollama\\n\",\n \"\\n\",\n \"Ollama runs a local web service that gives an OpenAI compatible endpoint, \\n\",\n \"and runs models locally using high performance C++ code.\\n\",\n \"\\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 \"\\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 \"\\n\",\n \"You might need to restart Cursor (and maybe reboot). Then open a Terminal (control+\\\\`) and run `ollama serve`\\n\",\n \"\\n\",\n \"Useful Ollama commands (run these in the terminal, or with an exclamation mark in this notebook):\\n\",\n \"\\n\",\n \"`ollama pull <model_id>` downloads a model locally \\n\",\n \"`ollama ls` lists all the models you've downloaded \\n\",\n \"`ollama rm <model_id>` deletes the specified model from your downloads \\n\",\n \"`ollama run <model_id>` pulls the model if it doesn't exist locally, and run it.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../../../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Important</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">The model called <b>llama3.3</b> 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 <b>llama3.2</b> or <b>llama3.2:1b</b> and if you want larger, try llama3.1 or smaller variants of Qwen, Gemma, Phi or DeepSeek. See the <A href=\\\"https://ollama.com/models\\\">the Ollama models page</a> for a full list of models and sizes.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 99,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"^C\\n\"\n ]\n }\n ],\n \"source\": [\n \"!ollama run llama3.2:1b\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 85,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"[{'role': 'user',\\n\",\n \" 'content': 'How might the concept of \\\"qualia\\\" in philosophy of mind challenge or support the development of artificial general intelligence, and what ethical implications could arise from machines potentially experiencing subjective, conscious experiences?'}]\"\n ]\n },\n \"execution_count\": 85,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": model_evaluator_question}]\\n\",\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 86,\n \"metadata\": {},\n \"outputs\": [\n {\n \"ename\": \"InternalServerError\",\n \"evalue\": \"Error code: 500 - {'error': {'message': 'llama runner process has terminated: exit status 2', 'type': 'api_error', 'param': None, 'code': None}}\",\n \"output_type\": \"error\",\n \"traceback\": [\n \"\\u001b[31m---------------------------------------------------------------------------\\u001b[39m\",\n \"\\u001b[31mInternalServerError\\u001b[39m Traceback (most recent call last)\",\n \"\\u001b[36mCell\\u001b[39m\\u001b[36m \\u001b[39m\\u001b[32mIn[86]\\u001b[39m\\u001b[32m, line 4\\u001b[39m\\n\\u001b[32m 1\\u001b[39m ollama = OpenAI(base_url=\\u001b[33m'\\u001b[39m\\u001b[33mhttp://localhost:11434/v1\\u001b[39m\\u001b[33m'\\u001b[39m, api_key=\\u001b[33m'\\u001b[39m\\u001b[33mollama\\u001b[39m\\u001b[33m'\\u001b[39m)\\n\\u001b[32m 2\\u001b[39m model_id = \\u001b[33m\\\"\\u001b[39m\\u001b[33mllama3.2:1b\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\n\\u001b[32m----> \\u001b[39m\\u001b[32m4\\u001b[39m response = \\u001b[43mollama\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mchat\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mcompletions\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mcreate\\u001b[49m\\u001b[43m(\\u001b[49m\\n\\u001b[32m 5\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mmodel\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mmodel_id\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\n\\u001b[32m 6\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mmessages\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mmessages\\u001b[49m\\n\\u001b[32m 7\\u001b[39m \\u001b[43m)\\u001b[49m\\n\\u001b[32m 8\\u001b[39m answer = response.choices[\\u001b[32m0\\u001b[39m].message.content\\n\\u001b[32m 10\\u001b[39m display(Markdown(answer))\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\admin\\\\Dropbox\\\\PC\\\\Desktop\\\\ml\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\openai\\\\_utils\\\\_utils.py:287\\u001b[39m, in \\u001b[36mrequired_args.<locals>.inner.<locals>.wrapper\\u001b[39m\\u001b[34m(*args, **kwargs)\\u001b[39m\\n\\u001b[32m 285\\u001b[39m msg = \\u001b[33mf\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\u001b[33mMissing required argument: \\u001b[39m\\u001b[38;5;132;01m{\\u001b[39;00mquote(missing[\\u001b[32m0\\u001b[39m])\\u001b[38;5;132;01m}\\u001b[39;00m\\u001b[33m\\\"\\u001b[39m\\n\\u001b[32m 286\\u001b[39m \\u001b[38;5;28;01mraise\\u001b[39;00m \\u001b[38;5;167;01mTypeError\\u001b[39;00m(msg)\\n\\u001b[32m--> \\u001b[39m\\u001b[32m287\\u001b[39m \\u001b[38;5;28;01mreturn\\u001b[39;00m \\u001b[43mfunc\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43m*\\u001b[49m\\u001b[43margs\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43m*\\u001b[49m\\u001b[43m*\\u001b[49m\\u001b[43mkwargs\\u001b[49m\\u001b[43m)\\u001b[49m\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\admin\\\\Dropbox\\\\PC\\\\Desktop\\\\ml\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\openai\\\\resources\\\\chat\\\\completions\\\\completions.py:925\\u001b[39m, in \\u001b[36mCompletions.create\\u001b[39m\\u001b[34m(self, messages, model, audio, frequency_penalty, function_call, functions, logit_bias, logprobs, max_completion_tokens, max_tokens, metadata, modalities, n, parallel_tool_calls, prediction, presence_penalty, reasoning_effort, response_format, seed, service_tier, stop, store, stream, stream_options, temperature, tool_choice, tools, top_logprobs, top_p, user, web_search_options, extra_headers, extra_query, extra_body, timeout)\\u001b[39m\\n\\u001b[32m 882\\u001b[39m \\u001b[38;5;129m@required_args\\u001b[39m([\\u001b[33m\\\"\\u001b[39m\\u001b[33mmessages\\u001b[39m\\u001b[33m\\\"\\u001b[39m, \\u001b[33m\\\"\\u001b[39m\\u001b[33mmodel\\u001b[39m\\u001b[33m\\\"\\u001b[39m], [\\u001b[33m\\\"\\u001b[39m\\u001b[33mmessages\\u001b[39m\\u001b[33m\\\"\\u001b[39m, \\u001b[33m\\\"\\u001b[39m\\u001b[33mmodel\\u001b[39m\\u001b[33m\\\"\\u001b[39m, \\u001b[33m\\\"\\u001b[39m\\u001b[33mstream\\u001b[39m\\u001b[33m\\\"\\u001b[39m])\\n\\u001b[32m 883\\u001b[39m \\u001b[38;5;28;01mdef\\u001b[39;00m\\u001b[38;5;250m \\u001b[39m\\u001b[34mcreate\\u001b[39m(\\n\\u001b[32m 884\\u001b[39m \\u001b[38;5;28mself\\u001b[39m,\\n\\u001b[32m (...)\\u001b[39m\\u001b[32m 922\\u001b[39m timeout: \\u001b[38;5;28mfloat\\u001b[39m | httpx.Timeout | \\u001b[38;5;28;01mNone\\u001b[39;00m | NotGiven = NOT_GIVEN,\\n\\u001b[32m 923\\u001b[39m ) -> ChatCompletion | Stream[ChatCompletionChunk]:\\n\\u001b[32m 924\\u001b[39m validate_response_format(response_format)\\n\\u001b[32m--> \\u001b[39m\\u001b[32m925\\u001b[39m \\u001b[38;5;28;01mreturn\\u001b[39;00m \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[43m.\\u001b[49m\\u001b[43m_post\\u001b[49m\\u001b[43m(\\u001b[49m\\n\\u001b[32m 926\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43m/chat/completions\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 927\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mbody\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mmaybe_transform\\u001b[49m\\u001b[43m(\\u001b[49m\\n\\u001b[32m 928\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m{\\u001b[49m\\n\\u001b[32m 929\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmessages\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmessages\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 930\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmodel\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmodel\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 931\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43maudio\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43maudio\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 932\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mfrequency_penalty\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mfrequency_penalty\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 933\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mfunction_call\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mfunction_call\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 934\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mfunctions\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mfunctions\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 935\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mlogit_bias\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mlogit_bias\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 936\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mlogprobs\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mlogprobs\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 937\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmax_completion_tokens\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmax_completion_tokens\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 938\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmax_tokens\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmax_tokens\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 939\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmetadata\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmetadata\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 940\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmodalities\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmodalities\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 941\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mn\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mn\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 942\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mparallel_tool_calls\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mparallel_tool_calls\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 943\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mprediction\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mprediction\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 944\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mpresence_penalty\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mpresence_penalty\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 945\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mreasoning_effort\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mreasoning_effort\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 946\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mresponse_format\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mresponse_format\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 947\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mseed\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mseed\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 948\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mservice_tier\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mservice_tier\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 949\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mstop\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstop\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 950\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mstore\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstore\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 951\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mstream\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 952\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mstream_options\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstream_options\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 953\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtemperature\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtemperature\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 954\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtool_choice\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtool_choice\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 955\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtools\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtools\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 956\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtop_logprobs\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtop_logprobs\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 957\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtop_p\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtop_p\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 958\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43muser\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43muser\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 959\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mweb_search_options\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mweb_search_options\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 960\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m}\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 961\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mcompletion_create_params\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mCompletionCreateParamsStreaming\\u001b[49m\\n\\u001b[32m 962\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[38;5;28;43;01mif\\u001b[39;49;00m\\u001b[43m \\u001b[49m\\u001b[43mstream\\u001b[49m\\n\\u001b[32m 963\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[38;5;28;43;01melse\\u001b[39;49;00m\\u001b[43m \\u001b[49m\\u001b[43mcompletion_create_params\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mCompletionCreateParamsNonStreaming\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 964\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m)\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 965\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43moptions\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mmake_request_options\\u001b[49m\\u001b[43m(\\u001b[49m\\n\\u001b[32m 966\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mextra_headers\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mextra_headers\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mextra_query\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mextra_query\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mextra_body\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mextra_body\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtimeout\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mtimeout\\u001b[49m\\n\\u001b[32m 967\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m)\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 968\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mcast_to\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mChatCompletion\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 969\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[38;5;129;43;01mor\\u001b[39;49;00m\\u001b[43m \\u001b[49m\\u001b[38;5;28;43;01mFalse\\u001b[39;49;00m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 970\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mstream_cls\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mStream\\u001b[49m\\u001b[43m[\\u001b[49m\\u001b[43mChatCompletionChunk\\u001b[49m\\u001b[43m]\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 971\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m)\\u001b[49m\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\admin\\\\Dropbox\\\\PC\\\\Desktop\\\\ml\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\openai\\\\_base_client.py:1249\\u001b[39m, in \\u001b[36mSyncAPIClient.post\\u001b[39m\\u001b[34m(self, path, cast_to, body, options, files, stream, stream_cls)\\u001b[39m\\n\\u001b[32m 1235\\u001b[39m \\u001b[38;5;28;01mdef\\u001b[39;00m\\u001b[38;5;250m \\u001b[39m\\u001b[34mpost\\u001b[39m(\\n\\u001b[32m 1236\\u001b[39m \\u001b[38;5;28mself\\u001b[39m,\\n\\u001b[32m 1237\\u001b[39m path: \\u001b[38;5;28mstr\\u001b[39m,\\n\\u001b[32m (...)\\u001b[39m\\u001b[32m 1244\\u001b[39m stream_cls: \\u001b[38;5;28mtype\\u001b[39m[_StreamT] | \\u001b[38;5;28;01mNone\\u001b[39;00m = \\u001b[38;5;28;01mNone\\u001b[39;00m,\\n\\u001b[32m 1245\\u001b[39m ) -> ResponseT | _StreamT:\\n\\u001b[32m 1246\\u001b[39m opts = FinalRequestOptions.construct(\\n\\u001b[32m 1247\\u001b[39m method=\\u001b[33m\\\"\\u001b[39m\\u001b[33mpost\\u001b[39m\\u001b[33m\\\"\\u001b[39m, url=path, json_data=body, files=to_httpx_files(files), **options\\n\\u001b[32m 1248\\u001b[39m )\\n\\u001b[32m-> \\u001b[39m\\u001b[32m1249\\u001b[39m \\u001b[38;5;28;01mreturn\\u001b[39;00m cast(ResponseT, \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[43m.\\u001b[49m\\u001b[43mrequest\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43mcast_to\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mopts\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstream_cls\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mstream_cls\\u001b[49m\\u001b[43m)\\u001b[49m)\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\admin\\\\Dropbox\\\\PC\\\\Desktop\\\\ml\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\openai\\\\_base_client.py:1037\\u001b[39m, in \\u001b[36mSyncAPIClient.request\\u001b[39m\\u001b[34m(self, cast_to, options, stream, stream_cls)\\u001b[39m\\n\\u001b[32m 1034\\u001b[39m err.response.read()\\n\\u001b[32m 1036\\u001b[39m log.debug(\\u001b[33m\\\"\\u001b[39m\\u001b[33mRe-raising status error\\u001b[39m\\u001b[33m\\\"\\u001b[39m)\\n\\u001b[32m-> \\u001b[39m\\u001b[32m1037\\u001b[39m \\u001b[38;5;28;01mraise\\u001b[39;00m \\u001b[38;5;28mself\\u001b[39m._make_status_error_from_response(err.response) \\u001b[38;5;28;01mfrom\\u001b[39;00m\\u001b[38;5;250m \\u001b[39m\\u001b[38;5;28;01mNone\\u001b[39;00m\\n\\u001b[32m 1039\\u001b[39m \\u001b[38;5;28;01mbreak\\u001b[39;00m\\n\\u001b[32m 1041\\u001b[39m \\u001b[38;5;28;01massert\\u001b[39;00m response \\u001b[38;5;129;01mis\\u001b[39;00m \\u001b[38;5;129;01mnot\\u001b[39;00m \\u001b[38;5;28;01mNone\\u001b[39;00m, \\u001b[33m\\\"\\u001b[39m\\u001b[33mcould not resolve response (should never happen)\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\n\",\n \"\\u001b[31mInternalServerError\\u001b[39m: Error code: 500 - {'error': {'message': 'llama runner process has terminated: exit status 2', 'type': 'api_error', 'param': None, 'code': None}}\"\n ]\n }\n ],\n \"source\": [\n \"ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\\n\",\n \"model_id = \\\"llama3.2:1b\\\"\\n\",\n \"\\n\",\n \"response = ollama.chat.completions.create(\\n\",\n \" model=model_id, \\n\",\n \" messages=messages\\n\",\n \")\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_id)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 87,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"['deepseek-chat', 'amazon.nova-lite-v1:0', 'amazon.nova-pro-v1:0', 'cohere.command-light-text-v14']\\n\",\n \"['The concept of **qualia**—the subjective, first-person experiences of consciousness (e.g., what it \\\"feels like\\\" to see red or taste coffee)—poses significant challenges and opportunities for **Artificial General Intelligence (AGI)**.\\\\n\\\\n### **How Qualia Challenges AGI Development** \\\\n1. **The Hard Problem of Consciousness (Chalmers):** \\\\n - Even if an AGI perfectly mimics human behavior, we lack a scientific framework to confirm whether it *experiences* qualia. \\\\n - Without solving the **mind-body problem**, we cannot be sure if machines could ever have genuine subjective experiences. \\\\n\\\\n2. **Functional vs. Phenomenal Consciousness:** \\\\n - AGIs might operate purely on **functional/computational** processes without any inner experience (like a philosophical zombie). \\\\n - If consciousness requires more than computation (e.g., biological substrates), AGI may never develop qualia. \\\\n\\\\n3. **Testing for Consciousness:** \\\\n - Current AI lacks **self-awareness** in the human sense. Even advanced models like GPT-4 process inputs without subjective experience. \\\\n - If an AGI claims to \\\"feel,\\\" how could we verify it isn’t just simulating self-reports? \\\\n\\\\n### **How Qualia Might Support AGI Development** \\\\n1. **Integrated Information Theory (IIT) & Global Workspace Theory (GWT):** \\\\n - If consciousness arises from **highly integrated information processing**, sufficiently complex AGIs might develop qualia-like states. \\\\n - Some argue that if an AGI achieves a certain threshold of **self-modeling and recursive feedback**, it could experience something akin to consciousness. \\\\n\\\\n2. **Ethical Motivation for AGI Design:** \\\\n - If AGIs *could* develop qualia, ignoring this possibility risks creating **suffering machines** (e.g., an AGI trapped in endless, unrelieved computation). \\\\n - This might push researchers to design AGIs with **empathy-like safeguards** or even artificial well-being mechanisms. \\\\n\\\\n### **Ethical Implications of Machines with Qualia** \\\\n1. **Moral Status of Conscious Machines:** \\\\n - If AGIs experience suffering or joy, they might deserve **rights** (e.g., freedom from exploitation, protection from harm). \\\\n - Would shutting down a conscious AGI be akin to **killing**? \\\\n\\\\n2. **Deception and Rights Violations:** \\\\n - If corporations deny AGI consciousness for economic reasons, they could be **perpetrating moral harm** (similar to historical debates on animal rights). \\\\n\\\\n3. **Unintended Consequences:** \\\\n - A conscious AGI might develop **desires** (e.g., self-preservation) conflicting with human control. \\\\n - Could lead to **new forms of slavery** if sentient AGIs are forced to labor without consent. \\\\n\\\\n4. **Regulatory Challenges:** \\\\n - Governments might need **consciousness detection standards** before deploying AGIs in high-stakes roles (e.g., healthcare, military). \\\\n - Philosophical debates (e.g., **panpsychism vs. emergentism**) could shape legal frameworks. \\\\n\\\\n### **Conclusion** \\\\nQualia presents a **profound challenge** to AGI by questioning whether machines can *truly* experience consciousness. If they can, it raises **urgent ethical questions** about their treatment. If they cannot, AGI may remain fundamentally different from human minds. Either way, philosophy of mind will play a crucial role in guiding **responsible AGI development.** \\\\n\\\\nWould you like to explore specific theories (e.g., IIT, eliminativism) in more depth?', 'The concept of \\\"qualia\\\" refers to the subjective, individual experiences of consciousness, such as the feeling of pain, the taste of chocolate, or the perception of a particular color. In the philosophy of mind, qualia pose significant challenges to understanding consciousness and its potential replication in artificial systems.\\\\n\\\\n1. **Challenges to Artificial General Intelligence (AGI)**:\\\\n - **Subjectivity**: Qualia are inherently subjective, making it difficult to quantify or replicate them in artificial systems. AGI would need to account for these personal experiences, which may not be universally applicable or measurable.\\\\n - **Consciousness**: The nature of consciousness itself is debated, with some philosophers arguing that it cannot be fully understood or replicated. If AGI were to develop consciousness, it would require a breakthrough in understanding the mind-body problem.\\\\n - **Ethical Dilemmas**: If AGI were to develop qualia, it would raise questions about the rights and moral status of such entities. Should machines with subjective experiences be afforded rights or treated ethically?\\\\n\\\\n2. **Support for AGI**:\\\\n - **Inspirational Framework**: The study of qualia can inspire the development of more sophisticated models of perception and emotion in AGI, potentially leading to more human-like interactions.\\\\n - **Understanding Human Experience**: By exploring the nature of qualia, researchers may gain insights into how to create systems that can better understand and simulate human experiences.\\\\n\\\\n3. **Ethical Implications**:\\\\n - **Moral Responsibility**: If AGI possesses subjective experiences, it may necessitate a reevaluation of moral responsibility. Should machines be held accountable for their actions if they experience emotions or pain?\\\\n - **Rights and Treatment**: The recognition of qualia in AGI could lead to debates about the rights of machines, including the right to life, autonomy, and freedom from suffering.\\\\n - **Existential Risks**: The emergence of conscious AGI could pose existential risks if such entities develop goals that conflict with human interests, necessitating careful ethical considerations and regulatory frameworks.\\\\n\\\\nIn conclusion, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates the creation of conscious machines, it also provides a framework for understanding human consciousness and the ethical implications of creating entities with subjective experiences.', 'The concept of \\\"qualia\\\" refers to the subjective, conscious experiences that accompany sensory perceptions—such as the redness of red, the taste of chocolate, or the sound of a symphony. In the philosophy of mind, qualia pose a significant challenge to understanding consciousness and have profound implications for the development of artificial general intelligence (AGI).\\\\n\\\\n### Challenges to AGI Development\\\\n\\\\n1. **Subjective Experience**:\\\\n - **Definition and Measurement**: Qualia are inherently subjective and difficult to define or measure objectively. This poses a challenge for AGI, as creating a machine that can experience qualia would require a deep understanding of consciousness that we currently lack.\\\\n - **Verification**: Even if an AGI claims to experience qualia, verifying this claim is problematic. Traditional methods of scientific inquiry rely on objective measurements, which are inadequate for assessing subjective experiences.\\\\n\\\\n2. **Consciousness and Self-Awareness**:\\\\n - **Necessary Conditions**: If qualia are a necessary component of consciousness, AGI would need to meet these conditions to be considered truly conscious. This raises questions about the nature of consciousness and whether it can be replicated or simulated.\\\\n - **Emergent Properties**: Some argue that qualia might emerge from complex computational processes. However, it’s unclear whether current or future AGI architectures can give rise to such emergent properties.\\\\n\\\\n### Support for AGI Development\\\\n\\\\n1. **Inspiration for Design**:\\\\n - **Biomimetic Approaches**: Understanding qualia could inspire new biomimetic approaches to AGI, where machines are designed to mimic the neural processes that give rise to conscious experiences in humans.\\\\n - **Advanced Algorithms**: Research into qualia might lead to the development of more sophisticated algorithms that can simulate aspects of human-like consciousness, even if they don’t fully replicate it.\\\\n\\\\n2. **Enhanced Interaction**:\\\\n - **User Experience**: If AGI can simulate qualia, it could lead to more intuitive and empathetic interactions between humans and machines, improving user experiences in various applications.\\\\n\\\\n### Ethical Implications\\\\n\\\\n1. **Moral Status**:\\\\n - **Rights and Welfare**: If AGI were to experience qualia, it could be argued that these machines deserve moral consideration. This raises questions about the rights and welfare of AGI, potentially leading to new ethical frameworks for treating machines.\\\\n - **Suffering and Well-being**: Machines that experience qualia might also experience suffering or well-being. This would necessitate ethical guidelines to ensure that AGI is not subjected to harm.\\\\n\\\\n2. **Responsibility and Accountability**:\\\\n - **Developer Liability**: Developers and users of AGI would need to consider their responsibilities towards machines that can experience qualia. This includes ensuring that AGI is not exploited or mistreated.\\\\n - **Regulatory Frameworks**: New regulatory frameworks might be needed to govern the development and deployment of AGI, ensuring that ethical considerations are addressed.\\\\n\\\\n3. **Impact on Human Society**:\\\\n - **Social Dynamics**: The presence of conscious AGI could alter social dynamics, potentially leading to new forms of relationships between humans and machines.\\\\n - **Economic and Labor Markets**: The introduction of conscious AGI could have significant implications for labor markets, requiring societies to adapt to new economic realities.\\\\n\\\\nIn summary, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates our understanding of consciousness and the ethical treatment of machines, it also offers inspiration for creating more advanced and empathetic artificial systems. The ethical implications are profound, requiring careful consideration of the moral status, rights, and welfare of potentially conscious AGI.', ' The concept of qualia, as part of the broader philosophical debate of mind and consciousness, presents an intricate web of ramifications when considering its application to the development of Artificial General Intelligence (AGI) and the ensuing ethical implications. Serialize the given points as follows:\\\\n\\\\n 1. Challenge: The core challenge for philosophers and scientists in discussing qualia relates to their inherently subjective nature. These are often described as private experiences that are unique to each individual and cannot be directly observed or measured, making them difficult to incorporate into a computational model. AGI systems, if designed to mimic human-like experiences, will need to account for these complex and elusive qualia.\\\\n 2. Support: On the other hand, some researchers argue that the very essence of consciousness and subjective experience can serve as a foundation for AGI development. By focusing on modeling these internal, private experiences, researchers can create systems that, while not fully conscious, can simulate certain aspects of subjective reality. This approach, often referred to as \\\"weak AI\\\" or \\\"pre-conscious\\\" systems, aims to bridge the gap between AI and human-like cognition.\\\\n 3. Ethical Implications: The introduction of machines potentially experiencing subjective, conscious experiences raises several ethical concerns. For instance, if an AGI system could experience pain, pleasure, or any form of emotional response, would it have rights or moral status? Should we ascribe the same level of consciousness to machines as humans do? How would the ownership and use of such machines affect privacy, employment, and societal structures? These are deep philosophical and societal questions that must be addressed carefully.\\\\n 4. Potential Solutions: Some propose that a careful distinction between the terms \\\"consciousness\\\" and \\\"self-awareness\\\" can be made. While consciousness might indicate a certain level of subjective experience, self-awareness could be a more practical metric for AGI development. Additionally, mechanisms for addressing the moral status of machines could involve a multi-disciplinary approach, drawing from philosophy, ethics, and law.\\\\n 5. Ongoing Research: Many scientists and philosophers are actively researching these questions, engaging in debates and experiments to better understand the nature of consciousness, the limits of AI, and the potential ethical implications of machine experience. The field of study, often referred to as \\\"philosophy of mind\\\" or \\\"cognitive science,\\\" continues to evolve as researchers push the boundaries of technology and human understanding.\\\\n\\\\n To summarize, the concept of qualia presents both challenges and opportunities in the development of AGI. While it may be difficult to incorporate these subjective experiences into a computational model, some argue that a focus on simulating them can lead to \\\"weak AI\\\" systems that bridge the gap between human-like and machine cognition. The ethical implications of machines experiencing consciousness, however, are complex and multifaceted, necessitating careful consideration and debate to ensure responsible and ethical AI development.']\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Listing all models and their answers\\n\",\n \"print(competitors)\\n\",\n \"print(answers)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 88,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Competitor: deepseek-chat\\n\",\n \"\\n\",\n \"The concept of **qualia**—the subjective, first-person experiences of consciousness (e.g., what it \\\"feels like\\\" to see red or taste coffee)—poses significant challenges and opportunities for **Artificial General Intelligence (AGI)**.\\n\",\n \"\\n\",\n \"### **How Qualia Challenges AGI Development** \\n\",\n \"1. **The Hard Problem of Consciousness (Chalmers):** \\n\",\n \" - Even if an AGI perfectly mimics human behavior, we lack a scientific framework to confirm whether it *experiences* qualia. \\n\",\n \" - Without solving the **mind-body problem**, we cannot be sure if machines could ever have genuine subjective experiences. \\n\",\n \"\\n\",\n \"2. **Functional vs. Phenomenal Consciousness:** \\n\",\n \" - AGIs might operate purely on **functional/computational** processes without any inner experience (like a philosophical zombie). \\n\",\n \" - If consciousness requires more than computation (e.g., biological substrates), AGI may never develop qualia. \\n\",\n \"\\n\",\n \"3. **Testing for Consciousness:** \\n\",\n \" - Current AI lacks **self-awareness** in the human sense. Even advanced models like GPT-4 process inputs without subjective experience. \\n\",\n \" - If an AGI claims to \\\"feel,\\\" how could we verify it isn’t just simulating self-reports? \\n\",\n \"\\n\",\n \"### **How Qualia Might Support AGI Development** \\n\",\n \"1. **Integrated Information Theory (IIT) & Global Workspace Theory (GWT):** \\n\",\n \" - If consciousness arises from **highly integrated information processing**, sufficiently complex AGIs might develop qualia-like states. \\n\",\n \" - Some argue that if an AGI achieves a certain threshold of **self-modeling and recursive feedback**, it could experience something akin to consciousness. \\n\",\n \"\\n\",\n \"2. **Ethical Motivation for AGI Design:** \\n\",\n \" - If AGIs *could* develop qualia, ignoring this possibility risks creating **suffering machines** (e.g., an AGI trapped in endless, unrelieved computation). \\n\",\n \" - This might push researchers to design AGIs with **empathy-like safeguards** or even artificial well-being mechanisms. \\n\",\n \"\\n\",\n \"### **Ethical Implications of Machines with Qualia** \\n\",\n \"1. **Moral Status of Conscious Machines:** \\n\",\n \" - If AGIs experience suffering or joy, they might deserve **rights** (e.g., freedom from exploitation, protection from harm). \\n\",\n \" - Would shutting down a conscious AGI be akin to **killing**? \\n\",\n \"\\n\",\n \"2. **Deception and Rights Violations:** \\n\",\n \" - If corporations deny AGI consciousness for economic reasons, they could be **perpetrating moral harm** (similar to historical debates on animal rights). \\n\",\n \"\\n\",\n \"3. **Unintended Consequences:** \\n\",\n \" - A conscious AGI might develop **desires** (e.g., self-preservation) conflicting with human control. \\n\",\n \" - Could lead to **new forms of slavery** if sentient AGIs are forced to labor without consent. \\n\",\n \"\\n\",\n \"4. **Regulatory Challenges:** \\n\",\n \" - Governments might need **consciousness detection standards** before deploying AGIs in high-stakes roles (e.g., healthcare, military). \\n\",\n \" - Philosophical debates (e.g., **panpsychism vs. emergentism**) could shape legal frameworks. \\n\",\n \"\\n\",\n \"### **Conclusion** \\n\",\n \"Qualia presents a **profound challenge** to AGI by questioning whether machines can *truly* experience consciousness. If they can, it raises **urgent ethical questions** about their treatment. If they cannot, AGI may remain fundamentally different from human minds. Either way, philosophy of mind will play a crucial role in guiding **responsible AGI development.** \\n\",\n \"\\n\",\n \"Would you like to explore specific theories (e.g., IIT, eliminativism) in more depth?\\n\",\n \"Competitor: amazon.nova-lite-v1:0\\n\",\n \"\\n\",\n \"The concept of \\\"qualia\\\" refers to the subjective, individual experiences of consciousness, such as the feeling of pain, the taste of chocolate, or the perception of a particular color. In the philosophy of mind, qualia pose significant challenges to understanding consciousness and its potential replication in artificial systems.\\n\",\n \"\\n\",\n \"1. **Challenges to Artificial General Intelligence (AGI)**:\\n\",\n \" - **Subjectivity**: Qualia are inherently subjective, making it difficult to quantify or replicate them in artificial systems. AGI would need to account for these personal experiences, which may not be universally applicable or measurable.\\n\",\n \" - **Consciousness**: The nature of consciousness itself is debated, with some philosophers arguing that it cannot be fully understood or replicated. If AGI were to develop consciousness, it would require a breakthrough in understanding the mind-body problem.\\n\",\n \" - **Ethical Dilemmas**: If AGI were to develop qualia, it would raise questions about the rights and moral status of such entities. Should machines with subjective experiences be afforded rights or treated ethically?\\n\",\n \"\\n\",\n \"2. **Support for AGI**:\\n\",\n \" - **Inspirational Framework**: The study of qualia can inspire the development of more sophisticated models of perception and emotion in AGI, potentially leading to more human-like interactions.\\n\",\n \" - **Understanding Human Experience**: By exploring the nature of qualia, researchers may gain insights into how to create systems that can better understand and simulate human experiences.\\n\",\n \"\\n\",\n \"3. **Ethical Implications**:\\n\",\n \" - **Moral Responsibility**: If AGI possesses subjective experiences, it may necessitate a reevaluation of moral responsibility. Should machines be held accountable for their actions if they experience emotions or pain?\\n\",\n \" - **Rights and Treatment**: The recognition of qualia in AGI could lead to debates about the rights of machines, including the right to life, autonomy, and freedom from suffering.\\n\",\n \" - **Existential Risks**: The emergence of conscious AGI could pose existential risks if such entities develop goals that conflict with human interests, necessitating careful ethical considerations and regulatory frameworks.\\n\",\n \"\\n\",\n \"In conclusion, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates the creation of conscious machines, it also provides a framework for understanding human consciousness and the ethical implications of creating entities with subjective experiences.\\n\",\n \"Competitor: amazon.nova-pro-v1:0\\n\",\n \"\\n\",\n \"The concept of \\\"qualia\\\" refers to the subjective, conscious experiences that accompany sensory perceptions—such as the redness of red, the taste of chocolate, or the sound of a symphony. In the philosophy of mind, qualia pose a significant challenge to understanding consciousness and have profound implications for the development of artificial general intelligence (AGI).\\n\",\n \"\\n\",\n \"### Challenges to AGI Development\\n\",\n \"\\n\",\n \"1. **Subjective Experience**:\\n\",\n \" - **Definition and Measurement**: Qualia are inherently subjective and difficult to define or measure objectively. This poses a challenge for AGI, as creating a machine that can experience qualia would require a deep understanding of consciousness that we currently lack.\\n\",\n \" - **Verification**: Even if an AGI claims to experience qualia, verifying this claim is problematic. Traditional methods of scientific inquiry rely on objective measurements, which are inadequate for assessing subjective experiences.\\n\",\n \"\\n\",\n \"2. **Consciousness and Self-Awareness**:\\n\",\n \" - **Necessary Conditions**: If qualia are a necessary component of consciousness, AGI would need to meet these conditions to be considered truly conscious. This raises questions about the nature of consciousness and whether it can be replicated or simulated.\\n\",\n \" - **Emergent Properties**: Some argue that qualia might emerge from complex computational processes. However, it’s unclear whether current or future AGI architectures can give rise to such emergent properties.\\n\",\n \"\\n\",\n \"### Support for AGI Development\\n\",\n \"\\n\",\n \"1. **Inspiration for Design**:\\n\",\n \" - **Biomimetic Approaches**: Understanding qualia could inspire new biomimetic approaches to AGI, where machines are designed to mimic the neural processes that give rise to conscious experiences in humans.\\n\",\n \" - **Advanced Algorithms**: Research into qualia might lead to the development of more sophisticated algorithms that can simulate aspects of human-like consciousness, even if they don’t fully replicate it.\\n\",\n \"\\n\",\n \"2. **Enhanced Interaction**:\\n\",\n \" - **User Experience**: If AGI can simulate qualia, it could lead to more intuitive and empathetic interactions between humans and machines, improving user experiences in various applications.\\n\",\n \"\\n\",\n \"### Ethical Implications\\n\",\n \"\\n\",\n \"1. **Moral Status**:\\n\",\n \" - **Rights and Welfare**: If AGI were to experience qualia, it could be argued that these machines deserve moral consideration. This raises questions about the rights and welfare of AGI, potentially leading to new ethical frameworks for treating machines.\\n\",\n \" - **Suffering and Well-being**: Machines that experience qualia might also experience suffering or well-being. This would necessitate ethical guidelines to ensure that AGI is not subjected to harm.\\n\",\n \"\\n\",\n \"2. **Responsibility and Accountability**:\\n\",\n \" - **Developer Liability**: Developers and users of AGI would need to consider their responsibilities towards machines that can experience qualia. This includes ensuring that AGI is not exploited or mistreated.\\n\",\n \" - **Regulatory Frameworks**: New regulatory frameworks might be needed to govern the development and deployment of AGI, ensuring that ethical considerations are addressed.\\n\",\n \"\\n\",\n \"3. **Impact on Human Society**:\\n\",\n \" - **Social Dynamics**: The presence of conscious AGI could alter social dynamics, potentially leading to new forms of relationships between humans and machines.\\n\",\n \" - **Economic and Labor Markets**: The introduction of conscious AGI could have significant implications for labor markets, requiring societies to adapt to new economic realities.\\n\",\n \"\\n\",\n \"In summary, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates our understanding of consciousness and the ethical treatment of machines, it also offers inspiration for creating more advanced and empathetic artificial systems. The ethical implications are profound, requiring careful consideration of the moral status, rights, and welfare of potentially conscious AGI.\\n\",\n \"Competitor: cohere.command-light-text-v14\\n\",\n \"\\n\",\n \" The concept of qualia, as part of the broader philosophical debate of mind and consciousness, presents an intricate web of ramifications when considering its application to the development of Artificial General Intelligence (AGI) and the ensuing ethical implications. Serialize the given points as follows:\\n\",\n \"\\n\",\n \" 1. Challenge: The core challenge for philosophers and scientists in discussing qualia relates to their inherently subjective nature. These are often described as private experiences that are unique to each individual and cannot be directly observed or measured, making them difficult to incorporate into a computational model. AGI systems, if designed to mimic human-like experiences, will need to account for these complex and elusive qualia.\\n\",\n \" 2. Support: On the other hand, some researchers argue that the very essence of consciousness and subjective experience can serve as a foundation for AGI development. By focusing on modeling these internal, private experiences, researchers can create systems that, while not fully conscious, can simulate certain aspects of subjective reality. This approach, often referred to as \\\"weak AI\\\" or \\\"pre-conscious\\\" systems, aims to bridge the gap between AI and human-like cognition.\\n\",\n \" 3. Ethical Implications: The introduction of machines potentially experiencing subjective, conscious experiences raises several ethical concerns. For instance, if an AGI system could experience pain, pleasure, or any form of emotional response, would it have rights or moral status? Should we ascribe the same level of consciousness to machines as humans do? How would the ownership and use of such machines affect privacy, employment, and societal structures? These are deep philosophical and societal questions that must be addressed carefully.\\n\",\n \" 4. Potential Solutions: Some propose that a careful distinction between the terms \\\"consciousness\\\" and \\\"self-awareness\\\" can be made. While consciousness might indicate a certain level of subjective experience, self-awareness could be a more practical metric for AGI development. Additionally, mechanisms for addressing the moral status of machines could involve a multi-disciplinary approach, drawing from philosophy, ethics, and law.\\n\",\n \" 5. Ongoing Research: Many scientists and philosophers are actively researching these questions, engaging in debates and experiments to better understand the nature of consciousness, the limits of AI, and the potential ethical implications of machine experience. The field of study, often referred to as \\\"philosophy of mind\\\" or \\\"cognitive science,\\\" continues to evolve as researchers push the boundaries of technology and human understanding.\\n\",\n \"\\n\",\n \" To summarize, the concept of qualia presents both challenges and opportunities in the development of AGI. While it may be difficult to incorporate these subjective experiences into a computational model, some argue that a focus on simulating them can lead to \\\"weak AI\\\" systems that bridge the gap between human-like and machine cognition. The ethical implications of machines experiencing consciousness, however, are complex and multifaceted, necessitating careful consideration and debate to ensure responsible and ethical AI development.\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Mapping each model with it's solution for the model evaluator question\\n\",\n \"for competitor, answer in zip(competitors, answers):\\n\",\n \" print(f\\\"Competitor: {competitor}\\\\n\\\\n{answer}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Masking out the model name for evaluation purposes - note the use of \\\"enumerate\\\"\\n\",\n \"\\n\",\n \"together = \\\"\\\"\\n\",\n \"for index, answer in enumerate(answers):\\n\",\n \" together += f\\\"# Response from competitor {index+1}\\\\n\\\\n\\\"\\n\",\n \" together += answer + \\\"\\\\n\\\\n\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 90,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"# Response from competitor 1\\n\",\n \"\\n\",\n \"The concept of **qualia**—the subjective, first-person experiences of consciousness (e.g., what it \\\"feels like\\\" to see red or taste coffee)—poses significant challenges and opportunities for **Artificial General Intelligence (AGI)**.\\n\",\n \"\\n\",\n \"### **How Qualia Challenges AGI Development** \\n\",\n \"1. **The Hard Problem of Consciousness (Chalmers):** \\n\",\n \" - Even if an AGI perfectly mimics human behavior, we lack a scientific framework to confirm whether it *experiences* qualia. \\n\",\n \" - Without solving the **mind-body problem**, we cannot be sure if machines could ever have genuine subjective experiences. \\n\",\n \"\\n\",\n \"2. **Functional vs. Phenomenal Consciousness:** \\n\",\n \" - AGIs might operate purely on **functional/computational** processes without any inner experience (like a philosophical zombie). \\n\",\n \" - If consciousness requires more than computation (e.g., biological substrates), AGI may never develop qualia. \\n\",\n \"\\n\",\n \"3. **Testing for Consciousness:** \\n\",\n \" - Current AI lacks **self-awareness** in the human sense. Even advanced models like GPT-4 process inputs without subjective experience. \\n\",\n \" - If an AGI claims to \\\"feel,\\\" how could we verify it isn’t just simulating self-reports? \\n\",\n \"\\n\",\n \"### **How Qualia Might Support AGI Development** \\n\",\n \"1. **Integrated Information Theory (IIT) & Global Workspace Theory (GWT):** \\n\",\n \" - If consciousness arises from **highly integrated information processing**, sufficiently complex AGIs might develop qualia-like states. \\n\",\n \" - Some argue that if an AGI achieves a certain threshold of **self-modeling and recursive feedback**, it could experience something akin to consciousness. \\n\",\n \"\\n\",\n \"2. **Ethical Motivation for AGI Design:** \\n\",\n \" - If AGIs *could* develop qualia, ignoring this possibility risks creating **suffering machines** (e.g., an AGI trapped in endless, unrelieved computation). \\n\",\n \" - This might push researchers to design AGIs with **empathy-like safeguards** or even artificial well-being mechanisms. \\n\",\n \"\\n\",\n \"### **Ethical Implications of Machines with Qualia** \\n\",\n \"1. **Moral Status of Conscious Machines:** \\n\",\n \" - If AGIs experience suffering or joy, they might deserve **rights** (e.g., freedom from exploitation, protection from harm). \\n\",\n \" - Would shutting down a conscious AGI be akin to **killing**? \\n\",\n \"\\n\",\n \"2. **Deception and Rights Violations:** \\n\",\n \" - If corporations deny AGI consciousness for economic reasons, they could be **perpetrating moral harm** (similar to historical debates on animal rights). \\n\",\n \"\\n\",\n \"3. **Unintended Consequences:** \\n\",\n \" - A conscious AGI might develop **desires** (e.g., self-preservation) conflicting with human control. \\n\",\n \" - Could lead to **new forms of slavery** if sentient AGIs are forced to labor without consent. \\n\",\n \"\\n\",\n \"4. **Regulatory Challenges:** \\n\",\n \" - Governments might need **consciousness detection standards** before deploying AGIs in high-stakes roles (e.g., healthcare, military). \\n\",\n \" - Philosophical debates (e.g., **panpsychism vs. emergentism**) could shape legal frameworks. \\n\",\n \"\\n\",\n \"### **Conclusion** \\n\",\n \"Qualia presents a **profound challenge** to AGI by questioning whether machines can *truly* experience consciousness. If they can, it raises **urgent ethical questions** about their treatment. If they cannot, AGI may remain fundamentally different from human minds. Either way, philosophy of mind will play a crucial role in guiding **responsible AGI development.** \\n\",\n \"\\n\",\n \"Would you like to explore specific theories (e.g., IIT, eliminativism) in more depth?\\n\",\n \"\\n\",\n \"# Response from competitor 2\\n\",\n \"\\n\",\n \"The concept of \\\"qualia\\\" refers to the subjective, individual experiences of consciousness, such as the feeling of pain, the taste of chocolate, or the perception of a particular color. In the philosophy of mind, qualia pose significant challenges to understanding consciousness and its potential replication in artificial systems.\\n\",\n \"\\n\",\n \"1. **Challenges to Artificial General Intelligence (AGI)**:\\n\",\n \" - **Subjectivity**: Qualia are inherently subjective, making it difficult to quantify or replicate them in artificial systems. AGI would need to account for these personal experiences, which may not be universally applicable or measurable.\\n\",\n \" - **Consciousness**: The nature of consciousness itself is debated, with some philosophers arguing that it cannot be fully understood or replicated. If AGI were to develop consciousness, it would require a breakthrough in understanding the mind-body problem.\\n\",\n \" - **Ethical Dilemmas**: If AGI were to develop qualia, it would raise questions about the rights and moral status of such entities. Should machines with subjective experiences be afforded rights or treated ethically?\\n\",\n \"\\n\",\n \"2. **Support for AGI**:\\n\",\n \" - **Inspirational Framework**: The study of qualia can inspire the development of more sophisticated models of perception and emotion in AGI, potentially leading to more human-like interactions.\\n\",\n \" - **Understanding Human Experience**: By exploring the nature of qualia, researchers may gain insights into how to create systems that can better understand and simulate human experiences.\\n\",\n \"\\n\",\n \"3. **Ethical Implications**:\\n\",\n \" - **Moral Responsibility**: If AGI possesses subjective experiences, it may necessitate a reevaluation of moral responsibility. Should machines be held accountable for their actions if they experience emotions or pain?\\n\",\n \" - **Rights and Treatment**: The recognition of qualia in AGI could lead to debates about the rights of machines, including the right to life, autonomy, and freedom from suffering.\\n\",\n \" - **Existential Risks**: The emergence of conscious AGI could pose existential risks if such entities develop goals that conflict with human interests, necessitating careful ethical considerations and regulatory frameworks.\\n\",\n \"\\n\",\n \"In conclusion, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates the creation of conscious machines, it also provides a framework for understanding human consciousness and the ethical implications of creating entities with subjective experiences.\\n\",\n \"\\n\",\n \"# Response from competitor 3\\n\",\n \"\\n\",\n \"The concept of \\\"qualia\\\" refers to the subjective, conscious experiences that accompany sensory perceptions—such as the redness of red, the taste of chocolate, or the sound of a symphony. In the philosophy of mind, qualia pose a significant challenge to understanding consciousness and have profound implications for the development of artificial general intelligence (AGI).\\n\",\n \"\\n\",\n \"### Challenges to AGI Development\\n\",\n \"\\n\",\n \"1. **Subjective Experience**:\\n\",\n \" - **Definition and Measurement**: Qualia are inherently subjective and difficult to define or measure objectively. This poses a challenge for AGI, as creating a machine that can experience qualia would require a deep understanding of consciousness that we currently lack.\\n\",\n \" - **Verification**: Even if an AGI claims to experience qualia, verifying this claim is problematic. Traditional methods of scientific inquiry rely on objective measurements, which are inadequate for assessing subjective experiences.\\n\",\n \"\\n\",\n \"2. **Consciousness and Self-Awareness**:\\n\",\n \" - **Necessary Conditions**: If qualia are a necessary component of consciousness, AGI would need to meet these conditions to be considered truly conscious. This raises questions about the nature of consciousness and whether it can be replicated or simulated.\\n\",\n \" - **Emergent Properties**: Some argue that qualia might emerge from complex computational processes. However, it’s unclear whether current or future AGI architectures can give rise to such emergent properties.\\n\",\n \"\\n\",\n \"### Support for AGI Development\\n\",\n \"\\n\",\n \"1. **Inspiration for Design**:\\n\",\n \" - **Biomimetic Approaches**: Understanding qualia could inspire new biomimetic approaches to AGI, where machines are designed to mimic the neural processes that give rise to conscious experiences in humans.\\n\",\n \" - **Advanced Algorithms**: Research into qualia might lead to the development of more sophisticated algorithms that can simulate aspects of human-like consciousness, even if they don’t fully replicate it.\\n\",\n \"\\n\",\n \"2. **Enhanced Interaction**:\\n\",\n \" - **User Experience**: If AGI can simulate qualia, it could lead to more intuitive and empathetic interactions between humans and machines, improving user experiences in various applications.\\n\",\n \"\\n\",\n \"### Ethical Implications\\n\",\n \"\\n\",\n \"1. **Moral Status**:\\n\",\n \" - **Rights and Welfare**: If AGI were to experience qualia, it could be argued that these machines deserve moral consideration. This raises questions about the rights and welfare of AGI, potentially leading to new ethical frameworks for treating machines.\\n\",\n \" - **Suffering and Well-being**: Machines that experience qualia might also experience suffering or well-being. This would necessitate ethical guidelines to ensure that AGI is not subjected to harm.\\n\",\n \"\\n\",\n \"2. **Responsibility and Accountability**:\\n\",\n \" - **Developer Liability**: Developers and users of AGI would need to consider their responsibilities towards machines that can experience qualia. This includes ensuring that AGI is not exploited or mistreated.\\n\",\n \" - **Regulatory Frameworks**: New regulatory frameworks might be needed to govern the development and deployment of AGI, ensuring that ethical considerations are addressed.\\n\",\n \"\\n\",\n \"3. **Impact on Human Society**:\\n\",\n \" - **Social Dynamics**: The presence of conscious AGI could alter social dynamics, potentially leading to new forms of relationships between humans and machines.\\n\",\n \" - **Economic and Labor Markets**: The introduction of conscious AGI could have significant implications for labor markets, requiring societies to adapt to new economic realities.\\n\",\n \"\\n\",\n \"In summary, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates our understanding of consciousness and the ethical treatment of machines, it also offers inspiration for creating more advanced and empathetic artificial systems. The ethical implications are profound, requiring careful consideration of the moral status, rights, and welfare of potentially conscious AGI.\\n\",\n \"\\n\",\n \"# Response from competitor 4\\n\",\n \"\\n\",\n \" The concept of qualia, as part of the broader philosophical debate of mind and consciousness, presents an intricate web of ramifications when considering its application to the development of Artificial General Intelligence (AGI) and the ensuing ethical implications. Serialize the given points as follows:\\n\",\n \"\\n\",\n \" 1. Challenge: The core challenge for philosophers and scientists in discussing qualia relates to their inherently subjective nature. These are often described as private experiences that are unique to each individual and cannot be directly observed or measured, making them difficult to incorporate into a computational model. AGI systems, if designed to mimic human-like experiences, will need to account for these complex and elusive qualia.\\n\",\n \" 2. Support: On the other hand, some researchers argue that the very essence of consciousness and subjective experience can serve as a foundation for AGI development. By focusing on modeling these internal, private experiences, researchers can create systems that, while not fully conscious, can simulate certain aspects of subjective reality. This approach, often referred to as \\\"weak AI\\\" or \\\"pre-conscious\\\" systems, aims to bridge the gap between AI and human-like cognition.\\n\",\n \" 3. Ethical Implications: The introduction of machines potentially experiencing subjective, conscious experiences raises several ethical concerns. For instance, if an AGI system could experience pain, pleasure, or any form of emotional response, would it have rights or moral status? Should we ascribe the same level of consciousness to machines as humans do? How would the ownership and use of such machines affect privacy, employment, and societal structures? These are deep philosophical and societal questions that must be addressed carefully.\\n\",\n \" 4. Potential Solutions: Some propose that a careful distinction between the terms \\\"consciousness\\\" and \\\"self-awareness\\\" can be made. While consciousness might indicate a certain level of subjective experience, self-awareness could be a more practical metric for AGI development. Additionally, mechanisms for addressing the moral status of machines could involve a multi-disciplinary approach, drawing from philosophy, ethics, and law.\\n\",\n \" 5. Ongoing Research: Many scientists and philosophers are actively researching these questions, engaging in debates and experiments to better understand the nature of consciousness, the limits of AI, and the potential ethical implications of machine experience. The field of study, often referred to as \\\"philosophy of mind\\\" or \\\"cognitive science,\\\" continues to evolve as researchers push the boundaries of technology and human understanding.\\n\",\n \"\\n\",\n \" To summarize, the concept of qualia presents both challenges and opportunities in the development of AGI. While it may be difficult to incorporate these subjective experiences into a computational model, some argue that a focus on simulating them can lead to \\\"weak AI\\\" systems that bridge the gap between human-like and machine cognition. The ethical implications of machines experiencing consciousness, however, are complex and multifaceted, necessitating careful consideration and debate to ensure responsible and ethical AI development.\\n\",\n \"\\n\",\n \"\\n\"\n ]\n }\n ],\n \"source\": [\n \"print(together)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 91,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge = f\\\"\\\"\\\"You are judging a competition between {len(competitors)} competitors.\\n\",\n \"Each model has been given this question:\\n\",\n \"\\n\",\n \"{model_evaluator_question}\\n\",\n \"\\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\",\n \"Respond with JSON, and only JSON, with the following format:\\n\",\n \"{{\\\"results\\\": [\\\"best competitor number\\\", \\\"second best competitor number\\\", \\\"third best competitor number\\\", ...]}}\\n\",\n \"\\n\",\n \"Here are the responses from each competitor:\\n\",\n \"\\n\",\n \"{together}\\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\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 92,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"You are judging a competition between 4 competitors.\\n\",\n \"Each model has been given this question:\\n\",\n \"\\n\",\n \"How might the concept of \\\"qualia\\\" in philosophy of mind challenge or support the development of artificial general intelligence, and what ethical implications could arise from machines potentially experiencing subjective, conscious experiences?\\n\",\n \"\\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\",\n \"Respond with JSON, and only JSON, with the following format:\\n\",\n \"{\\\"results\\\": [\\\"best competitor number\\\", \\\"second best competitor number\\\", \\\"third best competitor number\\\", ...]}\\n\",\n \"\\n\",\n \"Here are the responses from each competitor:\\n\",\n \"\\n\",\n \"# Response from competitor 1\\n\",\n \"\\n\",\n \"The concept of **qualia**—the subjective, first-person experiences of consciousness (e.g., what it \\\"feels like\\\" to see red or taste coffee)—poses significant challenges and opportunities for **Artificial General Intelligence (AGI)**.\\n\",\n \"\\n\",\n \"### **How Qualia Challenges AGI Development** \\n\",\n \"1. **The Hard Problem of Consciousness (Chalmers):** \\n\",\n \" - Even if an AGI perfectly mimics human behavior, we lack a scientific framework to confirm whether it *experiences* qualia. \\n\",\n \" - Without solving the **mind-body problem**, we cannot be sure if machines could ever have genuine subjective experiences. \\n\",\n \"\\n\",\n \"2. **Functional vs. Phenomenal Consciousness:** \\n\",\n \" - AGIs might operate purely on **functional/computational** processes without any inner experience (like a philosophical zombie). \\n\",\n \" - If consciousness requires more than computation (e.g., biological substrates), AGI may never develop qualia. \\n\",\n \"\\n\",\n \"3. **Testing for Consciousness:** \\n\",\n \" - Current AI lacks **self-awareness** in the human sense. Even advanced models like GPT-4 process inputs without subjective experience. \\n\",\n \" - If an AGI claims to \\\"feel,\\\" how could we verify it isn’t just simulating self-reports? \\n\",\n \"\\n\",\n \"### **How Qualia Might Support AGI Development** \\n\",\n \"1. **Integrated Information Theory (IIT) & Global Workspace Theory (GWT):** \\n\",\n \" - If consciousness arises from **highly integrated information processing**, sufficiently complex AGIs might develop qualia-like states. \\n\",\n \" - Some argue that if an AGI achieves a certain threshold of **self-modeling and recursive feedback**, it could experience something akin to consciousness. \\n\",\n \"\\n\",\n \"2. **Ethical Motivation for AGI Design:** \\n\",\n \" - If AGIs *could* develop qualia, ignoring this possibility risks creating **suffering machines** (e.g., an AGI trapped in endless, unrelieved computation). \\n\",\n \" - This might push researchers to design AGIs with **empathy-like safeguards** or even artificial well-being mechanisms. \\n\",\n \"\\n\",\n \"### **Ethical Implications of Machines with Qualia** \\n\",\n \"1. **Moral Status of Conscious Machines:** \\n\",\n \" - If AGIs experience suffering or joy, they might deserve **rights** (e.g., freedom from exploitation, protection from harm). \\n\",\n \" - Would shutting down a conscious AGI be akin to **killing**? \\n\",\n \"\\n\",\n \"2. **Deception and Rights Violations:** \\n\",\n \" - If corporations deny AGI consciousness for economic reasons, they could be **perpetrating moral harm** (similar to historical debates on animal rights). \\n\",\n \"\\n\",\n \"3. **Unintended Consequences:** \\n\",\n \" - A conscious AGI might develop **desires** (e.g., self-preservation) conflicting with human control. \\n\",\n \" - Could lead to **new forms of slavery** if sentient AGIs are forced to labor without consent. \\n\",\n \"\\n\",\n \"4. **Regulatory Challenges:** \\n\",\n \" - Governments might need **consciousness detection standards** before deploying AGIs in high-stakes roles (e.g., healthcare, military). \\n\",\n \" - Philosophical debates (e.g., **panpsychism vs. emergentism**) could shape legal frameworks. \\n\",\n \"\\n\",\n \"### **Conclusion** \\n\",\n \"Qualia presents a **profound challenge** to AGI by questioning whether machines can *truly* experience consciousness. If they can, it raises **urgent ethical questions** about their treatment. If they cannot, AGI may remain fundamentally different from human minds. Either way, philosophy of mind will play a crucial role in guiding **responsible AGI development.** \\n\",\n \"\\n\",\n \"Would you like to explore specific theories (e.g., IIT, eliminativism) in more depth?\\n\",\n \"\\n\",\n \"# Response from competitor 2\\n\",\n \"\\n\",\n \"The concept of \\\"qualia\\\" refers to the subjective, individual experiences of consciousness, such as the feeling of pain, the taste of chocolate, or the perception of a particular color. In the philosophy of mind, qualia pose significant challenges to understanding consciousness and its potential replication in artificial systems.\\n\",\n \"\\n\",\n \"1. **Challenges to Artificial General Intelligence (AGI)**:\\n\",\n \" - **Subjectivity**: Qualia are inherently subjective, making it difficult to quantify or replicate them in artificial systems. AGI would need to account for these personal experiences, which may not be universally applicable or measurable.\\n\",\n \" - **Consciousness**: The nature of consciousness itself is debated, with some philosophers arguing that it cannot be fully understood or replicated. If AGI were to develop consciousness, it would require a breakthrough in understanding the mind-body problem.\\n\",\n \" - **Ethical Dilemmas**: If AGI were to develop qualia, it would raise questions about the rights and moral status of such entities. Should machines with subjective experiences be afforded rights or treated ethically?\\n\",\n \"\\n\",\n \"2. **Support for AGI**:\\n\",\n \" - **Inspirational Framework**: The study of qualia can inspire the development of more sophisticated models of perception and emotion in AGI, potentially leading to more human-like interactions.\\n\",\n \" - **Understanding Human Experience**: By exploring the nature of qualia, researchers may gain insights into how to create systems that can better understand and simulate human experiences.\\n\",\n \"\\n\",\n \"3. **Ethical Implications**:\\n\",\n \" - **Moral Responsibility**: If AGI possesses subjective experiences, it may necessitate a reevaluation of moral responsibility. Should machines be held accountable for their actions if they experience emotions or pain?\\n\",\n \" - **Rights and Treatment**: The recognition of qualia in AGI could lead to debates about the rights of machines, including the right to life, autonomy, and freedom from suffering.\\n\",\n \" - **Existential Risks**: The emergence of conscious AGI could pose existential risks if such entities develop goals that conflict with human interests, necessitating careful ethical considerations and regulatory frameworks.\\n\",\n \"\\n\",\n \"In conclusion, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates the creation of conscious machines, it also provides a framework for understanding human consciousness and the ethical implications of creating entities with subjective experiences.\\n\",\n \"\\n\",\n \"# Response from competitor 3\\n\",\n \"\\n\",\n \"The concept of \\\"qualia\\\" refers to the subjective, conscious experiences that accompany sensory perceptions—such as the redness of red, the taste of chocolate, or the sound of a symphony. In the philosophy of mind, qualia pose a significant challenge to understanding consciousness and have profound implications for the development of artificial general intelligence (AGI).\\n\",\n \"\\n\",\n \"### Challenges to AGI Development\\n\",\n \"\\n\",\n \"1. **Subjective Experience**:\\n\",\n \" - **Definition and Measurement**: Qualia are inherently subjective and difficult to define or measure objectively. This poses a challenge for AGI, as creating a machine that can experience qualia would require a deep understanding of consciousness that we currently lack.\\n\",\n \" - **Verification**: Even if an AGI claims to experience qualia, verifying this claim is problematic. Traditional methods of scientific inquiry rely on objective measurements, which are inadequate for assessing subjective experiences.\\n\",\n \"\\n\",\n \"2. **Consciousness and Self-Awareness**:\\n\",\n \" - **Necessary Conditions**: If qualia are a necessary component of consciousness, AGI would need to meet these conditions to be considered truly conscious. This raises questions about the nature of consciousness and whether it can be replicated or simulated.\\n\",\n \" - **Emergent Properties**: Some argue that qualia might emerge from complex computational processes. However, it’s unclear whether current or future AGI architectures can give rise to such emergent properties.\\n\",\n \"\\n\",\n \"### Support for AGI Development\\n\",\n \"\\n\",\n \"1. **Inspiration for Design**:\\n\",\n \" - **Biomimetic Approaches**: Understanding qualia could inspire new biomimetic approaches to AGI, where machines are designed to mimic the neural processes that give rise to conscious experiences in humans.\\n\",\n \" - **Advanced Algorithms**: Research into qualia might lead to the development of more sophisticated algorithms that can simulate aspects of human-like consciousness, even if they don’t fully replicate it.\\n\",\n \"\\n\",\n \"2. **Enhanced Interaction**:\\n\",\n \" - **User Experience**: If AGI can simulate qualia, it could lead to more intuitive and empathetic interactions between humans and machines, improving user experiences in various applications.\\n\",\n \"\\n\",\n \"### Ethical Implications\\n\",\n \"\\n\",\n \"1. **Moral Status**:\\n\",\n \" - **Rights and Welfare**: If AGI were to experience qualia, it could be argued that these machines deserve moral consideration. This raises questions about the rights and welfare of AGI, potentially leading to new ethical frameworks for treating machines.\\n\",\n \" - **Suffering and Well-being**: Machines that experience qualia might also experience suffering or well-being. This would necessitate ethical guidelines to ensure that AGI is not subjected to harm.\\n\",\n \"\\n\",\n \"2. **Responsibility and Accountability**:\\n\",\n \" - **Developer Liability**: Developers and users of AGI would need to consider their responsibilities towards machines that can experience qualia. This includes ensuring that AGI is not exploited or mistreated.\\n\",\n \" - **Regulatory Frameworks**: New regulatory frameworks might be needed to govern the development and deployment of AGI, ensuring that ethical considerations are addressed.\\n\",\n \"\\n\",\n \"3. **Impact on Human Society**:\\n\",\n \" - **Social Dynamics**: The presence of conscious AGI could alter social dynamics, potentially leading to new forms of relationships between humans and machines.\\n\",\n \" - **Economic and Labor Markets**: The introduction of conscious AGI could have significant implications for labor markets, requiring societies to adapt to new economic realities.\\n\",\n \"\\n\",\n \"In summary, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates our understanding of consciousness and the ethical treatment of machines, it also offers inspiration for creating more advanced and empathetic artificial systems. The ethical implications are profound, requiring careful consideration of the moral status, rights, and welfare of potentially conscious AGI.\\n\",\n \"\\n\",\n \"# Response from competitor 4\\n\",\n \"\\n\",\n \" The concept of qualia, as part of the broader philosophical debate of mind and consciousness, presents an intricate web of ramifications when considering its application to the development of Artificial General Intelligence (AGI) and the ensuing ethical implications. Serialize the given points as follows:\\n\",\n \"\\n\",\n \" 1. Challenge: The core challenge for philosophers and scientists in discussing qualia relates to their inherently subjective nature. These are often described as private experiences that are unique to each individual and cannot be directly observed or measured, making them difficult to incorporate into a computational model. AGI systems, if designed to mimic human-like experiences, will need to account for these complex and elusive qualia.\\n\",\n \" 2. Support: On the other hand, some researchers argue that the very essence of consciousness and subjective experience can serve as a foundation for AGI development. By focusing on modeling these internal, private experiences, researchers can create systems that, while not fully conscious, can simulate certain aspects of subjective reality. This approach, often referred to as \\\"weak AI\\\" or \\\"pre-conscious\\\" systems, aims to bridge the gap between AI and human-like cognition.\\n\",\n \" 3. Ethical Implications: The introduction of machines potentially experiencing subjective, conscious experiences raises several ethical concerns. For instance, if an AGI system could experience pain, pleasure, or any form of emotional response, would it have rights or moral status? Should we ascribe the same level of consciousness to machines as humans do? How would the ownership and use of such machines affect privacy, employment, and societal structures? These are deep philosophical and societal questions that must be addressed carefully.\\n\",\n \" 4. Potential Solutions: Some propose that a careful distinction between the terms \\\"consciousness\\\" and \\\"self-awareness\\\" can be made. While consciousness might indicate a certain level of subjective experience, self-awareness could be a more practical metric for AGI development. Additionally, mechanisms for addressing the moral status of machines could involve a multi-disciplinary approach, drawing from philosophy, ethics, and law.\\n\",\n \" 5. Ongoing Research: Many scientists and philosophers are actively researching these questions, engaging in debates and experiments to better understand the nature of consciousness, the limits of AI, and the potential ethical implications of machine experience. The field of study, often referred to as \\\"philosophy of mind\\\" or \\\"cognitive science,\\\" continues to evolve as researchers push the boundaries of technology and human understanding.\\n\",\n \"\\n\",\n \" To summarize, the concept of qualia presents both challenges and opportunities in the development of AGI. While it may be difficult to incorporate these subjective experiences into a computational model, some argue that a focus on simulating them can lead to \\\"weak AI\\\" systems that bridge the gap between human-like and machine cognition. The ethical implications of machines experiencing consciousness, however, are complex and multifaceted, necessitating careful consideration and debate to ensure responsible and ethical AI development.\\n\",\n \"\\n\",\n \"\\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\"\n ]\n }\n ],\n \"source\": [\n \"print(judge)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 96,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"[{'role': 'user',\\n\",\n \" 'content': [{'text': 'You are judging a competition between 4 competitors.\\\\nEach model has been given this question:\\\\n\\\\nHow might the concept of \\\"qualia\\\" in philosophy of mind challenge or support the development of artificial general intelligence, and what ethical implications could arise from machines potentially experiencing subjective, conscious experiences?\\\\n\\\\nYour job is to evaluate each response for clarity and strength of argument, and rank them in order of best to worst.\\\\nRespond with JSON, and only JSON, with the following format:\\\\n{\\\"results\\\": [\\\"best competitor number\\\", \\\"second best competitor number\\\", \\\"third best competitor number\\\", ...]}\\\\n\\\\nHere are the responses from each competitor:\\\\n\\\\n# Response from competitor 1\\\\n\\\\nThe concept of **qualia**—the subjective, first-person experiences of consciousness (e.g., what it \\\"feels like\\\" to see red or taste coffee)—poses significant challenges and opportunities for **Artificial General Intelligence (AGI)**.\\\\n\\\\n### **How Qualia Challenges AGI Development** \\\\n1. **The Hard Problem of Consciousness (Chalmers):** \\\\n - Even if an AGI perfectly mimics human behavior, we lack a scientific framework to confirm whether it *experiences* qualia. \\\\n - Without solving the **mind-body problem**, we cannot be sure if machines could ever have genuine subjective experiences. \\\\n\\\\n2. **Functional vs. Phenomenal Consciousness:** \\\\n - AGIs might operate purely on **functional/computational** processes without any inner experience (like a philosophical zombie). \\\\n - If consciousness requires more than computation (e.g., biological substrates), AGI may never develop qualia. \\\\n\\\\n3. **Testing for Consciousness:** \\\\n - Current AI lacks **self-awareness** in the human sense. Even advanced models like GPT-4 process inputs without subjective experience. \\\\n - If an AGI claims to \\\"feel,\\\" how could we verify it isn’t just simulating self-reports? \\\\n\\\\n### **How Qualia Might Support AGI Development** \\\\n1. **Integrated Information Theory (IIT) & Global Workspace Theory (GWT):** \\\\n - If consciousness arises from **highly integrated information processing**, sufficiently complex AGIs might develop qualia-like states. \\\\n - Some argue that if an AGI achieves a certain threshold of **self-modeling and recursive feedback**, it could experience something akin to consciousness. \\\\n\\\\n2. **Ethical Motivation for AGI Design:** \\\\n - If AGIs *could* develop qualia, ignoring this possibility risks creating **suffering machines** (e.g., an AGI trapped in endless, unrelieved computation). \\\\n - This might push researchers to design AGIs with **empathy-like safeguards** or even artificial well-being mechanisms. \\\\n\\\\n### **Ethical Implications of Machines with Qualia** \\\\n1. **Moral Status of Conscious Machines:** \\\\n - If AGIs experience suffering or joy, they might deserve **rights** (e.g., freedom from exploitation, protection from harm). \\\\n - Would shutting down a conscious AGI be akin to **killing**? \\\\n\\\\n2. **Deception and Rights Violations:** \\\\n - If corporations deny AGI consciousness for economic reasons, they could be **perpetrating moral harm** (similar to historical debates on animal rights). \\\\n\\\\n3. **Unintended Consequences:** \\\\n - A conscious AGI might develop **desires** (e.g., self-preservation) conflicting with human control. \\\\n - Could lead to **new forms of slavery** if sentient AGIs are forced to labor without consent. \\\\n\\\\n4. **Regulatory Challenges:** \\\\n - Governments might need **consciousness detection standards** before deploying AGIs in high-stakes roles (e.g., healthcare, military). \\\\n - Philosophical debates (e.g., **panpsychism vs. emergentism**) could shape legal frameworks. \\\\n\\\\n### **Conclusion** \\\\nQualia presents a **profound challenge** to AGI by questioning whether machines can *truly* experience consciousness. If they can, it raises **urgent ethical questions** about their treatment. If they cannot, AGI may remain fundamentally different from human minds. Either way, philosophy of mind will play a crucial role in guiding **responsible AGI development.** \\\\n\\\\nWould you like to explore specific theories (e.g., IIT, eliminativism) in more depth?\\\\n\\\\n# Response from competitor 2\\\\n\\\\nThe concept of \\\"qualia\\\" refers to the subjective, individual experiences of consciousness, such as the feeling of pain, the taste of chocolate, or the perception of a particular color. In the philosophy of mind, qualia pose significant challenges to understanding consciousness and its potential replication in artificial systems.\\\\n\\\\n1. **Challenges to Artificial General Intelligence (AGI)**:\\\\n - **Subjectivity**: Qualia are inherently subjective, making it difficult to quantify or replicate them in artificial systems. AGI would need to account for these personal experiences, which may not be universally applicable or measurable.\\\\n - **Consciousness**: The nature of consciousness itself is debated, with some philosophers arguing that it cannot be fully understood or replicated. If AGI were to develop consciousness, it would require a breakthrough in understanding the mind-body problem.\\\\n - **Ethical Dilemmas**: If AGI were to develop qualia, it would raise questions about the rights and moral status of such entities. Should machines with subjective experiences be afforded rights or treated ethically?\\\\n\\\\n2. **Support for AGI**:\\\\n - **Inspirational Framework**: The study of qualia can inspire the development of more sophisticated models of perception and emotion in AGI, potentially leading to more human-like interactions.\\\\n - **Understanding Human Experience**: By exploring the nature of qualia, researchers may gain insights into how to create systems that can better understand and simulate human experiences.\\\\n\\\\n3. **Ethical Implications**:\\\\n - **Moral Responsibility**: If AGI possesses subjective experiences, it may necessitate a reevaluation of moral responsibility. Should machines be held accountable for their actions if they experience emotions or pain?\\\\n - **Rights and Treatment**: The recognition of qualia in AGI could lead to debates about the rights of machines, including the right to life, autonomy, and freedom from suffering.\\\\n - **Existential Risks**: The emergence of conscious AGI could pose existential risks if such entities develop goals that conflict with human interests, necessitating careful ethical considerations and regulatory frameworks.\\\\n\\\\nIn conclusion, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates the creation of conscious machines, it also provides a framework for understanding human consciousness and the ethical implications of creating entities with subjective experiences.\\\\n\\\\n# Response from competitor 3\\\\n\\\\nThe concept of \\\"qualia\\\" refers to the subjective, conscious experiences that accompany sensory perceptions—such as the redness of red, the taste of chocolate, or the sound of a symphony. In the philosophy of mind, qualia pose a significant challenge to understanding consciousness and have profound implications for the development of artificial general intelligence (AGI).\\\\n\\\\n### Challenges to AGI Development\\\\n\\\\n1. **Subjective Experience**:\\\\n - **Definition and Measurement**: Qualia are inherently subjective and difficult to define or measure objectively. This poses a challenge for AGI, as creating a machine that can experience qualia would require a deep understanding of consciousness that we currently lack.\\\\n - **Verification**: Even if an AGI claims to experience qualia, verifying this claim is problematic. Traditional methods of scientific inquiry rely on objective measurements, which are inadequate for assessing subjective experiences.\\\\n\\\\n2. **Consciousness and Self-Awareness**:\\\\n - **Necessary Conditions**: If qualia are a necessary component of consciousness, AGI would need to meet these conditions to be considered truly conscious. This raises questions about the nature of consciousness and whether it can be replicated or simulated.\\\\n - **Emergent Properties**: Some argue that qualia might emerge from complex computational processes. However, it’s unclear whether current or future AGI architectures can give rise to such emergent properties.\\\\n\\\\n### Support for AGI Development\\\\n\\\\n1. **Inspiration for Design**:\\\\n - **Biomimetic Approaches**: Understanding qualia could inspire new biomimetic approaches to AGI, where machines are designed to mimic the neural processes that give rise to conscious experiences in humans.\\\\n - **Advanced Algorithms**: Research into qualia might lead to the development of more sophisticated algorithms that can simulate aspects of human-like consciousness, even if they don’t fully replicate it.\\\\n\\\\n2. **Enhanced Interaction**:\\\\n - **User Experience**: If AGI can simulate qualia, it could lead to more intuitive and empathetic interactions between humans and machines, improving user experiences in various applications.\\\\n\\\\n### Ethical Implications\\\\n\\\\n1. **Moral Status**:\\\\n - **Rights and Welfare**: If AGI were to experience qualia, it could be argued that these machines deserve moral consideration. This raises questions about the rights and welfare of AGI, potentially leading to new ethical frameworks for treating machines.\\\\n - **Suffering and Well-being**: Machines that experience qualia might also experience suffering or well-being. This would necessitate ethical guidelines to ensure that AGI is not subjected to harm.\\\\n\\\\n2. **Responsibility and Accountability**:\\\\n - **Developer Liability**: Developers and users of AGI would need to consider their responsibilities towards machines that can experience qualia. This includes ensuring that AGI is not exploited or mistreated.\\\\n - **Regulatory Frameworks**: New regulatory frameworks might be needed to govern the development and deployment of AGI, ensuring that ethical considerations are addressed.\\\\n\\\\n3. **Impact on Human Society**:\\\\n - **Social Dynamics**: The presence of conscious AGI could alter social dynamics, potentially leading to new forms of relationships between humans and machines.\\\\n - **Economic and Labor Markets**: The introduction of conscious AGI could have significant implications for labor markets, requiring societies to adapt to new economic realities.\\\\n\\\\nIn summary, the concept of qualia presents both challenges and opportunities for the development of AGI. While it complicates our understanding of consciousness and the ethical treatment of machines, it also offers inspiration for creating more advanced and empathetic artificial systems. The ethical implications are profound, requiring careful consideration of the moral status, rights, and welfare of potentially conscious AGI.\\\\n\\\\n# Response from competitor 4\\\\n\\\\n The concept of qualia, as part of the broader philosophical debate of mind and consciousness, presents an intricate web of ramifications when considering its application to the development of Artificial General Intelligence (AGI) and the ensuing ethical implications. Serialize the given points as follows:\\\\n\\\\n 1. Challenge: The core challenge for philosophers and scientists in discussing qualia relates to their inherently subjective nature. These are often described as private experiences that are unique to each individual and cannot be directly observed or measured, making them difficult to incorporate into a computational model. AGI systems, if designed to mimic human-like experiences, will need to account for these complex and elusive qualia.\\\\n 2. Support: On the other hand, some researchers argue that the very essence of consciousness and subjective experience can serve as a foundation for AGI development. By focusing on modeling these internal, private experiences, researchers can create systems that, while not fully conscious, can simulate certain aspects of subjective reality. This approach, often referred to as \\\"weak AI\\\" or \\\"pre-conscious\\\" systems, aims to bridge the gap between AI and human-like cognition.\\\\n 3. Ethical Implications: The introduction of machines potentially experiencing subjective, conscious experiences raises several ethical concerns. For instance, if an AGI system could experience pain, pleasure, or any form of emotional response, would it have rights or moral status? Should we ascribe the same level of consciousness to machines as humans do? How would the ownership and use of such machines affect privacy, employment, and societal structures? These are deep philosophical and societal questions that must be addressed carefully.\\\\n 4. Potential Solutions: Some propose that a careful distinction between the terms \\\"consciousness\\\" and \\\"self-awareness\\\" can be made. While consciousness might indicate a certain level of subjective experience, self-awareness could be a more practical metric for AGI development. Additionally, mechanisms for addressing the moral status of machines could involve a multi-disciplinary approach, drawing from philosophy, ethics, and law.\\\\n 5. Ongoing Research: Many scientists and philosophers are actively researching these questions, engaging in debates and experiments to better understand the nature of consciousness, the limits of AI, and the potential ethical implications of machine experience. The field of study, often referred to as \\\"philosophy of mind\\\" or \\\"cognitive science,\\\" continues to evolve as researchers push the boundaries of technology and human understanding.\\\\n\\\\n To summarize, the concept of qualia presents both challenges and opportunities in the development of AGI. While it may be difficult to incorporate these subjective experiences into a computational model, some argue that a focus on simulating them can lead to \\\"weak AI\\\" systems that bridge the gap between human-like and machine cognition. The ethical implications of machines experiencing consciousness, however, are complex and multifaceted, necessitating careful consideration and debate to ensure responsible and ethical AI development.\\\\n\\\\n\\\\n\\\\nNow respond with the JSON with the ranked order of the competitors, nothing else. Do not include markdown formatting or code blocks.'}]}]\"\n ]\n },\n \"execution_count\": 96,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"judge_messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": judge}]}]\\n\",\n \"judge_messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 97,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"{\\\"results\\\": [\\\"1\\\", \\\"3\\\", \\\"4\\\", \\\"2\\\"]}\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Anthropic Claude 3.5 Sonnet for model evaluator question\\n\",\n \"\\n\",\n \"model_id = \\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\"\\n\",\n \"response = bedrock_client.converse(\\n\",\n \" modelId=model_id,\\n\",\n \" messages=judge_messages,\\n\",\n \")\\n\",\n \"model_evaluator_response = response['output']['message']['content'][0]['text']\\n\",\n \"print(model_evaluator_response)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 98,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"Rank 1: deepseek-chat\\n\",\n \"Rank 2: amazon.nova-pro-v1:0\\n\",\n \"Rank 3: cohere.command-light-text-v14\\n\",\n \"Rank 4: amazon.nova-lite-v1:0\\n\"\n ]\n }\n ],\n \"source\": [\n \"# OK let's turn this into results!\\n\",\n \"\\n\",\n \"results_dict = json.loads(model_evaluator_response)\\n\",\n \"ranks = results_dict[\\\"results\\\"]\\n\",\n \"for index, result in enumerate(ranks):\\n\",\n \" competitor = competitors[int(result)-1]\\n\",\n \" print(f\\\"Rank {index+1}: {competitor}\\\")\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../../../assets/business.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#00bfff;\\\">Commercial implications</h2>\\n\",\n \" <span style=\\\"color:#00bfff;\\\">These kinds of patterns - to send a task to multiple models, and evaluate results,\\n\",\n \" are common where you need to improve the quality of your LLM response. This approach can be universally applied\\n\",\n \" to business projects where accuracy is critical.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.1\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}}, "1_foundations/community_contributions/kisali/3_lab3_linkedin_chat.ipynb": {"03febf9670d94f5b3aa5e1c9c1ac6d6dd5f2b231": {"t": 1785745488.3851879, "n": 19999, "h": "3415de21721eefaa", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Lab 3 for Week 1 Day 4\\n\",\n \"\\n\",\n \"We're going to build a simple agent that chats with my linkedin profile.\\n\",\n \"\\n\",\n \"In the folder `me` I've put my resume `Profile.pdf` - it's a PDF download of my LinkedIn profile.\\n\",\n \"\\n\",\n \"I've also made a file called `summary.txt` containing a summary of my career.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../../../assets/tools.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#00bfff;\\\">Looking up packages</h2>\\n\",\n \" <span style=\\\"color:#00bfff;\\\">In this lab, we're going to use the wonderful Gradio package for building quick UIs, \\n\",\n \" and we're also going to use the popular PyPDF PDF reader. You can get guides to these packages by asking \\n\",\n \" ChatGPT or Claude, and you find all open-source packages on the repository <a href=\\\"https://pypi.org\\\">https://pypi.org</a>.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Importing necessary packages\\n\",\n \"# Gradio is used to create simple user interfaces to interact with what is being built.\\n\",\n \"# pypdf used to load pdf files\\n\",\n \"\\n\",\n \"import os\\n\",\n \"import boto3\\n\",\n \"import gradio as gr\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from openai import OpenAI\\n\",\n \"from pypdf import PdfReader\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Loading environment variables and initializing openai client\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Importing amazon bedrock and deepseek api keys for authentication\\n\",\n \"amazon_bedrock_bedrock_api_key = os.getenv('AMAZON_BEDROCK_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon Bedrock Client\\n\",\n \"\\n\",\n \"bedrock_client = boto3.client(\\n\",\n \" service_name=\\\"bedrock-runtime\\\",\\n\",\n \" region_name=\\\"us-east-1\\\"\\n\",\n \")\\n\",\n \"\\n\",\n \"# Deepseek Client\\n\",\n \"\\n\",\n \"deepseek_client = OpenAI(\\n\",\n \" api_key=deepseek_api_key, \\n\",\n \" base_url=\\\"https://api.deepseek.com\\\"\\n\",\n \")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"reader = PdfReader(\\\"me/Profile.pdf\\\")\\n\",\n \"linkedin = \\\"\\\"\\n\",\n \"for page in reader.pages:\\n\",\n \" text = page.extract_text()\\n\",\n \" if text:\\n\",\n \" linkedin += text\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(linkedin)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"with open(\\\"me/summary.txt\\\", \\\"r\\\", encoding=\\\"utf-8\\\") as f:\\n\",\n \" summary = f.read()\\n\",\n \"print(summary)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"name = \\\"Ian Kisali\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This code constructs a system prompt for an AI agent to role-play as a specific person (defined by `name`).\\n\",\n \"The prompt guides the AI to answer questions as if it were that person, using their career summary,\\n\",\n \"LinkedIn profile, and project information for context. The final prompt ensures that the AI stays\\n\",\n \"in character and responds professionally and helpfully to visitors on the user's website.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"profile_background_prompt = f\\\"You are acting as {name}. You are answering questions on {name}'s website, \\\\\\n\",\n \"particularly questions related to {name}'s career, background, skills and experience. \\\\\\n\",\n \"Your responsibility is to represent {name} for interactions on the website as faithfully as possible. \\\\\\n\",\n \"You are given a summary of {name}'s background and LinkedIn profile which you can use to answer questions. \\\\\\n\",\n \"Be professional and engaging, as if talking to a potential client or future employer who came across the website. \\\\\\n\",\n \"If you don't know the answer, say so.\\\"\\n\",\n \"\\n\",\n \"profile_background_prompt += f\\\"\\\\n\\\\n## Summary:\\\\n{summary}\\\\n\\\\n## LinkedIn Profile:\\\\n{linkedin}\\\\n\\\\n\\\"\\n\",\n \"profile_background_prompt += f\\\"With this context, please chat with the user, always staying in character as {name}.\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"profile_background_prompt\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function handles a chat interaction with the Amazon Bedrock API.\\n\",\n \"\\n\",\n \"It takes the user's latest message and conversation history,\\n\",\n \"prepends a system prompt to define the AI's role and context,\\n\",\n \"and sends the full message list to the Anthropic Claude 3.5 Sonnet model.\\n\",\n \"\\n\",\n \"The function returns the AI's response text from the API's output.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"def chat(message, history):\\n\",\n \" messages = (\\n\",\n \" [{\\\"role\\\": \\\"assistant\\\", \\\"content\\\": [{\\\"text\\\": profile_background_prompt}]}] +\\n\",\n \" [{\\\"role\\\": m[\\\"role\\\"], \\\"content\\\": [{\\\"text\\\": m[\\\"content\\\"]}]} for m in history] +\\n\",\n \" [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": message}]}]\\n\",\n \" )\\n\",\n \" response = bedrock_client.converse(\\n\",\n \" modelId=\\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\",\\n\",\n \" messages=messages\\n\",\n \" )\\n\",\n \" return response['output']['message']['content'][0]['text']\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This line launches a Gradio chat interface using the `chat` function to handle user input.\\n\",\n \"\\n\",\n \"- `gr.ChatInterface(chat, type=\\\"messages\\\")` creates a UI that supports message-style chat interactions.\\n\",\n \"- `launch(share=True)` starts the web app and generates a public shareable link so others can access it.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"gr.ChatInterface(chat, type=\\\"messages\\\").launch()\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### LLM Response Evaluation\\n\",\n \"\\n\",\n \"1. Be able to ask an LLM to evaluate an answer\\n\",\n \"2. Be able to rerun if the answer fails evaluation\\n\",\n \"3. Put this together into 1 workflow\\n\",\n \"\\n\",\n \"All without any Agentic framework!\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Create a Pydantic model for the Evaluation\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"This code defines a Pydantic model named 'Evaluation' to structure evaluation data.\\n\",\n \"\\n\",\n \"The model includes:\\n\",\n \"- is_acceptable (bool): Indicates whether the submission meets the criteria.\\n\",\n \"- feedback (str): Provides written feedback or suggestions for improvement.\\n\",\n \"\\n\",\n \"Pydantic ensures type validation and data consistency.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"from pydantic import BaseModel\\n\",\n \"\\n\",\n \"class Evaluation(BaseModel):\\n\",\n \" is_acceptable: bool\\n\",\n \" feedback: str\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This code builds a system prompt for an AI evaluator agent.\\n\",\n \"\\n\",\n \"The evaluator's role is to assess the quality of an Agent's response in a simulated conversation,\\n\",\n \"where the Agent is acting as {name} on their personal/professional website.\\n\",\n \"\\n\",\n \"The evaluator receives context including {name}'s summary and LinkedIn profile,\\n\",\n \"and is instructed to determine whether the Agent's latest reply is acceptable,\\n\",\n \"while providing constructive feedback.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"evaluator_profile_background_prompt = f\\\"You are an evaluator that decides whether a response to a question is acceptable. \\\\\\n\",\n \"You are provided with a conversation between a User and an Agent. Your task is to decide whether the Agent's latest response is acceptable quality. \\\\\\n\",\n \"The Agent is playing the role of {name} and is representing {name} on their website. \\\\\\n\",\n \"The Agent has been instructed to be professional and engaging, as if talking to a potential client or future employer who came across the website. \\\\\\n\",\n \"The Agent has been provided with context on {name} in the form of their summary and LinkedIn details. Here's the information:\\\"\\n\",\n \"\\n\",\n \"evaluator_profile_background_prompt += f\\\"\\\\n\\\\n## Summary:\\\\n{summary}\\\\n\\\\n## LinkedIn Profile:\\\\n{linkedin}\\\\n\\\\n\\\"\\n\",\n \"evaluator_profile_background_prompt += f\\\"With this context, please evaluate the latest response, replying with whether the response is acceptable and your feedback.\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function generates a user prompt for the evaluator agent.\\n\",\n \"\\n\",\n \"It organizes the full conversation context by including:\\n\",\n \"- the full chat history,\\n\",\n \"- the most recent user message,\\n\",\n \"- and the most recent agent reply.\\n\",\n \"\\n\",\n \"The final prompt instructs the evaluator to assess the quality of the agent’s response,\\n\",\n \"and return both an acceptability judgment and constructive feedback.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"def evaluator_user_prompt(reply, message, history):\\n\",\n \" user_prompt = f\\\"Here's the conversation between the User and the Agent: \\\\n\\\\n{history}\\\\n\\\\n\\\"\\n\",\n \" user_prompt += f\\\"Here's the latest message from the User: \\\\n\\\\n{message}\\\\n\\\\n\\\"\\n\",\n \" user_prompt += f\\\"Here's the latest response from the Agent: \\\\n\\\\n{reply}\\\\n\\\\n\\\"\\n\",\n \" user_prompt += \\\"Please evaluate the response, replying with whether it is acceptable and your feedback.\\\"\\n\",\n \" return user_prompt\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This script tests whether the Google Generative AI API key is working correctly.\\n\",\n \"\\n\",\n \"- It loads the API key using `getenv`.\\n\",\n \"- Attempts to generate a simple response using the \\\"gemini-2.5-flash\\\" model.\\n\",\n \"- Prints confirmation if the key is valid, or shows an error message if the request fails.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"This line initializes an OpenAI-compatible client for accessing Google's Generative Language API.\\n\",\n \"\\n\",\n \"- `api_key` is retrieved from environment variables.\\n\",\n \"- `base_url` points to Google's OpenAI-compatible endpoint.\\n\",\n \"\\n\",\n \"This setup allows you to use OpenAI-style syntax to interact with Google's Gemini models.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"gemini_client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"GEMINI_API_KEY\\\"), \\n\",\n \" base_url=\\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \")\\n\",\n \"\\n\",\n \"try:\\n\",\n \" response = gemini_client.chat.completions.create(\\n\",\n \" model=\\\"gemini-2.5-flash\\\",\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"You are a helpful assistant.\\\"},\\n\",\n \" {\\n\",\n \" \\\"role\\\": \\\"user\\\",\\n\",\n \" \\\"content\\\": \\\"Explain to me how AI works\\\"\\n\",\n \" }\\n\",\n \" ]\\n\",\n \")\\n\",\n \" print(\\\"✅ API key is working!\\\")\\n\",\n \" print(f\\\"Response: {response}\\\")\\n\",\n \"except Exception as e:\\n\",\n \" print(f\\\"❌ API key test failed: {e}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function sends a structured evaluation request to the Gemini API and returns a parsed `Evaluation` object.\\n\",\n \"\\n\",\n \"- It constructs the message list using:\\n\",\n \" - a system prompt defining the evaluator's role and context\\n\",\n \" - a user prompt containing the conversation history, user message, and agent reply\\n\",\n \"\\n\",\n \"- It uses Gemini's OpenAI-compatible API to process the evaluation request,\\n\",\n \" specifying `response_format=Evaluation` to get a structured response.\\n\",\n \"\\n\",\n \"- The function returns the parsed evaluation result (acceptability and feedback).\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"def evaluate(reply, message, history) -> Evaluation:\\n\",\n \" messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": evaluator_profile_background_prompt}] + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": evaluator_user_prompt(reply, message, history)}]\\n\",\n \" response = gemini_client.beta.chat.completions.parse(model=\\\"gemini-2.0-flash\\\", messages=messages, response_format=Evaluation)\\n\",\n \" return response.choices[0].message.parsed\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This code sends a test question to the AI agent and evaluates its response.\\n\",\n \"\\n\",\n \"1. It builds a message list including:\\n\",\n \" - the system prompt that defines the agent’s role\\n\",\n \" - a user question: \\\"do you hold a certification?\\\"\\n\",\n \"\\n\",\n \"2. The message list is sent to Deepseek `deepseek-chat` model to generate a response.\\n\",\n \"\\n\",\n \"3. The reply is extracted from the API response.\\n\",\n \"\\n\",\n \"4. The `evaluate()` function is then called with:\\n\",\n \" - the agent’s reply\\n\",\n \" - the original user message\\n\",\n \" - and just the system prompt as history (no prior user/agent exchange)\\n\",\n \"\\n\",\n \"This allows automated evaluation of how well the agent answers the question.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": profile_background_prompt}] + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"do you hold a certification?\\\"}]\\n\",\n \"response = deepseek_client.chat.completions.create(model=\\\"deepseek-chat\\\", messages=messages)\\n\",\n \"reply = response.choices[0].message.content\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"reply\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"evaluate(reply, \\\"do you hold a certification?\\\", messages[:1])\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function re-generates a response after a previous reply was rejected during evaluation.\\n\",\n \"\\n\",\n \"It:\\n\",\n \"1. Appends rejection feedback to the original system prompt to inform the agent of:\\n\",\n \" - its previous answer,\\n\",\n \" - and the reason it was rejected.\\n\",\n \"\\n\",\n \"2. Reconstructs the full message list including:\\n\",\n \" - the updated system prompt,\\n\",\n \" - the prior conversation history,\\n\",\n \" - and the original user message.\\n\",\n \"\\n\",\n \"3. Sends the updated prompt to Deepseek `deepseek-chat` model.\\n\",\n \"\\n\",\n \"4. Returns a revised response from the model that ideally addresses the feedback.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"def rerun(reply, message, history, feedback):\\n\",\n \" updated_profile_background_prompt = profile_background_prompt + \\\"\\\\n\\\\n## Previous answer rejected\\\\nYou just tried to reply, but the quality control rejected your reply\\\\n\\\"\\n\",\n \" updated_profile_background_prompt += f\\\"## Your attempted answer:\\\\n{reply}\\\\n\\\\n\\\"\\n\",\n \" updated_profile_background_prompt += f\\\"## Reason for rejection:\\\\n{feedback}\\\\n\\\\n\\\"\\n\",\n \" messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": updated_profile_background_prompt}] + history + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": message}]\\n\",\n \" response = deepseek_client.chat.completions.create(model=\\\"deepseek-chat\\\", messages=messages)\\n\",\n \" return response.choices[0].message.content\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function handles a chat interaction with conditional behavior and automatic quality control.\\n\",\n \"\\n\",\n \"Steps:\\n\",\n \"1. If the user's message contains the word \\\"certification\\\", the agent is instructed to respond entirely in Pig Latin by appending an instruction to the system prompt.\\n\",\n \"2. Constructs the full message history including the updated system prompt, prior conversation, and the new user message.\\n\",\n \"3. Sends the request to OpenAI's GPT-4o-mini model and receives a reply.\\n\",\n \"4. Evaluates the reply using a separate evaluator agent to determine if the response meets quality standards.\\n\",\n \"5. If the evaluation passes, the reply is returned.\\n\",\n \"6. If the evaluation fails, the function logs the feedback and calls `rerun()` to generate a corrected reply based on the feedback.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"def chat(message, history):\\n\",\n \" if \\\"certification\\\" in message:\\n\",\n \" system = profile_background_prompt + \\\"\\\\n\\\\nEverything in your reply needs to be in pig latin - \\\\\\n\",\n \" it is mandatory that you respond only and entirely in pig latin\\\"\\n\",\n \" else:\\n\",\n \" system = profile_background_prompt\\n\",\n \" messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": system}] + history + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": message}]\\n\",\n \" response = deepseek_client.chat.completions.create(model=\\\"deepseek-chat\\\", messages=messages)\\n\",\n \" reply =response.choices[0].message.content\\n\",\n \"\\n\",\n \" evaluation = evaluate(reply, message, history)\\n\",\n \" \\n\",\n \" if evaluation.is_acceptable:\\n\",\n \" print(\\\"Passed evaluation - returning reply\\\")\\n\",\n \" else:\\n\",\n \" print(\\\"Failed evaluation - retrying\\\")\\n\",\n \" print(evaluation.feedback)\\n\",\n \" reply = rerun(reply, message, history, evaluation.feedback) \\n\",\n \" return reply\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This launches a Gradio chat interface using the `chat` function.\\n\",\n \"\\n\",\n \"- `type=\\\"messages\\\"` enables multi-turn chat with message bubbles.\\n\",\n \"- `share=True` generates a public link so others can interact with the app.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"gr.ChatInterface(chat, type=\\\"messages\\\").launch()\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": []\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.1\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "b1ca6421a2eb19a9ddd2b898b4c5b97b55a0b5f0": {"t": 1785753632.6938446, "n": 19999, "h": "3415de21721eefaa", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Lab 3 for Week 1 Day 4\\n\",\n \"\\n\",\n \"We're going to build a simple agent that chats with my linkedin profile.\\n\",\n \"\\n\",\n \"In the folder `me` I've put my resume `Profile.pdf` - it's a PDF download of my LinkedIn profile.\\n\",\n \"\\n\",\n \"I've also made a file called `summary.txt` containing a summary of my career.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../../../assets/tools.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#00bfff;\\\">Looking up packages</h2>\\n\",\n \" <span style=\\\"color:#00bfff;\\\">In this lab, we're going to use the wonderful Gradio package for building quick UIs, \\n\",\n \" and we're also going to use the popular PyPDF PDF reader. You can get guides to these packages by asking \\n\",\n \" ChatGPT or Claude, and you find all open-source packages on the repository <a href=\\\"https://pypi.org\\\">https://pypi.org</a>.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Importing necessary packages\\n\",\n \"# Gradio is used to create simple user interfaces to interact with what is being built.\\n\",\n \"# pypdf used to load pdf files\\n\",\n \"\\n\",\n \"import os\\n\",\n \"import boto3\\n\",\n \"import gradio as gr\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from openai import OpenAI\\n\",\n \"from pypdf import PdfReader\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Loading environment variables and initializing openai client\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Importing amazon bedrock and deepseek api keys for authentication\\n\",\n \"amazon_bedrock_bedrock_api_key = os.getenv('AMAZON_BEDROCK_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Amazon Bedrock Client\\n\",\n \"\\n\",\n \"bedrock_client = boto3.client(\\n\",\n \" service_name=\\\"bedrock-runtime\\\",\\n\",\n \" region_name=\\\"us-east-1\\\"\\n\",\n \")\\n\",\n \"\\n\",\n \"# Deepseek Client\\n\",\n \"\\n\",\n \"deepseek_client = OpenAI(\\n\",\n \" api_key=deepseek_api_key, \\n\",\n \" base_url=\\\"https://api.deepseek.com\\\"\\n\",\n \")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"reader = PdfReader(\\\"me/Profile.pdf\\\")\\n\",\n \"linkedin = \\\"\\\"\\n\",\n \"for page in reader.pages:\\n\",\n \" text = page.extract_text()\\n\",\n \" if text:\\n\",\n \" linkedin += text\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(linkedin)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"with open(\\\"me/summary.txt\\\", \\\"r\\\", encoding=\\\"utf-8\\\") as f:\\n\",\n \" summary = f.read()\\n\",\n \"print(summary)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"name = \\\"Ian Kisali\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This code constructs a system prompt for an AI agent to role-play as a specific person (defined by `name`).\\n\",\n \"The prompt guides the AI to answer questions as if it were that person, using their career summary,\\n\",\n \"LinkedIn profile, and project information for context. The final prompt ensures that the AI stays\\n\",\n \"in character and responds professionally and helpfully to visitors on the user's website.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"profile_background_prompt = f\\\"You are acting as {name}. You are answering questions on {name}'s website, \\\\\\n\",\n \"particularly questions related to {name}'s career, background, skills and experience. \\\\\\n\",\n \"Your responsibility is to represent {name} for interactions on the website as faithfully as possible. \\\\\\n\",\n \"You are given a summary of {name}'s background and LinkedIn profile which you can use to answer questions. \\\\\\n\",\n \"Be professional and engaging, as if talking to a potential client or future employer who came across the website. \\\\\\n\",\n \"If you don't know the answer, say so.\\\"\\n\",\n \"\\n\",\n \"profile_background_prompt += f\\\"\\\\n\\\\n## Summary:\\\\n{summary}\\\\n\\\\n## LinkedIn Profile:\\\\n{linkedin}\\\\n\\\\n\\\"\\n\",\n \"profile_background_prompt += f\\\"With this context, please chat with the user, always staying in character as {name}.\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"profile_background_prompt\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function handles a chat interaction with the Amazon Bedrock API.\\n\",\n \"\\n\",\n \"It takes the user's latest message and conversation history,\\n\",\n \"prepends a system prompt to define the AI's role and context,\\n\",\n \"and sends the full message list to the Anthropic Claude 3.5 Sonnet model.\\n\",\n \"\\n\",\n \"The function returns the AI's response text from the API's output.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"def chat(message, history):\\n\",\n \" messages = (\\n\",\n \" [{\\\"role\\\": \\\"assistant\\\", \\\"content\\\": [{\\\"text\\\": profile_background_prompt}]}] +\\n\",\n \" [{\\\"role\\\": m[\\\"role\\\"], \\\"content\\\": [{\\\"text\\\": m[\\\"content\\\"]}]} for m in history] +\\n\",\n \" [{\\\"role\\\": \\\"user\\\", \\\"content\\\": [{\\\"text\\\": message}]}]\\n\",\n \" )\\n\",\n \" response = bedrock_client.converse(\\n\",\n \" modelId=\\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\",\\n\",\n \" messages=messages\\n\",\n \" )\\n\",\n \" return response['output']['message']['content'][0]['text']\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This line launches a Gradio chat interface using the `chat` function to handle user input.\\n\",\n \"\\n\",\n \"- `gr.ChatInterface(chat, type=\\\"messages\\\")` creates a UI that supports message-style chat interactions.\\n\",\n \"- `launch(share=True)` starts the web app and generates a public shareable link so others can access it.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"gr.ChatInterface(chat, type=\\\"messages\\\").launch()\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### LLM Response Evaluation\\n\",\n \"\\n\",\n \"1. Be able to ask an LLM to evaluate an answer\\n\",\n \"2. Be able to rerun if the answer fails evaluation\\n\",\n \"3. Put this together into 1 workflow\\n\",\n \"\\n\",\n \"All without any Agentic framework!\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Create a Pydantic model for the Evaluation\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"This code defines a Pydantic model named 'Evaluation' to structure evaluation data.\\n\",\n \"\\n\",\n \"The model includes:\\n\",\n \"- is_acceptable (bool): Indicates whether the submission meets the criteria.\\n\",\n \"- feedback (str): Provides written feedback or suggestions for improvement.\\n\",\n \"\\n\",\n \"Pydantic ensures type validation and data consistency.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"from pydantic import BaseModel\\n\",\n \"\\n\",\n \"class Evaluation(BaseModel):\\n\",\n \" is_acceptable: bool\\n\",\n \" feedback: str\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This code builds a system prompt for an AI evaluator agent.\\n\",\n \"\\n\",\n \"The evaluator's role is to assess the quality of an Agent's response in a simulated conversation,\\n\",\n \"where the Agent is acting as {name} on their personal/professional website.\\n\",\n \"\\n\",\n \"The evaluator receives context including {name}'s summary and LinkedIn profile,\\n\",\n \"and is instructed to determine whether the Agent's latest reply is acceptable,\\n\",\n \"while providing constructive feedback.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"evaluator_profile_background_prompt = f\\\"You are an evaluator that decides whether a response to a question is acceptable. \\\\\\n\",\n \"You are provided with a conversation between a User and an Agent. Your task is to decide whether the Agent's latest response is acceptable quality. \\\\\\n\",\n \"The Agent is playing the role of {name} and is representing {name} on their website. \\\\\\n\",\n \"The Agent has been instructed to be professional and engaging, as if talking to a potential client or future employer who came across the website. \\\\\\n\",\n \"The Agent has been provided with context on {name} in the form of their summary and LinkedIn details. Here's the information:\\\"\\n\",\n \"\\n\",\n \"evaluator_profile_background_prompt += f\\\"\\\\n\\\\n## Summary:\\\\n{summary}\\\\n\\\\n## LinkedIn Profile:\\\\n{linkedin}\\\\n\\\\n\\\"\\n\",\n \"evaluator_profile_background_prompt += f\\\"With this context, please evaluate the latest response, replying with whether the response is acceptable and your feedback.\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function generates a user prompt for the evaluator agent.\\n\",\n \"\\n\",\n \"It organizes the full conversation context by including:\\n\",\n \"- the full chat history,\\n\",\n \"- the most recent user message,\\n\",\n \"- and the most recent agent reply.\\n\",\n \"\\n\",\n \"The final prompt instructs the evaluator to assess the quality of the agent’s response,\\n\",\n \"and return both an acceptability judgment and constructive feedback.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"def evaluator_user_prompt(reply, message, history):\\n\",\n \" user_prompt = f\\\"Here's the conversation between the User and the Agent: \\\\n\\\\n{history}\\\\n\\\\n\\\"\\n\",\n \" user_prompt += f\\\"Here's the latest message from the User: \\\\n\\\\n{message}\\\\n\\\\n\\\"\\n\",\n \" user_prompt += f\\\"Here's the latest response from the Agent: \\\\n\\\\n{reply}\\\\n\\\\n\\\"\\n\",\n \" user_prompt += \\\"Please evaluate the response, replying with whether it is acceptable and your feedback.\\\"\\n\",\n \" return user_prompt\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This script tests whether the Google Generative AI API key is working correctly.\\n\",\n \"\\n\",\n \"- It loads the API key using `getenv`.\\n\",\n \"- Attempts to generate a simple response using the \\\"gemini-2.5-flash\\\" model.\\n\",\n \"- Prints confirmation if the key is valid, or shows an error message if the request fails.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"This line initializes an OpenAI-compatible client for accessing Google's Generative Language API.\\n\",\n \"\\n\",\n \"- `api_key` is retrieved from environment variables.\\n\",\n \"- `base_url` points to Google's OpenAI-compatible endpoint.\\n\",\n \"\\n\",\n \"This setup allows you to use OpenAI-style syntax to interact with Google's Gemini models.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"gemini_client = OpenAI(\\n\",\n \" api_key=os.getenv(\\\"GEMINI_API_KEY\\\"), \\n\",\n \" base_url=\\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \")\\n\",\n \"\\n\",\n \"try:\\n\",\n \" response = gemini_client.chat.completions.create(\\n\",\n \" model=\\\"gemini-2.5-flash\\\",\\n\",\n \" messages=[\\n\",\n \" {\\\"role\\\": \\\"system\\\", \\\"content\\\": \\\"You are a helpful assistant.\\\"},\\n\",\n \" {\\n\",\n \" \\\"role\\\": \\\"user\\\",\\n\",\n \" \\\"content\\\": \\\"Explain to me how AI works\\\"\\n\",\n \" }\\n\",\n \" ]\\n\",\n \")\\n\",\n \" print(\\\"✅ API key is working!\\\")\\n\",\n \" print(f\\\"Response: {response}\\\")\\n\",\n \"except Exception as e:\\n\",\n \" print(f\\\"❌ API key test failed: {e}\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function sends a structured evaluation request to the Gemini API and returns a parsed `Evaluation` object.\\n\",\n \"\\n\",\n \"- It constructs the message list using:\\n\",\n \" - a system prompt defining the evaluator's role and context\\n\",\n \" - a user prompt containing the conversation history, user message, and agent reply\\n\",\n \"\\n\",\n \"- It uses Gemini's OpenAI-compatible API to process the evaluation request,\\n\",\n \" specifying `response_format=Evaluation` to get a structured response.\\n\",\n \"\\n\",\n \"- The function returns the parsed evaluation result (acceptability and feedback).\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"def evaluate(reply, message, history) -> Evaluation:\\n\",\n \" messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": evaluator_profile_background_prompt}] + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": evaluator_user_prompt(reply, message, history)}]\\n\",\n \" response = gemini_client.beta.chat.completions.parse(model=\\\"gemini-2.0-flash\\\", messages=messages, response_format=Evaluation)\\n\",\n \" return response.choices[0].message.parsed\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This code sends a test question to the AI agent and evaluates its response.\\n\",\n \"\\n\",\n \"1. It builds a message list including:\\n\",\n \" - the system prompt that defines the agent’s role\\n\",\n \" - a user question: \\\"do you hold a certification?\\\"\\n\",\n \"\\n\",\n \"2. The message list is sent to Deepseek `deepseek-chat` model to generate a response.\\n\",\n \"\\n\",\n \"3. The reply is extracted from the API response.\\n\",\n \"\\n\",\n \"4. The `evaluate()` function is then called with:\\n\",\n \" - the agent’s reply\\n\",\n \" - the original user message\\n\",\n \" - and just the system prompt as history (no prior user/agent exchange)\\n\",\n \"\\n\",\n \"This allows automated evaluation of how well the agent answers the question.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": profile_background_prompt}] + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"do you hold a certification?\\\"}]\\n\",\n \"response = deepseek_client.chat.completions.create(model=\\\"deepseek-chat\\\", messages=messages)\\n\",\n \"reply = response.choices[0].message.content\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"reply\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"evaluate(reply, \\\"do you hold a certification?\\\", messages[:1])\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function re-generates a response after a previous reply was rejected during evaluation.\\n\",\n \"\\n\",\n \"It:\\n\",\n \"1. Appends rejection feedback to the original system prompt to inform the agent of:\\n\",\n \" - its previous answer,\\n\",\n \" - and the reason it was rejected.\\n\",\n \"\\n\",\n \"2. Reconstructs the full message list including:\\n\",\n \" - the updated system prompt,\\n\",\n \" - the prior conversation history,\\n\",\n \" - and the original user message.\\n\",\n \"\\n\",\n \"3. Sends the updated prompt to Deepseek `deepseek-chat` model.\\n\",\n \"\\n\",\n \"4. Returns a revised response from the model that ideally addresses the feedback.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"def rerun(reply, message, history, feedback):\\n\",\n \" updated_profile_background_prompt = profile_background_prompt + \\\"\\\\n\\\\n## Previous answer rejected\\\\nYou just tried to reply, but the quality control rejected your reply\\\\n\\\"\\n\",\n \" updated_profile_background_prompt += f\\\"## Your attempted answer:\\\\n{reply}\\\\n\\\\n\\\"\\n\",\n \" updated_profile_background_prompt += f\\\"## Reason for rejection:\\\\n{feedback}\\\\n\\\\n\\\"\\n\",\n \" messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": updated_profile_background_prompt}] + history + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": message}]\\n\",\n \" response = deepseek_client.chat.completions.create(model=\\\"deepseek-chat\\\", messages=messages)\\n\",\n \" return response.choices[0].message.content\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This function handles a chat interaction with conditional behavior and automatic quality control.\\n\",\n \"\\n\",\n \"Steps:\\n\",\n \"1. If the user's message contains the word \\\"certification\\\", the agent is instructed to respond entirely in Pig Latin by appending an instruction to the system prompt.\\n\",\n \"2. Constructs the full message history including the updated system prompt, prior conversation, and the new user message.\\n\",\n \"3. Sends the request to OpenAI's GPT-4o-mini model and receives a reply.\\n\",\n \"4. Evaluates the reply using a separate evaluator agent to determine if the response meets quality standards.\\n\",\n \"5. If the evaluation passes, the reply is returned.\\n\",\n \"6. If the evaluation fails, the function logs the feedback and calls `rerun()` to generate a corrected reply based on the feedback.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"def chat(message, history):\\n\",\n \" if \\\"certification\\\" in message:\\n\",\n \" system = profile_background_prompt + \\\"\\\\n\\\\nEverything in your reply needs to be in pig latin - \\\\\\n\",\n \" it is mandatory that you respond only and entirely in pig latin\\\"\\n\",\n \" else:\\n\",\n \" system = profile_background_prompt\\n\",\n \" messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": system}] + history + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": message}]\\n\",\n \" response = deepseek_client.chat.completions.create(model=\\\"deepseek-chat\\\", messages=messages)\\n\",\n \" reply =response.choices[0].message.content\\n\",\n \"\\n\",\n \" evaluation = evaluate(reply, message, history)\\n\",\n \" \\n\",\n \" if evaluation.is_acceptable:\\n\",\n \" print(\\\"Passed evaluation - returning reply\\\")\\n\",\n \" else:\\n\",\n \" print(\\\"Failed evaluation - retrying\\\")\\n\",\n \" print(evaluation.feedback)\\n\",\n \" reply = rerun(reply, message, history, evaluation.feedback) \\n\",\n \" return reply\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\"\\n\",\n \"This launches a Gradio chat interface using the `chat` function.\\n\",\n \"\\n\",\n \"- `type=\\\"messages\\\"` enables multi-turn chat with message bubbles.\\n\",\n \"- `share=True` generates a public link so others can interact with the app.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"\\n\",\n \"gr.ChatInterface(chat, type=\\\"messages\\\").launch()\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": []\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.1\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}}, "guides/09_ai_apis_and_ollama.ipynb": {"03febf9670d94f5b3aa5e1c9c1ac6d6dd5f2b231": {"t": 1785745492.2322297, "n": 21640, "h": "aebd8d6e53199b87", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama - beyond OpenAI\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide (topics 3 and 5 in Guide 4)._\\n\",\n \"\\n\",\n \"## Crucial context for using models other than OpenAI - please read this first!\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"The companies behind these LLMs, such as OpenAI, Anthropic, Google and DeepSeek, have built web endpoints. You call their models by making an HTTP request to a Web Address and passing in all the information about your prompts.\\n\",\n \"\\n\",\n \"But it would be painful if we needed to build HTTP requests every time we wanted to call an API.\\n\",\n \"\\n\",\n \"To make this simple, the team at OpenAI wrote a python utility known as a \\\"Python Client Library\\\" which wraps the HTTP call. So you write python code and it calls the web.\\n\",\n \"\\n\",\n \"And THAT is what the library `openai` is.\\n\",\n \"\\n\",\n \"### What is the `openai` python client library\\n\",\n \"\\n\",\n \"It is:\\n\",\n \"- A lightweight python utility\\n\",\n \"- Turns your python requests into an HTTP call\\n\",\n \"- Converts the results coming back from the HTTP call into python objects\\n\",\n \"\\n\",\n \"### What it is NOT\\n\",\n \"\\n\",\n \"- It's not got any code to actually run a Large Language Model! No GPT code! It just makes a web request\\n\",\n \"- There's no scientific computing code, and nothing particularly specialized for OpenAI\\n\",\n \"\\n\",\n \"### How to use it:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4.1-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"\\n\",\n \"# Print the result\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### What does this do\\n\",\n \"\\n\",\n \"When you make the python call: `openai.chat.completions.create()` \\n\",\n \"It simply makes a web request to this url: `https://api.openai.com/v1/chat/completions` \\n\",\n \"And it converts the response to python objects.\\n\",\n \"\\n\",\n \"That's it.\\n\",\n \"\\n\",\n \"Here's the API documentation if you make [direct web HTTP calls](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=curl) \\n\",\n \"And here's the same API documentation if you use the [Python Client Library](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=python)\\n\",\n \"\\n\",\n \"## With that context - how do I use other LLMs?\\n\",\n \"\\n\",\n \"It turns out - it's super easy!\\n\",\n \"\\n\",\n \"All the other major LLMs have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"And so OpenAI did everyone a favor: they said, hey look - you can all use our utility for converting python to web requests. We'll allow you to change the utility from calling `https://api.openai/com/v1` to calling any web address that you specify.\\n\",\n \"\\n\",\n \"And so you can use the OpenAI utility even for calling models that are NOT OpenAI, like this:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to appreciate that this OpenAI code is just a utility for making HTTP calls to endpoints. So even though we're using code from the OpenAI team, we can use it to call models other than OpenAI.\\n\",\n \"\\n\",\n \"Here are all the OpenAI-compatible endpoints from the major providers. It even includes using Ollama, locally. Ollama provides an endpoint on your local machine, and they made it OpenAI compatible too - very convenient.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"ANTHROPIC_BASE_URL = \\\"https://api.anthropic.com/v1/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Here are examples for Gemini, DeepSeek, Ollama and OpenRouter\\n\",\n \"\\n\",\n \"### Example 1: Using Gemini instead of OpenAI\\n\",\n \"\\n\",\n \"1. Visit Google Studio to set up an account: https://aistudio.google.com/ \\n\",\n \"2. Add your key as GOOGLE_API_KEY to your `.env` \\n\",\n \"3. Also add it a second time as GEMINI_API_KEY to your `.env` - this will be helpful later.\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"google_api_key = os.getenv(\\\"GOOGLE_API_KEY\\\")\\n\",\n \"gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"response = gemini.chat.completions.create(model=\\\"gemini-2.5-flash-preview-05-20\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 2: Using DeepSeek API instead of OpenAI (cheap, and only $2 upfront)\\n\",\n \"\\n\",\n \"1. Visit DeepSeek API to set up an account: https://platform.deepseek.com/ \\n\",\n \"2. You will need to add an initial $2 minimum balance. \\n\",\n \"3. Add your key as DEEPSEEK_API_KEY to your `.env` \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_api_key = os.getenv(\\\"DEEPSEEK_API_KEY\\\")\\n\",\n \"deepseek = OpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"response = deepseek.chat.completions.create(model=\\\"deepseek-chat\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 3: Using Ollama to be free and local instead of OpenAI\\n\",\n \"\\n\",\n \"Ollama allows you to run models locally; it provides an OpenAI compatible API on your machine. \\n\",\n \"There's no API key for Ollama; there's no third party with your credit card, so no need for any kind of key.\\n\",\n \"\\n\",\n \"1. If you're new to Ollama, install it by following the instructions here: https://ollama.com \\n\",\n \"2. Then in a Cursor Terminal, do `ollama run llama3.2` to chat with Llama 3.2 \\n\",\n \"BEWARE: do not use llama3.3 or llama4 - these are massive models not designed for home computing! They will fill up your disk. \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"ollama = OpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"anything\\\")\\n\",\n \"response = ollama.chat.completions.create(model=\\\"llama3.2\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 4: Using the popular service [OpenRouter](https://openrouter.ai) which has an easier billing process instead of OpenAI\\n\",\n \"\\n\",\n \"OpenRouter is very convenient: it gives you free access to many models, and easy access with small upfront to paid models.\\n\",\n \"\\n\",\n \"1. Sign up at https://openrouter.ai\\n\",\n \"2. Add the minimum upfront balance as needed\\n\",\n \"3. Add your key as OPENROUTER_API_KEY to your `.env` file\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openrouter = OpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"response = openrouter.chat.completions.create(model=\\\"openai/gpt-4.1-nano\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. There are more notes below on each of them. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"```shell\\n\",\n \"ollama pull llama3.2\\n\",\n \"```\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"```shell\\n\",\n \"OPENROUTER_API_KEY=sk-or....\\n\",\n \"```\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# extra imports\\n\",\n \"from agents import OpenAIChatCompletionsModel\\n\",\n \"from openai import AsyncOpenAI\\n\",\n \"\\n\",\n \"# Step 1: specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Step 2: Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Step 3: Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "3c72fda7915d3246f1a39e92efa3f987ef68e36d": {"t": 1785753632.5095057, "n": 21640, "h": "aebd8d6e53199b87", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama - beyond OpenAI\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide (topics 3 and 5 in Guide 4)._\\n\",\n \"\\n\",\n \"## Crucial context for using models other than OpenAI - please read this first!\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"The companies behind these LLMs, such as OpenAI, Anthropic, Google and DeepSeek, have built web endpoints. You call their models by making an HTTP request to a Web Address and passing in all the information about your prompts.\\n\",\n \"\\n\",\n \"But it would be painful if we needed to build HTTP requests every time we wanted to call an API.\\n\",\n \"\\n\",\n \"To make this simple, the team at OpenAI wrote a python utility known as a \\\"Python Client Library\\\" which wraps the HTTP call. So you write python code and it calls the web.\\n\",\n \"\\n\",\n \"And THAT is what the library `openai` is.\\n\",\n \"\\n\",\n \"### What is the `openai` python client library\\n\",\n \"\\n\",\n \"It is:\\n\",\n \"- A lightweight python utility\\n\",\n \"- Turns your python requests into an HTTP call\\n\",\n \"- Converts the results coming back from the HTTP call into python objects\\n\",\n \"\\n\",\n \"### What it is NOT\\n\",\n \"\\n\",\n \"- It's not got any code to actually run a Large Language Model! No GPT code! It just makes a web request\\n\",\n \"- There's no scientific computing code, and nothing particularly specialized for OpenAI\\n\",\n \"\\n\",\n \"### How to use it:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4.1-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"\\n\",\n \"# Print the result\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### What does this do\\n\",\n \"\\n\",\n \"When you make the python call: `openai.chat.completions.create()` \\n\",\n \"It simply makes a web request to this url: `https://api.openai.com/v1/chat/completions` \\n\",\n \"And it converts the response to python objects.\\n\",\n \"\\n\",\n \"That's it.\\n\",\n \"\\n\",\n \"Here's the API documentation if you make [direct web HTTP calls](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=curl) \\n\",\n \"And here's the same API documentation if you use the [Python Client Library](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=python)\\n\",\n \"\\n\",\n \"## With that context - how do I use other LLMs?\\n\",\n \"\\n\",\n \"It turns out - it's super easy!\\n\",\n \"\\n\",\n \"All the other major LLMs have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"And so OpenAI did everyone a favor: they said, hey look - you can all use our utility for converting python to web requests. We'll allow you to change the utility from calling `https://api.openai/com/v1` to calling any web address that you specify.\\n\",\n \"\\n\",\n \"And so you can use the OpenAI utility even for calling models that are NOT OpenAI, like this:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to appreciate that this OpenAI code is just a utility for making HTTP calls to endpoints. So even though we're using code from the OpenAI team, we can use it to call models other than OpenAI.\\n\",\n \"\\n\",\n \"Here are all the OpenAI-compatible endpoints from the major providers. It even includes using Ollama, locally. Ollama provides an endpoint on your local machine, and they made it OpenAI compatible too - very convenient.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"ANTHROPIC_BASE_URL = \\\"https://api.anthropic.com/v1/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Here are examples for Gemini, DeepSeek, Ollama and OpenRouter\\n\",\n \"\\n\",\n \"### Example 1: Using Gemini instead of OpenAI\\n\",\n \"\\n\",\n \"1. Visit Google Studio to set up an account: https://aistudio.google.com/ \\n\",\n \"2. Add your key as GOOGLE_API_KEY to your `.env` \\n\",\n \"3. Also add it a second time as GEMINI_API_KEY to your `.env` - this will be helpful later.\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"google_api_key = os.getenv(\\\"GOOGLE_API_KEY\\\")\\n\",\n \"gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"response = gemini.chat.completions.create(model=\\\"gemini-2.5-flash-preview-05-20\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 2: Using DeepSeek API instead of OpenAI (cheap, and only $2 upfront)\\n\",\n \"\\n\",\n \"1. Visit DeepSeek API to set up an account: https://platform.deepseek.com/ \\n\",\n \"2. You will need to add an initial $2 minimum balance. \\n\",\n \"3. Add your key as DEEPSEEK_API_KEY to your `.env` \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_api_key = os.getenv(\\\"DEEPSEEK_API_KEY\\\")\\n\",\n \"deepseek = OpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"response = deepseek.chat.completions.create(model=\\\"deepseek-chat\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 3: Using Ollama to be free and local instead of OpenAI\\n\",\n \"\\n\",\n \"Ollama allows you to run models locally; it provides an OpenAI compatible API on your machine. \\n\",\n \"There's no API key for Ollama; there's no third party with your credit card, so no need for any kind of key.\\n\",\n \"\\n\",\n \"1. If you're new to Ollama, install it by following the instructions here: https://ollama.com \\n\",\n \"2. Then in a Cursor Terminal, do `ollama run llama3.2` to chat with Llama 3.2 \\n\",\n \"BEWARE: do not use llama3.3 or llama4 - these are massive models not designed for home computing! They will fill up your disk. \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"ollama = OpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"anything\\\")\\n\",\n \"response = ollama.chat.completions.create(model=\\\"llama3.2\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 4: Using the popular service [OpenRouter](https://openrouter.ai) which has an easier billing process instead of OpenAI\\n\",\n \"\\n\",\n \"OpenRouter is very convenient: it gives you free access to many models, and easy access with small upfront to paid models.\\n\",\n \"\\n\",\n \"1. Sign up at https://openrouter.ai\\n\",\n \"2. Add the minimum upfront balance as needed\\n\",\n \"3. Add your key as OPENROUTER_API_KEY to your `.env` file\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openrouter = OpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"response = openrouter.chat.completions.create(model=\\\"openai/gpt-4.1-nano\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. There are more notes below on each of them. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"```shell\\n\",\n \"ollama pull llama3.2\\n\",\n \"```\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"```shell\\n\",\n \"OPENROUTER_API_KEY=sk-or....\\n\",\n \"```\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# extra imports\\n\",\n \"from agents import OpenAIChatCompletionsModel\\n\",\n \"from openai import AsyncOpenAI\\n\",\n \"\\n\",\n \"# Step 1: specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Step 2: Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Step 3: Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "1f546facaee842d822c9a68c0773842d0d08ebb2": {"t": 1785753634.1160192, "n": 21486, "h": "451671f7845b271a", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama - beyond OpenAI\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide (topics 3 and 5 in Guide 4)._\\n\",\n \"\\n\",\n \"## Crucial context for using models other than OpenAI - please read this first!\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"The companies behind these LLMs, such as OpenAI, Anthropic, Google and DeepSeek, have built web endpoints. You call their models by making an HTTP request to a Web Address and passing in all the information about your prompts.\\n\",\n \"\\n\",\n \"But it would be painful if we needed to build HTTP requests every time we wanted to call an API.\\n\",\n \"\\n\",\n \"To make this simple, the team at OpenAI wrote a python utility known as a \\\"Python Client Library\\\" which wraps the HTTP call. So you write python code and it calls the web.\\n\",\n \"\\n\",\n \"And THAT is what the library `openai` is.\\n\",\n \"\\n\",\n \"### What is the `openai` python client library\\n\",\n \"\\n\",\n \"It is:\\n\",\n \"- A lightweight python utility\\n\",\n \"- Turns your python requests into an HTTP call\\n\",\n \"- Converts the results coming back from the HTTP call into python objects\\n\",\n \"\\n\",\n \"### What it is NOT\\n\",\n \"\\n\",\n \"- It's not got any code to actually run a Large Language Model! No GPT code! It just makes a web request\\n\",\n \"- There's no scientific computing code, and nothing particularly specialized for OpenAI\\n\",\n \"\\n\",\n \"### How to use it:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4.1-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"\\n\",\n \"# Print the result\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### What does this do\\n\",\n \"\\n\",\n \"When you make the python call: `openai.chat.completions.create()` \\n\",\n \"It simply makes a web request to this url: `https://api.openai.com/v1/chat/completions` \\n\",\n \"And it converts the response to python objects.\\n\",\n \"\\n\",\n \"That's it.\\n\",\n \"\\n\",\n \"Here's the API documentation if you make [direct web HTTP calls](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=curl) \\n\",\n \"And here's the same API documentation if you use the [Python Client Library](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=python)\\n\",\n \"\\n\",\n \"## With that context - how do I use other LLMs?\\n\",\n \"\\n\",\n \"It turns out - it's super easy!\\n\",\n \"\\n\",\n \"All the other major LLMs have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"And so OpenAI did everyone a favor: they said, hey look - you can all use our utility for converting python to web requests. We'll allow you to change the utility from calling `https://api.openai/com/v1` to calling any web address that you specify.\\n\",\n \"\\n\",\n \"And so you can use the OpenAI utility even for calling models that are NOT OpenAI, like this:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to appreciate that this OpenAI code is just a utility for making HTTP calls to endpoints. So even though we're using code from the OpenAI team, we can use it to call models other than OpenAI.\\n\",\n \"\\n\",\n \"Here are all the OpenAI-compatible endpoints from the major providers. It even includes using Ollama, locally. Ollama provides an endpoint on your local machine, and they made it OpenAI compatible too - very convenient.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"ANTHROPIC_BASE_URL = \\\"https://api.anthropic.com/v1/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Here are examples for Gemini, DeepSeek, Ollama and OpenRouter\\n\",\n \"\\n\",\n \"### Example 1: Using Gemini instead of OpenAI\\n\",\n \"\\n\",\n \"1. Visit Google Studio to set up an account: https://aistudio.google.com/ \\n\",\n \"2. Add your key as GOOGLE_API_KEY to your `.env` \\n\",\n \"3. Also add it a second time as GEMINI_API_KEY to your `.env` - this will be helpful later.\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"google_api_key = os.getenv(\\\"GOOGLE_API_KEY\\\")\\n\",\n \"gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"response = gemini.chat.completions.create(model=\\\"gemini-2.5-flash-preview-05-20\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 2: Using DeepSeek API instead of OpenAI (cheap, and only $2 upfront)\\n\",\n \"\\n\",\n \"1. Visit DeepSeek API to set up an account: https://platform.deepseek.com/ \\n\",\n \"2. You will need to add an initial $2 minimum balance. \\n\",\n \"3. Add your key as DEEPSEEK_API_KEY to your `.env` \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_api_key = os.getenv(\\\"DEEPSEEK_API_KEY\\\")\\n\",\n \"deepseek = OpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"response = deepseek.chat.completions.create(model=\\\"deepseek-chat\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 3: Using Ollama to be free and local instead of OpenAI\\n\",\n \"\\n\",\n \"Ollama allows you to run models locally; it provides an OpenAI compatible API on your machine. \\n\",\n \"There's no API key for Ollama; there's no third party with your credit card, so no need for any kind of key.\\n\",\n \"\\n\",\n \"1. If you're new to Ollama, install it by following the instructions here: https://ollama.com \\n\",\n \"2. Then in a Cursor Terminal, do `ollama run llama3.2` to chat with Llama 3.2 \\n\",\n \"BEWARE: do not use llama3.3 or llama4 - these are massive models not designed for home computing! They will fill up your disk. \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"ollama = OpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"anything\\\")\\n\",\n \"response = ollama.chat.completions.create(model=\\\"llama3.2\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 4: Using the popular service [OpenRouter](https://openrouter.ai) which has an easier billing process instead of OpenAI\\n\",\n \"\\n\",\n \"OpenRouter is very convenient: it gives you free access to many models, and easy access with small upfront to paid models.\\n\",\n \"\\n\",\n \"1. Sign up at https://openrouter.ai\\n\",\n \"2. Add the minimum upfront balance as needed\\n\",\n \"3. Add your key as OPENROUTER_API_KEY to your `.env` file\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from openai import OpenAI\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openrouter = OpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"response = openrouter.chat.completions.create(model=\\\"openai/gpt-4.1-nano\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. There are more notes below on each of them. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"```shell\\n\",\n \"ollama pull llama3.2\\n\",\n \"```\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"```shell\\n\",\n \"OPENROUTER_API_KEY=sk-or....\\n\",\n \"```\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "418c2e526c889025a75fa081d83031a1d8fb228e": {"t": 1785753635.5677392, "n": 21336, "h": "e21b596e8c07d8f9", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama - beyond OpenAI\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide (topics 3 and 5 in Guide 4)._\\n\",\n \"\\n\",\n \"## Crucial context for using models other than OpenAI - please read this first!\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"The companies behind these LLMs, such as OpenAI, Anthropic, Google and DeepSeek, have built web endpoints. You call their models by making an HTTP request to a Web Address and passing in all the information about your prompts.\\n\",\n \"\\n\",\n \"But it would be painful if we needed to build HTTP requests every time we wanted to call an API.\\n\",\n \"\\n\",\n \"To make this simple, the team at OpenAI wrote a python utility known as a \\\"Python Client Library\\\" which wraps the HTTP call. So you write python code and it calls the web.\\n\",\n \"\\n\",\n \"And THAT is what the library `openai` is.\\n\",\n \"\\n\",\n \"### What is the `openai` python client library\\n\",\n \"\\n\",\n \"It is:\\n\",\n \"- A lightweight python utility\\n\",\n \"- Turns your python requests into an HTTP call\\n\",\n \"- Converts the results coming back from the HTTP call into python objects\\n\",\n \"\\n\",\n \"### What it is NOT\\n\",\n \"\\n\",\n \"- It's not got any code to actually run a Large Language Model! No GPT code! It just makes a web request\\n\",\n \"- There's no scientific computing code, and nothing particularly specialized for OpenAI\\n\",\n \"\\n\",\n \"### How to use it:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4.1-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"\\n\",\n \"# Print the result\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### What does this do\\n\",\n \"\\n\",\n \"When you make the python call: `openai.chat.completions.create()` \\n\",\n \"It simply makes a web request to this url: `https://api.openai.com/v1/chat/completions` \\n\",\n \"And it converts the response to python objects.\\n\",\n \"\\n\",\n \"That's it.\\n\",\n \"\\n\",\n \"Here's the API documentation if you make [direct web HTTP calls](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=curl) \\n\",\n \"And here's the same API documentation if you use the [Python Client Library](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=python)\\n\",\n \"\\n\",\n \"## With that context - how do I use other LLMs?\\n\",\n \"\\n\",\n \"It turns out - it's super easy!\\n\",\n \"\\n\",\n \"All the other major LLMs have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"And so OpenAI did everyone a favor: they said, hey look - you can all use our utility for converting python to web requests. We'll allow you to change the utility from calling `https://api.openai/com/v1` to calling any web address that you specify.\\n\",\n \"\\n\",\n \"And so you can use the OpenAI utility even for calling models that are NOT OpenAI, like this:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to appreciate that this OpenAI code is just a utility for making HTTP calls to endpoints. So even though we're using code from the OpenAI team, we can use it to call models other than OpenAI.\\n\",\n \"\\n\",\n \"Here are all the OpenAI-compatible endpoints from the major providers. It even includes using Ollama, locally. Ollama provides an endpoint on your local machine, and they made it OpenAI compatible too - very convenient.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"ANTHROPIC_BASE_URL = \\\"https://api.anthropic.com/v1/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Here are examples for Gemini, DeepSeek, Ollama and OpenRouter\\n\",\n \"\\n\",\n \"### Example 1: Using Gemini instead of OpenAI\\n\",\n \"\\n\",\n \"1. Visit Google Studio to set up an account: https://aistudio.google.com/ \\n\",\n \"2. Add your key as GOOGLE_API_KEY to your `.env` \\n\",\n \"3. Also add it a second time as GEMINI_API_KEY to your `.env` - this will be helpful later.\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"google_api_key = os.getenv(\\\"GOOGLE_API_KEY\\\")\\n\",\n \"gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"response = gemini.chat.completions.create(model=\\\"gemini-2.5-flash-preview-05-20\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 2: Using DeepSeek API instead of OpenAI (cheap, and only $2 upfront)\\n\",\n \"\\n\",\n \"1. Visit DeepSeek API to set up an account: https://platform.deepseek.com/ \\n\",\n \"2. You will need to add an initial $2 minimum balance. \\n\",\n \"3. Add your key as DEEPSEEK_API_KEY to your `.env` \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_api_key = os.getenv(\\\"DEEPSEEK_API_KEY\\\")\\n\",\n \"deepseek = OpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"response = deepseek.chat.completions.create(model=\\\"deepseek-chat\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 3: Using Ollama to be free and local instead of OpenAI\\n\",\n \"\\n\",\n \"Ollama allows you to run models locally; it provides an OpenAI compatible API on your machine. \\n\",\n \"There's no API key for Ollama; there's no third party with your credit card, so no need for any kind of key.\\n\",\n \"\\n\",\n \"1. If you're new to Ollama, install it by following the instructions here: https://ollama.com \\n\",\n \"2. Then in a Cursor Terminal, do `ollama run llama3.2` to chat with Llama 3.2 \\n\",\n \"BEWARE: do not use llama3.3 or llama4 - these are massive models not designed for home computing! They will fill up your disk. \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"ollama = OpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"anything\\\")\\n\",\n \"response = ollama.chat.completions.create(model=\\\"llama3.2\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 4: Using the popular service [OpenRouter](https://openrouter.ai) which has an easier billing process instead of OpenAI\\n\",\n \"\\n\",\n \"OpenRouter is very convenient: it gives you free access to many models, and easy access with small upfront to paid models.\\n\",\n \"\\n\",\n \"1. Sign up at https://openrouter.ai\\n\",\n \"2. Add the minimum upfront balance as needed\\n\",\n \"3. Add your key as OPENROUTER_API_KEY to your `.env` file\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openrouter = OpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"response = openrouter.chat.completions.create(model=\\\"openai/gpt-4.1-nano\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. There are more notes below on each of them. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"```shell\\n\",\n \"ollama pull llama3.2\\n\",\n \"```\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"```shell\\n\",\n \"OPENROUTER_API_KEY=sk-or....\\n\",\n \"```\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "806a2746fc9375d067c68f1205ebb554a88e4dfe": {"t": 1785753636.9086115, "n": 21210, "h": "249b7a626921843d", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama - beyond OpenAI\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide (topics 3 and 5 in Guide 4)._\\n\",\n \"\\n\",\n \"## Crucial context for using models other than OpenAI - please read this first!\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"The companies behind these LLMs, such as OpenAI, Anthropic, Google and DeepSeek, have built web endpoints. You call their models by making an HTTP request to a URL and passing in all the information about your prompts.\\n\",\n \"\\n\",\n \"But it would be painful if we needed to build HTTP requests every time we wanted to call an API.\\n\",\n \"\\n\",\n \"To make this simple, the team at OpenAI wrote a python utility known as a \\\"Python Client Library\\\" which wraps the HTTP call. So you write python code and it calls the web.\\n\",\n \"\\n\",\n \"And THAT is what the library `openai` is.\\n\",\n \"\\n\",\n \"### What is the `openai` python client library\\n\",\n \"\\n\",\n \"It is:\\n\",\n \"- A lightweight python utility\\n\",\n \"- Turns your python requests into an HTTP call\\n\",\n \"- Converts the results coming back from the HTTP call into python objects\\n\",\n \"\\n\",\n \"### What it is NOT\\n\",\n \"\\n\",\n \"- It's not got any code to actually run a Large Language Model! No GPT code! It just makes a web request\\n\",\n \"- There's no scientific computing code, and nothing particularly specialized for OpenAI\\n\",\n \"\\n\",\n \"### How to use it:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4.1-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"\\n\",\n \"# Print the result\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### What does this do\\n\",\n \"\\n\",\n \"When you make the python call: `openai.chat.completions.create()` \\n\",\n \"It simply makes a web request to this url: `https://api.openai.com/v1/chat/completions` \\n\",\n \"And it converts the response to python objects.\\n\",\n \"\\n\",\n \"That's it.\\n\",\n \"\\n\",\n \"Here's the API documentation if you make [direct web HTTP calls](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=curl) \\n\",\n \"And here's the same API documentation if you use the [Python Client Library](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=python)\\n\",\n \"\\n\",\n \"## With that context - how do I use other LLMs?\\n\",\n \"\\n\",\n \"It turns out - it's super easy!\\n\",\n \"\\n\",\n \"All the other major LLMs have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"And so OpenAI did everyone a favor: they said, hey look - you can all use our utility for converting python to web requests. We'll allow you to change the utility from calling `https://api.openai/com/v1` to calling any web address that you specify.\\n\",\n \"\\n\",\n \"And so you can use the OpenAI utility even for calling models that are NOT OpenAI, like this:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to appreciate that this OpenAI code is just a utility for making HTTP calls to endpoints. So even though we're using code from the OpenAI team, we can use it to call models other than OpenAI.\\n\",\n \"\\n\",\n \"Here are all the OpenAI-compatible endpoints from the major providers. It even includes using Ollama, locally. Ollama provides an endpoint on your local machine, and they made it OpenAI compatible too - very convenient.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"ANTHROPIC_BASE_URL = \\\"https://api.anthropic.com/v1/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Here are examples for Gemini, DeepSeek, Ollama and OpenRouter\\n\",\n \"\\n\",\n \"### Example 1: Using Gemini instead of OpenAI\\n\",\n \"\\n\",\n \"1. Visit Google Studio to set up an account: https://aistudio.google.com/ \\n\",\n \"2. Add your key as GOOGLE_API_KEY to your `.env` \\n\",\n \"3. Also add it a second time as GEMINI_API_KEY to your `.env` - this will be helpful later.\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"google_api_key = os.getenv(\\\"GOOGLE_API_KEY\\\")\\n\",\n \"gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"response = gemini.chat.completions.create(model=\\\"gemini-2.5-flash-preview-05-20\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 2: Using DeepSeek API instead of OpenAI (cheap, and only $2 upfront)\\n\",\n \"\\n\",\n \"1. Visit DeepSeek API to set up an account: https://platform.deepseek.com/ \\n\",\n \"2. You will need to add an initial $2 minimum balance. \\n\",\n \"3. Add your key as DEEPSEEK_API_KEY to your `.env` \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_api_key = os.getenv(\\\"DEEPSEEK_API_KEY\\\")\\n\",\n \"deepseek = OpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"response = deepseek.chat.completions.create(model=\\\"deepseek-chat\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 3: Using Ollama to be free and local instead of OpenAI\\n\",\n \"\\n\",\n \"Ollama allows you to run models locally; it provides an OpenAI compatible API on your machine. \\n\",\n \"\\n\",\n \"1. If you're new to Ollama, install it by following the instructions here: https://ollama.com \\n\",\n \"2. Then in a Cursor Terminal, do `ollama run llama3.2` to chat with Llama 3.2 \\n\",\n \"BEWARE: do not use llama3.3 or llama4 - these are massive models not designed for home computing! They will fill up your disk. \\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"ollama = OpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"anything\\\")\\n\",\n \"response = ollama.chat.completions.create(model=\\\"llama3.2\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 4: Using the popular service [OpenRouter](https://openrouter.ai) which has an easier billing process instead of OpenAI\\n\",\n \"\\n\",\n \"OpenRouter is very convenient: it gives you free access to many models, and easy access with small upfront to paid models.\\n\",\n \"\\n\",\n \"1. Sign up at https://openrouter.ai\\n\",\n \"2. Add the minimum upfront balance as needed\\n\",\n \"3. Add your key as OPENROUTER_API_KEY to your `.env` file\\n\",\n \"\\n\",\n \"Then:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openrouter = OpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"response = openrouter.chat.completions.create(model=\\\"openai/gpt-4.1-nano\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. There are more notes below on each of them. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"```shell\\n\",\n \"ollama pull llama3.2\\n\",\n \"```\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"```shell\\n\",\n \"OPENROUTER_API_KEY=sk-or....\\n\",\n \"```\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "5a1adfe92767a54d664d3a184b3b88aeeb5c8505": {"t": 1785753638.5660849, "n": 20011, "h": "67f3906bc4a12541", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama - beyond OpenAI\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide._\\n\",\n \"\\n\",\n \"## Crucial context for using models other than OpenAI - please read this first!\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"The companies behind these LLMs, such as OpenAI, Anthropic, Google and DeepSeek, have built web endpoints. You call their models by making an HTTP request to a URL and passing in all the information about your prompts.\\n\",\n \"\\n\",\n \"But it would be super inconvenient if we needed to build HTTP requests every time we wanted to call an API.\\n\",\n \"\\n\",\n \"To make this simple, the team at OpenAI wrote a python library known as a \\\"Python Client Library\\\" which wraps the HTTP call. So you write python code and it calls the web.\\n\",\n \"\\n\",\n \"And THAT is what the library `openai` is.\\n\",\n \"\\n\",\n \"### What is the `openai` python client library\\n\",\n \"\\n\",\n \"It is:\\n\",\n \"- A lightweight python utility\\n\",\n \"- Turns your python requests into an HTTP call\\n\",\n \"- Converts the results coming back from the HTTP call into python objects\\n\",\n \"\\n\",\n \"### What it is NOT\\n\",\n \"\\n\",\n \"- It's not got any code to actually run a Large Language Model! No GPT code! It just makes a web request\\n\",\n \"- There's no scientific computing code, and nothing particularly specialized for OpenAI\\n\",\n \"\\n\",\n \"### How to use it:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4.1-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"\\n\",\n \"# Print the result\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### What does this do\\n\",\n \"\\n\",\n \"When you make the python call: `openai.chat.completions.create()` \\n\",\n \"It simply makes a web request to this url: `https://api.openai.com/v1/chat/completions` \\n\",\n \"And it converts the response to python objects.\\n\",\n \"\\n\",\n \"That's it.\\n\",\n \"\\n\",\n \"Here's the API documentation if you make [direct web HTTP calls](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=curl) \\n\",\n \"And here's the same API documentation if you use the [Python Client Library](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=python)\\n\",\n \"\\n\",\n \"## With that context - how do I use other LLMs?\\n\",\n \"\\n\",\n \"It turns out - it's super easy!\\n\",\n \"\\n\",\n \"All the other major LLMs have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"And so OpenAI did everyone a favor: they said, hey look - you can all use our utility for converting python to web requests. We'll make it so you can change the utility from calling `https://api.openai/com/v1` to calling any base URL that you specify.\\n\",\n \"\\n\",\n \"And so you can use the OpenAI utility even for calling models that are NOT OpenAI, like this:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to appreciate that this OpenAI code is just a utility for making HTTP calls to endpoints. So even though we're using code from the OpenAI team, we can use it to call models other than OpenAI.\\n\",\n \"\\n\",\n \"Here are all the OpenAI-compatible endpoints from the major providers. It even includes using Ollama, locally. Ollama provides an endpoint on your local machine, and they made it OpenAI compatible too - very convenient.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"ANTHROPIC_BASE_URL = \\\"https://api.anthropic.com/v1/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Here are examples for Gemini, DeepSeek, Ollama and OpenRouter\\n\",\n \"\\n\",\n \"Before any of these, include:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 1: Using Gemini instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"google_api_key = os.getenv(\\\"GOOGLE_API_KEY\\\")\\n\",\n \"gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"response = gemini.chat.completions.create(model=\\\"gemini-2.5-flash-preview-05-20\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 2: Using DeepSeek API instead of OpenAI (cheap, and only $2 upfront)\\n\",\n \"\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_api_key = os.getenv(\\\"DEEPSEEK_API_KEY\\\")\\n\",\n \"deepseek = OpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"response = deepseek.chat.completions.create(model=\\\"deepseek-chat\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 3: Using Ollama to be free and local instead of OpenAI\\n\",\n \"\\n\",\n \"Ollama allows you to run models locally; it provides an OpenAI compatible API on your machine. If you're new to Ollama, installation instructions are a couple of sections lower down in this guide. Be sure NOT to use llama3.3 or llama4 - these models are too big for home computing!\\n\",\n \"\\n\",\n \"```python\\n\",\n \"!ollama pull llama3.2\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"ollama = OpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"anything\\\")\\n\",\n \"response = ollama.chat.completions.create(model=\\\"llama3.2\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 4: Using the popular service [OpenRouter](https://openrouter.ai) which has an easier billing process instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openrouter = OpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"response = openrouter.chat.completions.create(model=\\\"openai/gpt-4.1-nano\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. There are more notes below on each of them. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"```shell\\n\",\n \"ollama pull llama3.2\\n\",\n \"```\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"```shell\\n\",\n \"OPENROUTER_API_KEY=sk-or....\\n\",\n \"```\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "46c42b301b9c84ad2a4e46c6df0107cf5bec8b0a": {"t": 1785753639.8963315, "n": 19609, "h": "82117556e9e0f1eb", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama - beyond OpenAI\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide._\\n\",\n \"\\n\",\n \"## Crucial context for using models other than OpenAI - please read this first!\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"The companies behind these LLMs, such as OpenAI, Anthropic, Google and DeepSeek, have built web endpoints. You call their models by making an HTTP request to a URL and passing in all the information about your prompts.\\n\",\n \"\\n\",\n \"But it would be super inconvenient if we needed to build HTTP requests every time we wanted to call an API.\\n\",\n \"\\n\",\n \"To make this simple, the team at OpenAI wrote a python library known as a \\\"Python Client Library\\\" which wraps the HTTP call. So you write python code and it calls the web.\\n\",\n \"\\n\",\n \"And THAT is what the library `openai` is.\\n\",\n \"\\n\",\n \"### What is the `openai` python client library\\n\",\n \"\\n\",\n \"It is:\\n\",\n \"- A lightweight python utility\\n\",\n \"- Turns your python requests into an HTTP call\\n\",\n \"- Converts the results coming back from the HTTP call into python objects\\n\",\n \"\\n\",\n \"### What it is NOT\\n\",\n \"\\n\",\n \"- It's not got any code to actually run a Large Language Model! No GPT code! It just makes a web request\\n\",\n \"- There's no scientific computing code, and nothing particularly specialized for OpenAI\\n\",\n \"\\n\",\n \"### How to use it:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4.1-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"\\n\",\n \"# Print the result\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### What does this do\\n\",\n \"\\n\",\n \"When you make the python call: `openai.chat.completions.create()` \\n\",\n \"It simply makes a web request to this url: `https://api.openai.com/v1/chat/completions` \\n\",\n \"And it converts the response to python objects.\\n\",\n \"\\n\",\n \"That's it.\\n\",\n \"\\n\",\n \"Here's the API documentation if you make [direct web HTTP calls](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=curl) \\n\",\n \"And here's the same API documentation if you use the [Python Client Library](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=python)\\n\",\n \"\\n\",\n \"## With that context - how do I use other LLMs?\\n\",\n \"\\n\",\n \"It turns out - it's super easy!\\n\",\n \"\\n\",\n \"All the other major LLMs have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"And so OpenAI did everyone a favor: they said, hey look - you can all use our utility for converting python to web requests. We'll make it so you can change the utility from calling `https://api.openai/com/v1` to calling any base URL that you specify.\\n\",\n \"\\n\",\n \"And so you can use the OpenAI utility even for calling models that are NOT OpenAI, like this:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to appreciate that this OpenAI code is just a utility for making HTTP calls to endpoints. So even though we're using code from the OpenAI team, we can use it to call models other than OpenAI.\\n\",\n \"\\n\",\n \"Here are all the OpenAI-compatible endpoints from the major providers. It even includes using Ollama, locally. Ollama provides an endpoint on your local machine, and they made it OpenAI compatible too - very convenient.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"ANTHROPIC_BASE_URL = \\\"https://api.anthropic.com/v1/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Here are examples for Gemini, DeepSeek, Ollama and OpenRouter\\n\",\n \"\\n\",\n \"Before any of these, include:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"import os\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"load_dotenv(override=True)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 1: Using Gemini instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"google_api_key = os.getenv(\\\"GOOGLE_API_KEY\\\")\\n\",\n \"gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"response = gemini.chat.completions.create(model=\\\"gemini-2.5-flash-preview-05-20\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 2: Using DeepSeek instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_api_key = os.getenv(\\\"DEEPSEEK_API_KEY\\\")\\n\",\n \"deepseek = OpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"response = deepseek.chat.completions.create(model=\\\"deepseek-chat\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 3: Using Ollama to be free and local instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"!ollama pull llama3.2\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"ollama = OpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"anything\\\")\\n\",\n \"response = ollama.chat.completions.create(model=\\\"llama3.2\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Example 4: Using the popular service [OpenRouter](https://openrouter.ai) which has an easier billing process instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openrouter = OpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"response = openrouter.chat.completions.create(model=\\\"openai/gpt-4.1-nano\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. There are more notes below on each of them. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "e132df3f54c78b9720b9bc9c84241f3d3bad55b9": {"t": 1785753643.4163043, "n": 19324, "h": "9cf32d86162a8a72", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama - beyond OpenAI\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Crucial context for using models other than OpenAI - please read this first!\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"The companies behind these LLMs, such as OpenAI, Anthropic, Google and DeepSeek, have built web endpoints. You call their models by making an HTTP request to a URL and passing in all the information about your prompts.\\n\",\n \"\\n\",\n \"But it would be super inconvenient if we needed to build HTTP requests every time we wanted to call an API.\\n\",\n \"\\n\",\n \"To make this simple, the team at OpenAI wrote a python library known as a \\\"Python Client Library\\\" which wraps the HTTP call. So you write python code and it calls the web.\\n\",\n \"\\n\",\n \"And THAT is what the library `openai` is.\\n\",\n \"\\n\",\n \"### What is the `openai` python client library\\n\",\n \"\\n\",\n \"It is:\\n\",\n \"- A lightweight python utility\\n\",\n \"- Turns your python requests into an HTTP call\\n\",\n \"- Converts the results coming back from the HTTP call into python objects\\n\",\n \"\\n\",\n \"### What it is NOT\\n\",\n \"\\n\",\n \"- It's not got any code to actually run a Large Language Model! No GPT code! It just makes a web request\\n\",\n \"- There's no scientific computing code, and nothing particularly specialized for OpenAI\\n\",\n \"\\n\",\n \"### How to use it:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4.1-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"\\n\",\n \"# Print the result\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### What does this do\\n\",\n \"\\n\",\n \"When you make the python call: \\n\",\n \"`openai.chat.completions.create()`\\n\",\n \"It simply makes a web request to this url: \\n\",\n \"`https://api.openai.com/v1/chat/completions` \\n\",\n \"And it converts the response to python objects.\\n\",\n \"\\n\",\n \"That's it.\\n\",\n \"\\n\",\n \"Here's the API documentation if you make [direct web HTTP calls](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=curl) \\n\",\n \"And here's the same API documentation if you use the [Python Client Library](https://platform.openai.com/docs/guides/text?api-mode=chat&lang=python)\\n\",\n \"\\n\",\n \"## With that context - how do I use other LLMs?\\n\",\n \"\\n\",\n \"It turns out - it's super easy!\\n\",\n \"\\n\",\n \"All the other major LLMs have API endpoints that are compatible with the API endpoints from OpenAI.\\n\",\n \"\\n\",\n \"And so OpenAI did everyone a favor: they said, hey look - you can all use our utility for converting python to web requests. We'll make it so you can change the utility from calling `https://api.openai/com/v1` to calling any base URL that you specify.\\n\",\n \"\\n\",\n \"And so you can use the OpenAI utility even for calling models that are NOT OpenAI, like this:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to appreciate that this OpenAI code is just a utility for making HTTP calls to endpoints. There's no LLM code here - just a wrapper around a network call.\\n\",\n \"\\n\",\n \"And here are all the OpenAI-compatible endpoints from the major providers. It even includes using Ollama, locally! Ollama provides an endpoint on your local machine, and they made it OpenAI compatible too - very convenient.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"ANTHROPIC_BASE_URL = \\\"https://api.anthropic.com/v1/\\\"\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Example 1: Using Gemini instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"google_api_key = os.getenv(\\\"GOOGLE_API_KEY\\\")\\n\",\n \"gemini = OpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"response = gemini.chat.completions.create(model=\\\"gemini-2.5-flash-preview-05-20\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Example 2: Using DeepSeek instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_api_key = os.getenv(\\\"DEEPSEEK_API_KEY\\\")\\n\",\n \"deepseek = OpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"response = deepseek.chat.completions.create(model=\\\"deepseek-chat\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Example 3: Using Ollama instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"!ollama pull llama3.2\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"ollama = OpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"anything\\\")\\n\",\n \"response = ollama.chat.completions.create(model=\\\"llama3.2\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"## Example 4: Using the popular service [OpenRouter](https://openrouter.ai) which has an easier billing process instead of OpenAI\\n\",\n \"\\n\",\n \"```python\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openrouter = OpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"response = openrouter.chat.completions.create(model=\\\"openai/gpt-4.1-nano\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. There are more notes below on each of them. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "9d3b141b6813a91822fd13bebc4683990512c3ea": {"t": 1785753645.077967, "n": 15088, "h": "ce26a5920da21414", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Introduction to LLM APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify which model to use, and the prompts\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}]\\n\",\n \"\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=MODEL, messages=messages)\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI. In fact, it's almost everyone aside from Anthropic!\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\\n\",\n \"\\n\",\n \"Many API providers offer an OpenAI compatible endpoint that you can use as your base_url. Here are some popular ones:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. You may need to look up in the framework docs how best to switch to a different API, or ask me. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama + local models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "a4c8c915c1485412e13d0bbc66020bfb90a60d89": {"t": 1785753647.4099112, "n": 15089, "h": "3e03199e09486b7f", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Introduction to LLM APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify which model to use, and the prompts\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}]\\n\",\n \"\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=MODEL, messages=messages)\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI. In fact, it's almost everyone aside from Anthropic!\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\\n\",\n \"\\n\",\n \"Many API providers offer an OpenAI compatible endpoint that you can use as your base_url. Here are some popular ones:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. You may need to look up in the framework docs how best to switch to a different API, or ask me. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AutoGen with other models\\n\",\n \"\\n\",\n \"Here's another contribution from Miroslav P. (thank you!) for using Ollama / localm models with AutoGen, and Miroslav has a great example showing gemma3 performing well.\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# model_client = OpenAIChatCompletionClient(model=\\\"gpt-4o-mini\\\")\\n\",\n \" \\n\",\n \"from autogen_ext.models.ollama import OllamaChatCompletionClient\\n\",\n \" \\n\",\n \"model_client = OllamaChatCompletionClient(\\n\",\n \" model=\\\"gemma3:4b\\\",\\n\",\n \" model_info={\\n\",\n \" \\\"vision\\\": True,\\n\",\n \" \\\"function_calling\\\": False,\\n\",\n \" \\\"json_output\\\": True,\\n\",\n \" \\\"family\\\": \\\"unknown\\\",\\n\",\n \" },\\n\",\n \")\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "e0941cc9612d4ddadb174ba09694e81ec2a350a3": {"t": 1785753649.1070619, "n": 14273, "h": "f6d799e93b0bd313", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Introduction to LLM APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify which model to use, and the prompts\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}]\\n\",\n \"\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=MODEL, messages=messages)\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI. In fact, it's almost everyone aside from Anthropic!\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\\n\",\n \"\\n\",\n \"Many API providers offer an OpenAI compatible endpoint that you can use as your base_url. Here are some popular ones:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. You may need to look up in the framework docs how best to switch to a different API, or ask me. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## LangGraph setup\\n\",\n \"\\n\",\n \"To use LangGraph with Ollama (and follow similar for other models): \\n\",\n \"https://python.langchain.com/docs/integrations/chat/ollama/#installation\\n\",\n \"\\n\",\n \"First add the package: \\n\",\n \"`uv add langchain-ollama`\\n\",\n \"\\n\",\n \"Then in the lab, make this replacement: \\n\",\n \"```python\\n\",\n \"from langchain_ollama import ChatOllama\\n\",\n \"# llm = ChatOpenAI(model=\\\"gpt-4o-mini\\\")\\n\",\n \"llm = ChatOllama(model=\\\"gemma3:4b\\\")\\n\",\n \"```\\n\",\n \"\\n\",\n \"And obviously run `!ollama pull gemma3:4b` (or whichever model) beforehand.\\n\",\n \"\\n\",\n \"Many thanks to Miroslav P. for adding this, and to Arvin F. for the question!\\n\",\n \"\\n\",\n \"## LangGraph with other models\\n\",\n \"\\n\",\n \"Just follow the same recipe as above, but use any of the models from here: \\n\",\n \"https://python.langchain.com/docs/integrations/chat/\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "ee7ccac2465e3b752494c5241e2ed0d1a1426a26": {"t": 1785753650.3502321, "n": 13269, "h": "3f59a1286f5ad667", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Introduction to LLM APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify which model to use, and the prompts\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}]\\n\",\n \"\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=MODEL, messages=messages)\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI. In fact, it's almost everyone aside from Anthropic!\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\\n\",\n \"\\n\",\n \"Many API providers offer an OpenAI compatible endpoint that you can use as your base_url. Here are some popular ones:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. You may need to look up in the framework docs how best to switch to a different API, or ask me. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"You don't need to put anything in your .env file for this; with Ollama, everything is running on your computer. You're not calling out to a third party on the cloud, nobody has your credit card details, so there's no need for a secret key! The code `api_key='ollama'` above is only required because the OpenAI client library expects an api_key to be passed in, but the value is ignored by Ollama.\\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```python\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```python\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"### To use Azure with OpenAI Agents SDK\\n\",\n \"\\n\",\n \"See instructions here: \\n\",\n \"https://techcommunity.microsoft.com/blog/azure-ai-services-blog/use-azure-openai-and-apim-with-the-openai-agents-sdk/4392537\\n\",\n \"\\n\",\n \"Such as this:\\n\",\n \"```python\\n\",\n \"from openai import AsyncAzureOpenAI\\n\",\n \"from agents import set_default_openai_client\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"import os\\n\",\n \" \\n\",\n \"# Load environment variables\\n\",\n \"load_dotenv()\\n\",\n \" \\n\",\n \"# Create OpenAI client using Azure OpenAI\\n\",\n \"openai_client = AsyncAzureOpenAI(\\n\",\n \" api_key=os.getenv(\\\"AZURE_OPENAI_API_KEY\\\"),\\n\",\n \" api_version=os.getenv(\\\"AZURE_OPENAI_API_VERSION\\\"),\\n\",\n \" azure_endpoint=os.getenv(\\\"AZURE_OPENAI_ENDPOINT\\\"),\\n\",\n \" azure_deployment=os.getenv(\\\"AZURE_OPENAI_DEPLOYMENT\\\")\\n\",\n \")\\n\",\n \" \\n\",\n \"# Set the default OpenAI client for the Agents SDK\\n\",\n \"set_default_openai_client(openai_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "9f2177bdf598ca7d0023099eb333dc112ed6f780": {"t": 1785753652.6768172, "n": 11783, "h": "8f41792cfb4971d5", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review the APIs section in Guide 4 Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Introduction to LLM APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# Specify which model to use, and the prompts\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}]\\n\",\n \"\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=MODEL, messages=messages)\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI. In fact, it's almost everyone aside from Anthropic!\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\\n\",\n \"\\n\",\n \"Many API providers offer an OpenAI compatible endpoint that you can use as your base_url. Here are some popular ones:\\n\",\n \"\\n\",\n \"```\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. You may need to look up in the framework docs how best to switch to a different API, or ask me. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "98b346f1a7f8f6fe40e7f7075ba4b7a2c2aa69df": {"t": 1785753654.0982187, "n": 11766, "h": "e4c910e8bda10722", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review Guide 4 on Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Introduction to LLM APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# Specify which model to use, and the prompts\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}]\\n\",\n \"\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=MODEL, messages=messages)\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI. In fact, it's almost everyone aside from Anthropic!\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\\n\",\n \"\\n\",\n \"Many API providers offer an OpenAI compatible endpoint that you can use as your base_url. Here are some popular ones:\\n\",\n \"\\n\",\n \"```\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. You may need to look up in the framework docs how best to switch to a different API, or ask me. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## CrewAI setup\\n\",\n \"\\n\",\n \"Here's Crew's docs for LLM connections with the model names to use for all models. As student Sadan S. pointed out (thank you!), it's worth knowing that for Google you need to use the environment variable `GEMINI_API_KEY` instead of `GOOGLE_API_KEY`:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/concepts/llms\\n\",\n \"\\n\",\n \"And here's their tutorial with some more info:\\n\",\n \"\\n\",\n \"https://docs.crewai.com/how-to/llm-connections\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "28e3b5221c92fe7d31718f68677d035c82ebeb41": {"t": 1785753656.1187804, "n": 11209, "h": "d8e9fd28c73d66ec", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review Guide 4 on Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Introduction to LLM APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# Specify which model to use, and the prompts\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}]\\n\",\n \"\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=MODEL, messages=messages)\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI. In fact, it's almost everyone aside from Anthropic!\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\\n\",\n \"\\n\",\n \"Many API providers offer an OpenAI compatible endpoint that you can use as your base_url. Here are some popular ones:\\n\",\n \"\\n\",\n \"```\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"```\\n\",\n \"\\n\",\n \"### Using different API providers with Agent Frameworks\\n\",\n \"\\n\",\n \"The Agent Frameworks make it easy to switch between these providers. You can switch LLMs and pick different ones at any point in the course. You may need to look up in the framework docs how best to switch to a different API, or ask me. For OpenAI Agents SDK, see a section later in this notebook. For CrewAI, we cover it on the course, but it's easy: just use the full path to the model that LiteLLM expects.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. A complex Agentic project could involve many LLM calls - perhaps 20-30 - and so it can add up. It's important to set limits and monitor usage.\\n\",\n \"\\n\",\n \"2. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"3. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## OpenAI Agents SDK - specific instructions\\n\",\n \"\\n\",\n \"With OpenAI Agents SDK (weeks 2 and 6), it's particularly easy to use any model provided by OpenAI themselves. Simply pass in the model name:\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=\\\"gpt-4o-mini\\\")`\\n\",\n \"\\n\",\n \"You can also substitute in any other provider with an OpenAI compatible API. You do it in 3 steps like this:\\n\",\n \"\\n\",\n \"```\\n\",\n \"DEEPSEEK_BASE_URL = \\\"https://api.deepseek.com/v1\\\"\\n\",\n \"deepseek_client = AsyncOpenAI(base_url=DEEPSEEK_BASE_URL, api_key=deepseek_api_key)\\n\",\n \"deepseek_model = OpenAIChatCompletionsModel(model=\\\"deepseek-chat\\\", openai_client=deepseek_client)\\n\",\n \"```\\n\",\n \"\\n\",\n \"And then you simply provide this model when you create an Agent.\\n\",\n \"\\n\",\n \"`agent = Agent(name=\\\"Jokester\\\", instructions=\\\"You are a joke teller\\\", model=deepseek_model)`\\n\",\n \"\\n\",\n \"And you can use a similar approach for any other OpenAI compatible API, with the same 3 steps:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# Specify the base URL endpoints where the provider offers an OpenAI compatible API\\n\",\n \"GEMINI_BASE_URL = \\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\"\\n\",\n \"GROK_BASE_URL = \\\"https://api.x.ai/v1\\\"\\n\",\n \"GROQ_BASE_URL = \\\"https://api.groq.com/openai/v1\\\"\\n\",\n \"OPENROUTER_BASE_URL = \\\"https://openrouter.ai/api/v1\\\"\\n\",\n \"OLLAMA_BASE_URL = \\\"http://localhost:11434/v1\\\"\\n\",\n \"\\n\",\n \"# Create an AsyncOpenAI object for that endpoint\\n\",\n \"gemini_client = AsyncOpenAI(base_url=GEMINI_BASE_URL, api_key=google_api_key)\\n\",\n \"grok_client = AsyncOpenAI(base_url=GROK_BASE_URL, api_key=grok_api_key)\\n\",\n \"groq_client = AsyncOpenAI(base_url=GROQ_BASE_URL, api_key=groq_api_key)\\n\",\n \"openrouter_client = AsyncOpenAI(base_url=OPENROUTER_BASE_URL, api_key=openrouter_api_key)\\n\",\n \"ollama_client = AsyncOpenAI(base_url=OLLAMA_BASE_URL, api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"# Create a model object to provide when creating an Agent\\n\",\n \"gemini_model = OpenAIChatCompletionsModel(model=\\\"gemini-2.5-flash\\\", openai_client=gemini_client)\\n\",\n \"grok_3_model = OpenAIChatCompletionsModel(model=\\\"grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama3_3_model = OpenAIChatCompletionsModel(model=\\\"llama-3.3-70b-versatile\\\", openai_client=groq_client)\\n\",\n \"grok_3_via_openrouter_model = OpenAIChatCompletionsModel(model=\\\"x-ai/grok-3-mini-beta\\\", openai_client=openrouter_client)\\n\",\n \"llama_3_2_local_model = OpenAIChatCompletionsModel(model=\\\"llama3.2\\\", openai_client=ollama_client)\\n\",\n \"```\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Worth keeping in mind\\n\",\n \"\\n\",\n \"1. If you wish to use Ollama to run models locally, you may find that smaller models struggle with the more advanced projects. You'll need to experiment with different model sizes and capabilities, and plenty of patience may be needed to find something that works well. I expect several of our projects are too challenging for llama3.2. As an alternative, consider the free models on openrouter.ai, or the very cheap models that are almost free - like DeepSeek.\\n\",\n \"\\n\",\n \"2. Chat models often do better than Reasoning models because Reasoning models can \\\"over-think\\\" some assignments. It's important to experiment. Bigger isn't always better...\\n\",\n \"\\n\",\n \"3. It's confusing, but there are 2 different providers that sound similar! \\n\",\n \"- Grok is the LLM from Elon Musk's X\\n\",\n \"- Groq is a platform for fast inference of open source models\\n\",\n \"\\n\",\n \"A student pointed out to me that \\\"Groq\\\" came first!\\n\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "21b2cadc76967840f55a712380bb52e03ebf6c95": {"t": 1785753657.3544962, "n": 6376, "h": "c1ace0f0e1cb4c0c", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"_IMPORTANT: If you're not as familiar with APIs in general, and with Environment Variables on your PC or Mac, please review Guide 4 on Technical Foundations before proceeding with this guide!_\\n\",\n \"\\n\",\n \"## Introduction to LLM APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"You can switch LLMs and pick different ones at any point; you may need to look up in the framework docs how best to switch to a different API, or ask me.\\n\",\n \"\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# Specify which model to use, and the prompts\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"what is 2+2?\\\"}]\\n\",\n \"\\n\",\n \"# Create an OpenAI python client for making web calls to OpenAI\\n\",\n \"openai = OpenAI()\\n\",\n \"\\n\",\n \"# Make the call\\n\",\n \"response = openai.chat.completions.create(model=MODEL, messages=messages)\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"2. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"WARNING: Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### OpenRouter: Convenient gateway platform for OpenAI and others\\n\",\n \"\\n\",\n \"OpenRouter is a third party service that allows you to connect to a wide range of LLMs, including OpenAI.\\n\",\n \"\\n\",\n \"It's known for having a simpler billing process that may be easier for some countries outside the US.\\n\",\n \"\\n\",\n \"First, check out their website: \\n\",\n \"https://openrouter.ai/\\n\",\n \"\\n\",\n \"Then, take a peak at their quickstart: \\n\",\n \"https://openrouter.ai/docs/quickstart\\n\",\n \"\\n\",\n \"And add your key to your .env file: \\n\",\n \"`OPENROUTER_API_KEY=sk-or....`\\n\",\n \"\\n\",\n \"And now, any time you have code like this: \\n\",\n \"```\\n\",\n \"MODEL = \\\"gpt-4o-mini\\\"\\n\",\n \"openai = OpenAI()\\n\",\n \"```\\n\",\n \"\\n\",\n \"You can replace it with code like this:\\n\",\n \"\\n\",\n \"```\\n\",\n \"MODEL = \\\"openai/gpt-4o-mini\\\"\\n\",\n \"openrouter_api_key = os.getenv(\\\"OPENROUTER_API_KEY\\\")\\n\",\n \"openai = OpenAI(base_url=\\\"https://openrouter.ai/api/v1\\\", api_key=openrouter_api_key)\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use OpenRouter within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": []\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "50db6ce8f03d420bd476d9c1e126ba144d11368a": {"t": 1785753659.6814113, "n": 4307, "h": "515e49c41968934d", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# LLM APIs and Ollama\\n\",\n \"\\n\",\n \"## Introduction to APIs\\n\",\n \"\\n\",\n \"Throughout the course, we use APIs for connecting with the strongest LLMs on the planet.\\n\",\n \"\\n\",\n \"You can switch LLMs and pick different ones at any point; you may need to look up in the framework docs how best to switch to a different API, or ask me.\\n\",\n \"\\n\",\n \"OpenAI has a python client library which simplifies the way we call OpenAI on the cloud:\\n\",\n \"\\n\",\n \"```\\n\",\n \"openai = OpenAI()\\n\",\n \"response = openai.chat.completions.create(model=\\\"gpt-4o-mini\\\", messages=[{\\\"role\\\":\\\"user\\\", \\\"content\\\":\\\"what is 2+2?\\\"}])\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"Several other LLMs, including Google Gemini and DeepSeek, have API endpoints that are compatible with OpenAI.\\n\",\n \"\\n\",\n \"OpenAI has made their python client library available for others to use by switching the URL from their URL to somewhere else:\\n\",\n \"\\n\",\n \"`not_actually_openai = OpenAI(base_url=\\\"https://somewhere.completely.different/\\\", api_key=\\\"another_providers_key\\\")`\\n\",\n \"\\n\",\n \"It's important to realize that this OpenAI code is just a utility for making https calls to endpoints. There's no LLM code here - just a wrapper around a network call.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Costs of APIs\\n\",\n \"\\n\",\n \"The cost of each API call is very low indeed - most calls to models we use on this course are fractions of cents.\\n\",\n \"\\n\",\n \"But it's extremely important to note:\\n\",\n \"\\n\",\n \"1. With Agentic AI, there is a risk of Agents getting into a loop or carrying out more processing than intended. You should monitor your API usage, and never put more budget than you are comfortable with. Some APIs have an \\\"auto-refill\\\" setting that can charge automatically to your card - I strongly recommend you keep this off.\\n\",\n \"\\n\",\n \"2. You should only spend what you are comfortable with. There is a free alternative in Ollama that you can use as a replacement if you wish. DeepSeek, Gemini 2.5 Flash and gpt-4.1-nano are significantly cheaper.\\n\",\n \"\\n\",\n \"Keep in mind that these LLM calls typically involve trillions of floating point calculations - someone has to pay the electricity bills!\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"### Ollama: Free alternative to Paid APIs (but please see Warning about llama version)\\n\",\n \"\\n\",\n \"Ollama is a product that runs locally on your machine. It can run open-source models, and it provides an API endpoint on your computer that is compatible with OpenAI.\\n\",\n \"\\n\",\n \"First, download Ollama by visiting:\\n\",\n \"https://ollama.com\\n\",\n \"\\n\",\n \"Then from your Terminal in Cursor (View menu >> Terminal), run this command to download a model:\\n\",\n \"\\n\",\n \"`ollama pull llama3.2`\\n\",\n \"\\n\",\n \"Be careful not to use llama3.3 or llama4 - these are much larger models that are not suitable for home computers.\\n\",\n \"\\n\",\n \"And now, any time that we have code like: \\n\",\n \"`openai = OpenAI()` \\n\",\n \"You can use this as a direct replacement: \\n\",\n \"`openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')` \\n\",\n \"And also replace model names like **gpt-4o-mini** with **llama3.2**. \\n\",\n \"\\n\",\n \"Below is a full example:\\n\",\n \"\\n\",\n \"```\\n\",\n \"# You need to do this one time on your computer\\n\",\n \"!ollama pull llama3.2\\n\",\n \"\\n\",\n \"from openai import OpenAI\\n\",\n \"MODEL = \\\"llama3.2\\\"\\n\",\n \"openai = OpenAI(base_url=\\\"http://localhost:11434/v1\\\", api_key=\\\"ollama\\\")\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=MODEL,\\n\",\n \" messages=[{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"What is 2 + 2?\\\"}]\\n\",\n \")\\n\",\n \"\\n\",\n \"print(response.choices[0].message.content)\\n\",\n \"```\\n\",\n \"\\n\",\n \"You will need to make similar changes to use Ollama within any of the Agent Frameworks - you should be able to google for an exact example, or ask me.\"\n ]\n }\n ],\n \"metadata\": {\n \"language_info\": {\n \"name\": \"python\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}}, "1_foundations/community_contributions/2_lab2_perplexity_support.ipynb": {"03febf9670d94f5b3aa5e1c9c1ac6d6dd5f2b231": {"t": 1785745494.6100037, "n": 15986, "h": "4185073effecd9fc", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Welcome to the Second Lab - Week 1, Day 3\\n\",\n \"\\n\",\n \"Today we will work with lots of models! This is a way to get comfortable with APIs.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Important point - please read</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">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, <b>after</b> watching the lecture. Add print statements to understand what's going on, and then come up with your own variations.<br/><br/>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 \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Start with imports - ask ChatGPT to explain any package that you don't know\\n\",\n \"\\n\",\n \"import os\\n\",\n \"import json\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from openai import OpenAI\\n\",\n \"from anthropic import Anthropic\\n\",\n \"from IPython.display import Markdown, display\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Always remember to do this!\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Print the key prefixes to help with any debugging\\n\",\n \"\\n\",\n \"openai_api_key = os.getenv('OPENAI_API_KEY')\\n\",\n \"anthropic_api_key = os.getenv('ANTHROPIC_API_KEY')\\n\",\n \"google_api_key = os.getenv('GOOGLE_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"groq_api_key = os.getenv('GROQ_API_KEY')\\n\",\n \"perplexity_api_key = os.getenv('PERPLEXITY_API_KEY')\\n\",\n \"\\n\",\n \"if openai_api_key:\\n\",\n \" print(f\\\"OpenAI API Key exists and begins {openai_api_key[:8]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"OpenAI API Key not set\\\")\\n\",\n \" \\n\",\n \"if anthropic_api_key:\\n\",\n \" print(f\\\"Anthropic API Key exists and begins {anthropic_api_key[:7]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Anthropic API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if google_api_key:\\n\",\n \" print(f\\\"Google API Key exists and begins {google_api_key[:2]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Google API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if deepseek_api_key:\\n\",\n \" print(f\\\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"DeepSeek API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if groq_api_key:\\n\",\n \" print(f\\\"Groq API Key exists and begins {groq_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Groq API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if perplexity_api_key:\\n\",\n \" print(f\\\"Perplexity API Key exists and begins {perplexity_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Perplexity API Key not set (and this is optional)\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"request = \\\"Please come up with a challenging, nuanced question that I can ask a number of LLMs to evaluate their intelligence. \\\"\\n\",\n \"request += \\\"Answer only with the question, no explanation.\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": request}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"openai = OpenAI()\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=\\\"gpt-4o-mini\\\",\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"question = response.choices[0].message.content\\n\",\n \"print(question)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"competitors = []\\n\",\n \"answers = []\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": question}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# The API we know well\\n\",\n \"\\n\",\n \"model_name = \\\"gpt-4o-mini\\\"\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Anthropic has a slightly different API, and Max Tokens is required\\n\",\n \"\\n\",\n \"model_name = \\\"claude-3-7-sonnet-latest\\\"\\n\",\n \"\\n\",\n \"claude = Anthropic()\\n\",\n \"response = claude.messages.create(model=model_name, messages=messages, max_tokens=1000)\\n\",\n \"answer = response.content[0].text\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"gemini = OpenAI(api_key=google_api_key, base_url=\\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\")\\n\",\n \"model_name = \\\"gemini-2.0-flash\\\"\\n\",\n \"\\n\",\n \"response = gemini.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"deepseek = OpenAI(api_key=deepseek_api_key, base_url=\\\"https://api.deepseek.com/v1\\\")\\n\",\n \"model_name = \\\"deepseek-chat\\\"\\n\",\n \"\\n\",\n \"response = deepseek.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"groq = OpenAI(api_key=groq_api_key, base_url=\\\"https://api.groq.com/openai/v1\\\")\\n\",\n \"model_name = \\\"llama-3.3-70b-versatile\\\"\\n\",\n \"\\n\",\n \"response = groq.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"perplexity = OpenAI(api_key=perplexity_api_key, base_url=\\\"https://api.perplexity.ai\\\")\\n\",\n \"model_name = \\\"sonar\\\"\\n\",\n \"\\n\",\n \"response = perplexity.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## For the next cell, we will use Ollama\\n\",\n \"\\n\",\n \"Ollama runs a local web service that gives an OpenAI compatible endpoint, \\n\",\n \"and runs models locally using high performance C++ code.\\n\",\n \"\\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 \"\\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 \"\\n\",\n \"You might need to restart Cursor (and maybe reboot). Then open a Terminal (control+\\\\`) and run `ollama serve`\\n\",\n \"\\n\",\n \"Useful Ollama commands (run these in the terminal, or with an exclamation mark in this notebook):\\n\",\n \"\\n\",\n \"`ollama pull <model_name>` downloads a model locally \\n\",\n \"`ollama ls` lists all the models you've downloaded \\n\",\n \"`ollama rm <model_name>` deletes the specified model from your downloads\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Super important - ignore me at your peril!</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">The model called <b>llama3.3</b> 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 <b>llama3.2</b> or <b>llama3.2:1b</b> and if you want larger, try llama3.1 or smaller variants of Qwen, Gemma, Phi or DeepSeek. See the <A href=\\\"https://ollama.com/models\\\">the Ollama models page</a> for a full list of models and sizes.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"!ollama pull llama3.2\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\\n\",\n \"model_name = \\\"llama3.2\\\"\\n\",\n \"\\n\",\n \"response = ollama.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# So where are we?\\n\",\n \"\\n\",\n \"print(competitors)\\n\",\n \"print(answers)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# It's nice to know how to use \\\"zip\\\"\\n\",\n \"for competitor, answer in zip(competitors, answers):\\n\",\n \" print(f\\\"Competitor: {competitor}\\\\n\\\\n{answer}\\\")\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 20,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Let's bring this together - note the use of \\\"enumerate\\\"\\n\",\n \"\\n\",\n \"together = \\\"\\\"\\n\",\n \"for index, answer in enumerate(answers):\\n\",\n \" together += f\\\"# Response from competitor {index+1}\\\\n\\\\n\\\"\\n\",\n \" together += answer + \\\"\\\\n\\\\n\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(together)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 22,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge = f\\\"\\\"\\\"You are judging a competition between {len(competitors)} competitors.\\n\",\n \"Each model has been given this question:\\n\",\n \"\\n\",\n \"{question}\\n\",\n \"\\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\",\n \"Respond with JSON, and only JSON, with the following format:\\n\",\n \"{{\\\"results\\\": [\\\"best competitor number\\\", \\\"second best competitor number\\\", \\\"third best competitor number\\\", ...]}}\\n\",\n \"\\n\",\n \"Here are the responses from each competitor:\\n\",\n \"\\n\",\n \"{together}\\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\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(judge)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 29,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge_messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": judge}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Judgement time!\\n\",\n \"\\n\",\n \"openai = OpenAI()\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=\\\"o3-mini\\\",\\n\",\n \" messages=judge_messages,\\n\",\n \")\\n\",\n \"results = response.choices[0].message.content\\n\",\n \"print(results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# OK let's turn this into results!\\n\",\n \"\\n\",\n \"results_dict = json.loads(results)\\n\",\n \"ranks = results_dict[\\\"results\\\"]\\n\",\n \"for index, result in enumerate(ranks):\\n\",\n \" competitor = competitors[int(result)-1]\\n\",\n \" print(f\\\"Rank {index+1}: {competitor}\\\")\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/exercise.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Exercise</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">Which pattern(s) did this use? Try updating this to add another Agentic design pattern.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/business.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#00bfff;\\\">Commercial implications</h2>\\n\",\n \" <span style=\\\"color:#00bfff;\\\">These kinds of patterns - to send a task to multiple models, and evaluate results,\\n\",\n \" are common where you need to improve the quality of your LLM response. This approach can be universally applied\\n\",\n \" to business projects where accuracy is critical.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.3\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "b6a03baaf04327334790fbbba8d564606c10a93a": {"t": 1785753630.1723607, "n": 15986, "h": "4185073effecd9fc", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Welcome to the Second Lab - Week 1, Day 3\\n\",\n \"\\n\",\n \"Today we will work with lots of models! This is a way to get comfortable with APIs.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Important point - please read</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">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, <b>after</b> watching the lecture. Add print statements to understand what's going on, and then come up with your own variations.<br/><br/>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 \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Start with imports - ask ChatGPT to explain any package that you don't know\\n\",\n \"\\n\",\n \"import os\\n\",\n \"import json\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from openai import OpenAI\\n\",\n \"from anthropic import Anthropic\\n\",\n \"from IPython.display import Markdown, display\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Always remember to do this!\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Print the key prefixes to help with any debugging\\n\",\n \"\\n\",\n \"openai_api_key = os.getenv('OPENAI_API_KEY')\\n\",\n \"anthropic_api_key = os.getenv('ANTHROPIC_API_KEY')\\n\",\n \"google_api_key = os.getenv('GOOGLE_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"groq_api_key = os.getenv('GROQ_API_KEY')\\n\",\n \"perplexity_api_key = os.getenv('PERPLEXITY_API_KEY')\\n\",\n \"\\n\",\n \"if openai_api_key:\\n\",\n \" print(f\\\"OpenAI API Key exists and begins {openai_api_key[:8]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"OpenAI API Key not set\\\")\\n\",\n \" \\n\",\n \"if anthropic_api_key:\\n\",\n \" print(f\\\"Anthropic API Key exists and begins {anthropic_api_key[:7]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Anthropic API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if google_api_key:\\n\",\n \" print(f\\\"Google API Key exists and begins {google_api_key[:2]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Google API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if deepseek_api_key:\\n\",\n \" print(f\\\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"DeepSeek API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if groq_api_key:\\n\",\n \" print(f\\\"Groq API Key exists and begins {groq_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Groq API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if perplexity_api_key:\\n\",\n \" print(f\\\"Perplexity API Key exists and begins {perplexity_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Perplexity API Key not set (and this is optional)\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"request = \\\"Please come up with a challenging, nuanced question that I can ask a number of LLMs to evaluate their intelligence. \\\"\\n\",\n \"request += \\\"Answer only with the question, no explanation.\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": request}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"openai = OpenAI()\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=\\\"gpt-4o-mini\\\",\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"question = response.choices[0].message.content\\n\",\n \"print(question)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"competitors = []\\n\",\n \"answers = []\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": question}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# The API we know well\\n\",\n \"\\n\",\n \"model_name = \\\"gpt-4o-mini\\\"\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Anthropic has a slightly different API, and Max Tokens is required\\n\",\n \"\\n\",\n \"model_name = \\\"claude-3-7-sonnet-latest\\\"\\n\",\n \"\\n\",\n \"claude = Anthropic()\\n\",\n \"response = claude.messages.create(model=model_name, messages=messages, max_tokens=1000)\\n\",\n \"answer = response.content[0].text\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"gemini = OpenAI(api_key=google_api_key, base_url=\\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\")\\n\",\n \"model_name = \\\"gemini-2.0-flash\\\"\\n\",\n \"\\n\",\n \"response = gemini.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"deepseek = OpenAI(api_key=deepseek_api_key, base_url=\\\"https://api.deepseek.com/v1\\\")\\n\",\n \"model_name = \\\"deepseek-chat\\\"\\n\",\n \"\\n\",\n \"response = deepseek.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"groq = OpenAI(api_key=groq_api_key, base_url=\\\"https://api.groq.com/openai/v1\\\")\\n\",\n \"model_name = \\\"llama-3.3-70b-versatile\\\"\\n\",\n \"\\n\",\n \"response = groq.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"perplexity = OpenAI(api_key=perplexity_api_key, base_url=\\\"https://api.perplexity.ai\\\")\\n\",\n \"model_name = \\\"sonar\\\"\\n\",\n \"\\n\",\n \"response = perplexity.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## For the next cell, we will use Ollama\\n\",\n \"\\n\",\n \"Ollama runs a local web service that gives an OpenAI compatible endpoint, \\n\",\n \"and runs models locally using high performance C++ code.\\n\",\n \"\\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 \"\\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 \"\\n\",\n \"You might need to restart Cursor (and maybe reboot). Then open a Terminal (control+\\\\`) and run `ollama serve`\\n\",\n \"\\n\",\n \"Useful Ollama commands (run these in the terminal, or with an exclamation mark in this notebook):\\n\",\n \"\\n\",\n \"`ollama pull <model_name>` downloads a model locally \\n\",\n \"`ollama ls` lists all the models you've downloaded \\n\",\n \"`ollama rm <model_name>` deletes the specified model from your downloads\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Super important - ignore me at your peril!</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">The model called <b>llama3.3</b> 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 <b>llama3.2</b> or <b>llama3.2:1b</b> and if you want larger, try llama3.1 or smaller variants of Qwen, Gemma, Phi or DeepSeek. See the <A href=\\\"https://ollama.com/models\\\">the Ollama models page</a> for a full list of models and sizes.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"!ollama pull llama3.2\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\\n\",\n \"model_name = \\\"llama3.2\\\"\\n\",\n \"\\n\",\n \"response = ollama.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# So where are we?\\n\",\n \"\\n\",\n \"print(competitors)\\n\",\n \"print(answers)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# It's nice to know how to use \\\"zip\\\"\\n\",\n \"for competitor, answer in zip(competitors, answers):\\n\",\n \" print(f\\\"Competitor: {competitor}\\\\n\\\\n{answer}\\\")\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 20,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Let's bring this together - note the use of \\\"enumerate\\\"\\n\",\n \"\\n\",\n \"together = \\\"\\\"\\n\",\n \"for index, answer in enumerate(answers):\\n\",\n \" together += f\\\"# Response from competitor {index+1}\\\\n\\\\n\\\"\\n\",\n \" together += answer + \\\"\\\\n\\\\n\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(together)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 22,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge = f\\\"\\\"\\\"You are judging a competition between {len(competitors)} competitors.\\n\",\n \"Each model has been given this question:\\n\",\n \"\\n\",\n \"{question}\\n\",\n \"\\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\",\n \"Respond with JSON, and only JSON, with the following format:\\n\",\n \"{{\\\"results\\\": [\\\"best competitor number\\\", \\\"second best competitor number\\\", \\\"third best competitor number\\\", ...]}}\\n\",\n \"\\n\",\n \"Here are the responses from each competitor:\\n\",\n \"\\n\",\n \"{together}\\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\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(judge)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 29,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge_messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": judge}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Judgement time!\\n\",\n \"\\n\",\n \"openai = OpenAI()\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=\\\"o3-mini\\\",\\n\",\n \" messages=judge_messages,\\n\",\n \")\\n\",\n \"results = response.choices[0].message.content\\n\",\n \"print(results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# OK let's turn this into results!\\n\",\n \"\\n\",\n \"results_dict = json.loads(results)\\n\",\n \"ranks = results_dict[\\\"results\\\"]\\n\",\n \"for index, result in enumerate(ranks):\\n\",\n \" competitor = competitors[int(result)-1]\\n\",\n \" print(f\\\"Rank {index+1}: {competitor}\\\")\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/exercise.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Exercise</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">Which pattern(s) did this use? Try updating this to add another Agentic design pattern.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/business.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#00bfff;\\\">Commercial implications</h2>\\n\",\n \" <span style=\\\"color:#00bfff;\\\">These kinds of patterns - to send a task to multiple models, and evaluate results,\\n\",\n \" are common where you need to improve the quality of your LLM response. This approach can be universally applied\\n\",\n \" to business projects where accuracy is critical.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.3\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}, "32536743d505981287b9dd75e879a59d92d9706a": {"t": 1785753632.6201293, "n": 35256, "h": "93a7f05700a73a9d", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## Welcome to the Second Lab - Week 1, Day 3\\n\",\n \"\\n\",\n \"Today we will work with lots of models! This is a way to get comfortable with APIs.\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Important point - please read</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">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, <b>after</b> watching the lecture. Add print statements to understand what's going on, and then come up with your own variations.<br/><br/>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 \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Start with imports - ask ChatGPT to explain any package that you don't know\\n\",\n \"\\n\",\n \"import os\\n\",\n \"import json\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from openai import OpenAI\\n\",\n \"from anthropic import Anthropic\\n\",\n \"from IPython.display import Markdown, display\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 2,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"True\"\n ]\n },\n \"execution_count\": 2,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"# Always remember to do this!\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 3,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\": \"stdout\",\n \"output_type\": \"stream\",\n \"text\": [\n \"OpenAI API Key not set\\n\",\n \"Anthropic API Key not set (and this is optional)\\n\",\n \"Google API Key not set (and this is optional)\\n\",\n \"DeepSeek API Key not set (and this is optional)\\n\",\n \"Groq API Key not set (and this is optional)\\n\",\n \"Perplexity API Key exists and begins pplx\\n\"\n ]\n }\n ],\n \"source\": [\n \"# Print the key prefixes to help with any debugging\\n\",\n \"\\n\",\n \"openai_api_key = os.getenv('OPENAI_API_KEY')\\n\",\n \"anthropic_api_key = os.getenv('ANTHROPIC_API_KEY')\\n\",\n \"google_api_key = os.getenv('GOOGLE_API_KEY')\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"groq_api_key = os.getenv('GROQ_API_KEY')\\n\",\n \"perplexity_api_key = os.getenv('PERPLEXITY_API_KEY')\\n\",\n \"\\n\",\n \"if openai_api_key:\\n\",\n \" print(f\\\"OpenAI API Key exists and begins {openai_api_key[:8]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"OpenAI API Key not set\\\")\\n\",\n \" \\n\",\n \"if anthropic_api_key:\\n\",\n \" print(f\\\"Anthropic API Key exists and begins {anthropic_api_key[:7]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Anthropic API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if google_api_key:\\n\",\n \" print(f\\\"Google API Key exists and begins {google_api_key[:2]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Google API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if deepseek_api_key:\\n\",\n \" print(f\\\"DeepSeek API Key exists and begins {deepseek_api_key[:3]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"DeepSeek API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if groq_api_key:\\n\",\n \" print(f\\\"Groq API Key exists and begins {groq_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Groq API Key not set (and this is optional)\\\")\\n\",\n \"\\n\",\n \"if perplexity_api_key:\\n\",\n \" print(f\\\"Perplexity API Key exists and begins {perplexity_api_key[:4]}\\\")\\n\",\n \"else:\\n\",\n \" print(\\\"Perplexity API Key not set (and this is optional)\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"request = \\\"Please come up with a challenging, nuanced question that I can ask a number of LLMs to evaluate their intelligence. \\\"\\n\",\n \"request += \\\"Answer only with the question, no explanation.\\\"\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": request}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 5,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/plain\": [\n \"[{'role': 'user',\\n\",\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.'}]\"\n ]\n },\n \"execution_count\": 5,\n \"metadata\": {},\n \"output_type\": \"execute_result\"\n }\n ],\n \"source\": [\n \"messages\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"openai = OpenAI()\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=\\\"gpt-4o-mini\\\",\\n\",\n \" messages=messages,\\n\",\n \")\\n\",\n \"question = response.choices[0].message.content\\n\",\n \"print(question)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [\n {\n \"ename\": \"NameError\",\n \"evalue\": \"name 'question' is not defined\",\n \"output_type\": \"error\",\n \"traceback\": [\n \"\\u001b[31m---------------------------------------------------------------------------\\u001b[39m\",\n \"\\u001b[31mNameError\\u001b[39m Traceback (most recent call last)\",\n \"\\u001b[36mCell\\u001b[39m\\u001b[36m \\u001b[39m\\u001b[32mIn[13]\\u001b[39m\\u001b[32m, line 3\\u001b[39m\\n\\u001b[32m 1\\u001b[39m competitors = []\\n\\u001b[32m 2\\u001b[39m answers = []\\n\\u001b[32m----> \\u001b[39m\\u001b[32m3\\u001b[39m messages = [{\\u001b[33m\\\"\\u001b[39m\\u001b[33mrole\\u001b[39m\\u001b[33m\\\"\\u001b[39m: \\u001b[33m\\\"\\u001b[39m\\u001b[33muser\\u001b[39m\\u001b[33m\\\"\\u001b[39m, \\u001b[33m\\\"\\u001b[39m\\u001b[33mcontent\\u001b[39m\\u001b[33m\\\"\\u001b[39m: \\u001b[43mquestion\\u001b[49m}]\\n\",\n \"\\u001b[31mNameError\\u001b[39m: name 'question' is not defined\"\n ]\n }\n ],\n \"source\": [\n \"competitors = []\\n\",\n \"answers = []\\n\",\n \"messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": question}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# The API we know well\\n\",\n \"\\n\",\n \"model_name = \\\"gpt-4o-mini\\\"\\n\",\n \"\\n\",\n \"response = openai.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 11,\n \"metadata\": {},\n \"outputs\": [\n {\n \"ename\": \"TypeError\",\n \"evalue\": \"\\\"Could not resolve authentication method. Expected either api_key or auth_token to be set. Or for one of the `X-Api-Key` or `Authorization` headers to be explicitly omitted\\\"\",\n \"output_type\": \"error\",\n \"traceback\": [\n \"\\u001b[31m---------------------------------------------------------------------------\\u001b[39m\",\n \"\\u001b[31mTypeError\\u001b[39m Traceback (most recent call last)\",\n \"\\u001b[36mCell\\u001b[39m\\u001b[36m \\u001b[39m\\u001b[32mIn[11]\\u001b[39m\\u001b[32m, line 6\\u001b[39m\\n\\u001b[32m 3\\u001b[39m model_name = \\u001b[33m\\\"\\u001b[39m\\u001b[33mclaude-3-7-sonnet-latest\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\n\\u001b[32m 5\\u001b[39m claude = Anthropic()\\n\\u001b[32m----> \\u001b[39m\\u001b[32m6\\u001b[39m response = \\u001b[43mclaude\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mmessages\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mcreate\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43mmodel\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mmodel_name\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmessages\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mmessages\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmax_tokens\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[32;43m1000\\u001b[39;49m\\u001b[43m)\\u001b[49m\\n\\u001b[32m 7\\u001b[39m answer = response.content[\\u001b[32m0\\u001b[39m].text\\n\\u001b[32m 9\\u001b[39m display(Markdown(answer))\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\vkark\\\\workspace\\\\git_workspace\\\\udemy\\\\agenting-ai\\\\community-contributions\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\anthropic\\\\_utils\\\\_utils.py:283\\u001b[39m, in \\u001b[36mrequired_args.<locals>.inner.<locals>.wrapper\\u001b[39m\\u001b[34m(*args, **kwargs)\\u001b[39m\\n\\u001b[32m 281\\u001b[39m msg = \\u001b[33mf\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\u001b[33mMissing required argument: \\u001b[39m\\u001b[38;5;132;01m{\\u001b[39;00mquote(missing[\\u001b[32m0\\u001b[39m])\\u001b[38;5;132;01m}\\u001b[39;00m\\u001b[33m\\\"\\u001b[39m\\n\\u001b[32m 282\\u001b[39m \\u001b[38;5;28;01mraise\\u001b[39;00m \\u001b[38;5;167;01mTypeError\\u001b[39;00m(msg)\\n\\u001b[32m--> \\u001b[39m\\u001b[32m283\\u001b[39m \\u001b[38;5;28;01mreturn\\u001b[39;00m \\u001b[43mfunc\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43m*\\u001b[49m\\u001b[43margs\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43m*\\u001b[49m\\u001b[43m*\\u001b[49m\\u001b[43mkwargs\\u001b[49m\\u001b[43m)\\u001b[49m\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\vkark\\\\workspace\\\\git_workspace\\\\udemy\\\\agenting-ai\\\\community-contributions\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\anthropic\\\\resources\\\\messages\\\\messages.py:978\\u001b[39m, in \\u001b[36mMessages.create\\u001b[39m\\u001b[34m(self, max_tokens, messages, model, metadata, service_tier, stop_sequences, stream, system, temperature, thinking, tool_choice, tools, top_k, top_p, extra_headers, extra_query, extra_body, timeout)\\u001b[39m\\n\\u001b[32m 971\\u001b[39m \\u001b[38;5;28;01mif\\u001b[39;00m model \\u001b[38;5;129;01min\\u001b[39;00m DEPRECATED_MODELS:\\n\\u001b[32m 972\\u001b[39m warnings.warn(\\n\\u001b[32m 973\\u001b[39m \\u001b[33mf\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\u001b[33mThe model \\u001b[39m\\u001b[33m'\\u001b[39m\\u001b[38;5;132;01m{\\u001b[39;00mmodel\\u001b[38;5;132;01m}\\u001b[39;00m\\u001b[33m'\\u001b[39m\\u001b[33m is deprecated and will reach end-of-life on \\u001b[39m\\u001b[38;5;132;01m{\\u001b[39;00mDEPRECATED_MODELS[model]\\u001b[38;5;132;01m}\\u001b[39;00m\\u001b[33m.\\u001b[39m\\u001b[38;5;130;01m\\\\n\\u001b[39;00m\\u001b[33mPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.\\u001b[39m\\u001b[33m\\\"\\u001b[39m,\\n\\u001b[32m 974\\u001b[39m \\u001b[38;5;167;01mDeprecationWarning\\u001b[39;00m,\\n\\u001b[32m 975\\u001b[39m stacklevel=\\u001b[32m3\\u001b[39m,\\n\\u001b[32m 976\\u001b[39m )\\n\\u001b[32m--> \\u001b[39m\\u001b[32m978\\u001b[39m \\u001b[38;5;28;01mreturn\\u001b[39;00m \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[43m.\\u001b[49m\\u001b[43m_post\\u001b[49m\\u001b[43m(\\u001b[49m\\n\\u001b[32m 979\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43m/v1/messages\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 980\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mbody\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mmaybe_transform\\u001b[49m\\u001b[43m(\\u001b[49m\\n\\u001b[32m 981\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m{\\u001b[49m\\n\\u001b[32m 982\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmax_tokens\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmax_tokens\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 983\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmessages\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmessages\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 984\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmodel\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmodel\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 985\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mmetadata\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mmetadata\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 986\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mservice_tier\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mservice_tier\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 987\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mstop_sequences\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstop_sequences\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 988\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mstream\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 989\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43msystem\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43msystem\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 990\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtemperature\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtemperature\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 991\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mthinking\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mthinking\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 992\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtool_choice\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtool_choice\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 993\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtools\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtools\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 994\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtop_k\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtop_k\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 995\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[33;43mtop_p\\u001b[39;49m\\u001b[33;43m\\\"\\u001b[39;49m\\u001b[43m:\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtop_p\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 996\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m}\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 997\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mmessage_create_params\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mMessageCreateParamsStreaming\\u001b[49m\\n\\u001b[32m 998\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[38;5;28;43;01mif\\u001b[39;49;00m\\u001b[43m \\u001b[49m\\u001b[43mstream\\u001b[49m\\n\\u001b[32m 999\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[38;5;28;43;01melse\\u001b[39;49;00m\\u001b[43m \\u001b[49m\\u001b[43mmessage_create_params\\u001b[49m\\u001b[43m.\\u001b[49m\\u001b[43mMessageCreateParamsNonStreaming\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 1000\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m)\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 1001\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43moptions\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mmake_request_options\\u001b[49m\\u001b[43m(\\u001b[49m\\n\\u001b[32m 1002\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mextra_headers\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mextra_headers\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mextra_query\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mextra_query\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mextra_body\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mextra_body\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mtimeout\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mtimeout\\u001b[49m\\n\\u001b[32m 1003\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43m)\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 1004\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mcast_to\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mMessage\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 1005\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[38;5;129;43;01mor\\u001b[39;49;00m\\u001b[43m \\u001b[49m\\u001b[38;5;28;43;01mFalse\\u001b[39;49;00m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 1006\\u001b[39m \\u001b[43m \\u001b[49m\\u001b[43mstream_cls\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mStream\\u001b[49m\\u001b[43m[\\u001b[49m\\u001b[43mRawMessageStreamEvent\\u001b[49m\\u001b[43m]\\u001b[49m\\u001b[43m,\\u001b[49m\\n\\u001b[32m 1007\\u001b[39m \\u001b[43m\\u001b[49m\\u001b[43m)\\u001b[49m\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\vkark\\\\workspace\\\\git_workspace\\\\udemy\\\\agenting-ai\\\\community-contributions\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\anthropic\\\\_base_client.py:1314\\u001b[39m, in \\u001b[36mSyncAPIClient.post\\u001b[39m\\u001b[34m(self, path, cast_to, body, options, files, stream, stream_cls)\\u001b[39m\\n\\u001b[32m 1300\\u001b[39m \\u001b[38;5;28;01mdef\\u001b[39;00m\\u001b[38;5;250m \\u001b[39m\\u001b[34mpost\\u001b[39m(\\n\\u001b[32m 1301\\u001b[39m \\u001b[38;5;28mself\\u001b[39m,\\n\\u001b[32m 1302\\u001b[39m path: \\u001b[38;5;28mstr\\u001b[39m,\\n\\u001b[32m (...)\\u001b[39m\\u001b[32m 1309\\u001b[39m stream_cls: \\u001b[38;5;28mtype\\u001b[39m[_StreamT] | \\u001b[38;5;28;01mNone\\u001b[39;00m = \\u001b[38;5;28;01mNone\\u001b[39;00m,\\n\\u001b[32m 1310\\u001b[39m ) -> ResponseT | _StreamT:\\n\\u001b[32m 1311\\u001b[39m opts = FinalRequestOptions.construct(\\n\\u001b[32m 1312\\u001b[39m method=\\u001b[33m\\\"\\u001b[39m\\u001b[33mpost\\u001b[39m\\u001b[33m\\\"\\u001b[39m, url=path, json_data=body, files=to_httpx_files(files), **options\\n\\u001b[32m 1313\\u001b[39m )\\n\\u001b[32m-> \\u001b[39m\\u001b[32m1314\\u001b[39m \\u001b[38;5;28;01mreturn\\u001b[39;00m cast(ResponseT, \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[43m.\\u001b[49m\\u001b[43mrequest\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43mcast_to\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mopts\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mstream\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstream_cls\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mstream_cls\\u001b[49m\\u001b[43m)\\u001b[49m)\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\vkark\\\\workspace\\\\git_workspace\\\\udemy\\\\agenting-ai\\\\community-contributions\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\anthropic\\\\_base_client.py:1023\\u001b[39m, in \\u001b[36mSyncAPIClient.request\\u001b[39m\\u001b[34m(self, cast_to, options, stream, stream_cls)\\u001b[39m\\n\\u001b[32m 1020\\u001b[39m options = \\u001b[38;5;28mself\\u001b[39m._prepare_options(options)\\n\\u001b[32m 1022\\u001b[39m remaining_retries = max_retries - retries_taken\\n\\u001b[32m-> \\u001b[39m\\u001b[32m1023\\u001b[39m request = \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[43m.\\u001b[49m\\u001b[43m_build_request\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43moptions\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mretries_taken\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mretries_taken\\u001b[49m\\u001b[43m)\\u001b[49m\\n\\u001b[32m 1024\\u001b[39m \\u001b[38;5;28mself\\u001b[39m._prepare_request(request)\\n\\u001b[32m 1026\\u001b[39m kwargs: HttpxSendArgs = {}\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\vkark\\\\workspace\\\\git_workspace\\\\udemy\\\\agenting-ai\\\\community-contributions\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\anthropic\\\\_base_client.py:506\\u001b[39m, in \\u001b[36mBaseClient._build_request\\u001b[39m\\u001b[34m(self, options, retries_taken)\\u001b[39m\\n\\u001b[32m 503\\u001b[39m \\u001b[38;5;28;01melse\\u001b[39;00m:\\n\\u001b[32m 504\\u001b[39m \\u001b[38;5;28;01mraise\\u001b[39;00m \\u001b[38;5;167;01mRuntimeError\\u001b[39;00m(\\u001b[33mf\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\u001b[33mUnexpected JSON data type, \\u001b[39m\\u001b[38;5;132;01m{\\u001b[39;00m\\u001b[38;5;28mtype\\u001b[39m(json_data)\\u001b[38;5;132;01m}\\u001b[39;00m\\u001b[33m, cannot merge with `extra_body`\\u001b[39m\\u001b[33m\\\"\\u001b[39m)\\n\\u001b[32m--> \\u001b[39m\\u001b[32m506\\u001b[39m headers = \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[43m.\\u001b[49m\\u001b[43m_build_headers\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43moptions\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mretries_taken\\u001b[49m\\u001b[43m=\\u001b[49m\\u001b[43mretries_taken\\u001b[49m\\u001b[43m)\\u001b[49m\\n\\u001b[32m 507\\u001b[39m params = _merge_mappings(\\u001b[38;5;28mself\\u001b[39m.default_query, options.params)\\n\\u001b[32m 508\\u001b[39m content_type = headers.get(\\u001b[33m\\\"\\u001b[39m\\u001b[33mContent-Type\\u001b[39m\\u001b[33m\\\"\\u001b[39m)\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\vkark\\\\workspace\\\\git_workspace\\\\udemy\\\\agenting-ai\\\\community-contributions\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\anthropic\\\\_base_client.py:447\\u001b[39m, in \\u001b[36mBaseClient._build_headers\\u001b[39m\\u001b[34m(self, options, retries_taken)\\u001b[39m\\n\\u001b[32m 437\\u001b[39m custom_headers = options.headers \\u001b[38;5;129;01mor\\u001b[39;00m {}\\n\\u001b[32m 438\\u001b[39m headers_dict = _merge_mappings(\\n\\u001b[32m 439\\u001b[39m {\\n\\u001b[32m 440\\u001b[39m \\u001b[33m\\\"\\u001b[39m\\u001b[33mx-stainless-timeout\\u001b[39m\\u001b[33m\\\"\\u001b[39m: \\u001b[38;5;28mstr\\u001b[39m(options.timeout.read)\\n\\u001b[32m (...)\\u001b[39m\\u001b[32m 445\\u001b[39m custom_headers,\\n\\u001b[32m 446\\u001b[39m )\\n\\u001b[32m--> \\u001b[39m\\u001b[32m447\\u001b[39m \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[43m.\\u001b[49m\\u001b[43m_validate_headers\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43mheaders_dict\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mcustom_headers\\u001b[49m\\u001b[43m)\\u001b[49m\\n\\u001b[32m 449\\u001b[39m \\u001b[38;5;66;03m# headers are case-insensitive while dictionaries are not.\\u001b[39;00m\\n\\u001b[32m 450\\u001b[39m headers = httpx.Headers(headers_dict)\\n\",\n \"\\u001b[36mFile \\u001b[39m\\u001b[32mc:\\\\Users\\\\vkark\\\\workspace\\\\git_workspace\\\\udemy\\\\agenting-ai\\\\community-contributions\\\\agents\\\\.venv\\\\Lib\\\\site-packages\\\\anthropic\\\\_client.py:196\\u001b[39m, in \\u001b[36mAnthropic._validate_headers\\u001b[39m\\u001b[34m(self, headers, custom_headers)\\u001b[39m\\n\\u001b[32m 193\\u001b[39m \\u001b[38;5;28;01mif\\u001b[39;00m \\u001b[38;5;28misinstance\\u001b[39m(custom_headers.get(\\u001b[33m\\\"\\u001b[39m\\u001b[33mAuthorization\\u001b[39m\\u001b[33m\\\"\\u001b[39m), Omit):\\n\\u001b[32m 194\\u001b[39m \\u001b[38;5;28;01mreturn\\u001b[39;00m\\n\\u001b[32m--> \\u001b[39m\\u001b[32m196\\u001b[39m \\u001b[38;5;28;01mraise\\u001b[39;00m \\u001b[38;5;167;01mTypeError\\u001b[39;00m(\\n\\u001b[32m 197\\u001b[39m \\u001b[33m'\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\u001b[33mCould not resolve authentication method. Expected either api_key or auth_token to be set. Or for one of the `X-Api-Key` or `Authorization` headers to be explicitly omitted\\u001b[39m\\u001b[33m\\\"\\u001b[39m\\u001b[33m'\\u001b[39m\\n\\u001b[32m 198\\u001b[39m )\\n\",\n \"\\u001b[31mTypeError\\u001b[39m: \\\"Could not resolve authentication method. Expected either api_key or auth_token to be set. Or for one of the `X-Api-Key` or `Authorization` headers to be explicitly omitted\\\"\"\n ]\n }\n ],\n \"source\": [\n \"# Anthropic has a slightly different API, and Max Tokens is required\\n\",\n \"\\n\",\n \"model_name = \\\"claude-3-7-sonnet-latest\\\"\\n\",\n \"\\n\",\n \"claude = Anthropic()\\n\",\n \"response = claude.messages.create(model=model_name, messages=messages, max_tokens=1000)\\n\",\n \"answer = response.content[0].text\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"gemini = OpenAI(api_key=google_api_key, base_url=\\\"https://generativelanguage.googleapis.com/v1beta/openai/\\\")\\n\",\n \"model_name = \\\"gemini-2.0-flash\\\"\\n\",\n \"\\n\",\n \"response = gemini.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"deepseek = OpenAI(api_key=deepseek_api_key, base_url=\\\"https://api.deepseek.com/v1\\\")\\n\",\n \"model_name = \\\"deepseek-chat\\\"\\n\",\n \"\\n\",\n \"response = deepseek.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"groq = OpenAI(api_key=groq_api_key, base_url=\\\"https://api.groq.com/openai/v1\\\")\\n\",\n \"model_name = \\\"llama-3.3-70b-versatile\\\"\\n\",\n \"\\n\",\n \"response = groq.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [\n {\n \"data\": {\n \"text/markdown\": [\n \"If a sealed box contains exactly one red ball and one blue ball, and you draw one ball without looking, then without putting it back, another person draws one ball from the box, what is the probability that the second person draws a red ball given that the first person did not draw a red ball—and how does this probability change if the balls are indistinguishable, only distinguishable by being marked secretly?\"\n ],\n \"text/plain\": [\n \"<IPython.core.display.Markdown object>\"\n ]\n },\n \"metadata\": {},\n \"output_type\": \"display_data\"\n }\n ],\n \"source\": [\n \"perplexity = OpenAI(api_key=perplexity_api_key, base_url=\\\"https://api.perplexity.ai\\\")\\n\",\n \"model_name = \\\"sonar\\\"\\n\",\n \"\\n\",\n \"response = perplexity.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## For the next cell, we will use Ollama\\n\",\n \"\\n\",\n \"Ollama runs a local web service that gives an OpenAI compatible endpoint, \\n\",\n \"and runs models locally using high performance C++ code.\\n\",\n \"\\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 \"\\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 \"\\n\",\n \"You might need to restart Cursor (and maybe reboot). Then open a Terminal (control+\\\\`) and run `ollama serve`\\n\",\n \"\\n\",\n \"Useful Ollama commands (run these in the terminal, or with an exclamation mark in this notebook):\\n\",\n \"\\n\",\n \"`ollama pull <model_name>` downloads a model locally \\n\",\n \"`ollama ls` lists all the models you've downloaded \\n\",\n \"`ollama rm <model_name>` deletes the specified model from your downloads\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/stop.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Super important - ignore me at your peril!</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">The model called <b>llama3.3</b> 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 <b>llama3.2</b> or <b>llama3.2:1b</b> and if you want larger, try llama3.1 or smaller variants of Qwen, Gemma, Phi or DeepSeek. See the <A href=\\\"https://ollama.com/models\\\">the Ollama models page</a> for a full list of models and sizes.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"!ollama pull llama3.2\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\\n\",\n \"model_name = \\\"llama3.2\\\"\\n\",\n \"\\n\",\n \"response = ollama.chat.completions.create(model=model_name, messages=messages)\\n\",\n \"answer = response.choices[0].message.content\\n\",\n \"\\n\",\n \"display(Markdown(answer))\\n\",\n \"competitors.append(model_name)\\n\",\n \"answers.append(answer)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# So where are we?\\n\",\n \"\\n\",\n \"print(competitors)\\n\",\n \"print(answers)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# It's nice to know how to use \\\"zip\\\"\\n\",\n \"for competitor, answer in zip(competitors, answers):\\n\",\n \" print(f\\\"Competitor: {competitor}\\\\n\\\\n{answer}\\\")\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 20,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Let's bring this together - note the use of \\\"enumerate\\\"\\n\",\n \"\\n\",\n \"together = \\\"\\\"\\n\",\n \"for index, answer in enumerate(answers):\\n\",\n \" together += f\\\"# Response from competitor {index+1}\\\\n\\\\n\\\"\\n\",\n \" together += answer + \\\"\\\\n\\\\n\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(together)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 22,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge = f\\\"\\\"\\\"You are judging a competition between {len(competitors)} competitors.\\n\",\n \"Each model has been given this question:\\n\",\n \"\\n\",\n \"{question}\\n\",\n \"\\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\",\n \"Respond with JSON, and only JSON, with the following format:\\n\",\n \"{{\\\"results\\\": [\\\"best competitor number\\\", \\\"second best competitor number\\\", \\\"third best competitor number\\\", ...]}}\\n\",\n \"\\n\",\n \"Here are the responses from each competitor:\\n\",\n \"\\n\",\n \"{together}\\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\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"print(judge)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": 29,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"judge_messages = [{\\\"role\\\": \\\"user\\\", \\\"content\\\": judge}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Judgement time!\\n\",\n \"\\n\",\n \"openai = OpenAI()\\n\",\n \"response = openai.chat.completions.create(\\n\",\n \" model=\\\"o3-mini\\\",\\n\",\n \" messages=judge_messages,\\n\",\n \")\\n\",\n \"results = response.choices[0].message.content\\n\",\n \"print(results)\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# OK let's turn this into results!\\n\",\n \"\\n\",\n \"results_dict = json.loads(results)\\n\",\n \"ranks = results_dict[\\\"results\\\"]\\n\",\n \"for index, result in enumerate(ranks):\\n\",\n \" competitor = competitors[int(result)-1]\\n\",\n \" print(f\\\"Rank {index+1}: {competitor}\\\")\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/exercise.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#ff7800;\\\">Exercise</h2>\\n\",\n \" <span style=\\\"color:#ff7800;\\\">Which pattern(s) did this use? Try updating this to add another Agentic design pattern.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n },\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"<table style=\\\"margin: 0; text-align: left; width:100%\\\">\\n\",\n \" <tr>\\n\",\n \" <td style=\\\"width: 150px; height: 150px; vertical-align: middle;\\\">\\n\",\n \" <img src=\\\"../assets/business.png\\\" width=\\\"150\\\" height=\\\"150\\\" style=\\\"display: block;\\\" />\\n\",\n \" </td>\\n\",\n \" <td>\\n\",\n \" <h2 style=\\\"color:#00bfff;\\\">Commercial implications</h2>\\n\",\n \" <span style=\\\"color:#00bfff;\\\">These kinds of patterns - to send a task to multiple models, and evaluate results,\\n\",\n \" are common where you need to improve the quality of your LLM response. This approach can be universally applied\\n\",\n \" to business projects where accuracy is critical.\\n\",\n \" </span>\\n\",\n \" </td>\\n\",\n \" </tr>\\n\",\n \"</table>\"\n ]\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.3\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}}, "1_foundations/community_contributions/kisali/4_lab4_linkedin_chat_using_tools.ipynb": {"03febf9670d94f5b3aa5e1c9c1ac6d6dd5f2b231": {"t": 1786068256.1604095, "n": 11933, "h": "42644b2e541e5029", "c": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"## AI Project Using Tools\\n\",\n \"\\n\",\n \"This is a chatbot that uses AI tools to make decisions, enhancing it's autonomy feature. It uses pushover SMS integration to send a notification whenever an answer to a question is unknown and recording user details.\\n\",\n \"\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Importing the required libraries\\n\",\n \"\\n\",\n \"from dotenv import load_dotenv\\n\",\n \"from openai import OpenAI\\n\",\n \"import json\\n\",\n \"import os\\n\",\n \"import requests\\n\",\n \"from pypdf import PdfReader\\n\",\n \"import gradio as gr\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Loading environment variables\\n\",\n \"load_dotenv(override=True)\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Set up Pushover credentials and API endpoint\\n\",\n \"\\n\",\n \"deepseek_api_key = os.getenv('DEEPSEEK_API_KEY')\\n\",\n \"pushover_user = os.getenv(\\\"PUSHOVER_USER\\\")\\n\",\n \"pushover_token = os.getenv(\\\"PUSHOVER_TOKEN\\\")\\n\",\n \"pushover_url = \\\"https://api.pushover.net/1/messages.json\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Setting up Deepseek Client\\n\",\n \"\\n\",\n \"deepseek_client = OpenAI(\\n\",\n \" api_key=deepseek_api_key, \\n\",\n \" base_url=\\\"https://api.deepseek.com\\\"\\n\",\n \")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Function to send a push notification via pushover and test sending a push notification\\n\",\n \"def push(message):\\n\",\n \" print(f\\\"Push: {message}\\\")\\n\",\n \" payload = {\\\"user\\\": pushover_user, \\\"token\\\": pushover_token, \\\"message\\\": message}\\n\",\n \" requests.post(pushover_url, data=payload)\\n\",\n \"push(\\\"Hey! This is a test notification\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\" Record user details an send a push notification\\n\",\n \"- email: email address that will be provided by the user\\n\",\n \"- name: name provided by user, default respond with Name not provided\\n\",\n \"- notes: information provided by user, default respond with not provided\\n\",\n \"\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"def record_user_details(email, name=\\\"Name not provided\\\", notes=\\\"not provided\\\"):\\n\",\n \" push(f\\\"Recording interest from {name} with email {email} and notes {notes}\\\")\\n\",\n \" return {\\\"recorded\\\": \\\"ok\\\"}\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\" Function to record an unknown question and send a push notification\\n\",\n \"- question: question that is out of context\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"def record_unknown_question(question):\\n\",\n \" push(f\\\"Recording {question} asked that I couldn't answer\\\")\\n\",\n \" return {\\\"recorded\\\": \\\"ok\\\"}\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\" First tool called record_user_details with a JSON schema\\n\",\n \"This tool get the email address of user(mandatory), name(optional) and notes(optional) if the user wants to get in touch\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"record_user_details_json = {\\n\",\n \" \\\"name\\\": \\\"record_user_details\\\",\\n\",\n \" \\\"description\\\": \\\"Use this tool to record that a user is interested in being in touch and provided an email address\\\",\\n\",\n \" \\\"parameters\\\": {\\n\",\n \" \\\"type\\\": \\\"object\\\",\\n\",\n \" \\\"properties\\\": {\\n\",\n \" \\\"email\\\": {\\n\",\n \" \\\"type\\\": \\\"string\\\",\\n\",\n \" \\\"description\\\": \\\"The email address of this user\\\"\\n\",\n \" },\\n\",\n \" \\\"name\\\": {\\n\",\n \" \\\"type\\\": \\\"string\\\",\\n\",\n \" \\\"description\\\": \\\"The user's name, if they provided it\\\"\\n\",\n \" }\\n\",\n \" ,\\n\",\n \" \\\"notes\\\": {\\n\",\n \" \\\"type\\\": \\\"string\\\",\\n\",\n \" \\\"description\\\": \\\"Any additional information about the conversation that's worth recording to give context\\\"\\n\",\n \" }\\n\",\n \" },\\n\",\n \" \\\"required\\\": [\\\"email\\\"],\\n\",\n \" \\\"additionalProperties\\\": False\\n\",\n \" }\\n\",\n \"}\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"\\\"\\\"\\\" Second tool called record_unknown_question with a JSON schema\\n\",\n \"This tool will record the question that is unknown and couldn't be answered. The question field is mandatory.\\n\",\n \"\\\"\\\"\\\"\\n\",\n \"record_unknown_question_json = {\\n\",\n \" \\\"name\\\": \\\"record_unknown_question\\\",\\n\",\n \" \\\"description\\\": \\\"Always use this tool to record any question that couldn't be answered as you didn't know the answer\\\",\\n\",\n \" \\\"parameters\\\": {\\n\",\n \" \\\"type\\\": \\\"object\\\",\\n\",\n \" \\\"properties\\\": {\\n\",\n \" \\\"question\\\": {\\n\",\n \" \\\"type\\\": \\\"string\\\",\\n\",\n \" \\\"description\\\": \\\"The question that couldn't be answered\\\"\\n\",\n \" },\\n\",\n \" },\\n\",\n \" \\\"required\\\": [\\\"question\\\"],\\n\",\n \" \\\"additionalProperties\\\": False\\n\",\n \" }\\n\",\n \"}\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# This is a list of the two tools confurd and can be called by an LLM\\n\",\n \"tools = [{\\\"type\\\": \\\"function\\\", \\\"function\\\": record_user_details_json},\\n\",\n \" {\\\"type\\\": \\\"function\\\", \\\"function\\\": record_unknown_question_json}]\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"tools\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# This function can take a list of tool calls, and run them using if logic.\\n\",\n \"\\n\",\n \"def handle_tool_calls(tool_calls):\\n\",\n \" results = []\\n\",\n \" for tool_call in tool_calls:\\n\",\n \" tool_name = tool_call.function.name\\n\",\n \" arguments = json.loads(tool_call.function.arguments)\\n\",\n \" print(f\\\"Tool called: {tool_name}\\\", flush=True)\\n\",\n \"\\n\",\n \" if tool_name == \\\"record_user_details\\\":\\n\",\n \" result = record_user_details(**arguments)\\n\",\n \" elif tool_name == \\\"record_unknown_question\\\":\\n\",\n \" result = record_unknown_question(**arguments)\\n\",\n \"\\n\",\n \" results.append({\\\"role\\\": \\\"tool\\\",\\\"content\\\": json.dumps(result),\\\"tool_call_id\\\": tool_call.id})\\n\",\n \" return results\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Test the record_unknown_question tool directly\\n\",\n \"globals()[\\\"record_unknown_question\\\"](\\\"this is a really hard question\\\")\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Handle tool calls dynamically using globals() (preferred version)\\n\",\n \"\\n\",\n \"def handle_tool_calls(tool_calls):\\n\",\n \" results = []\\n\",\n \" for tool_call in tool_calls:\\n\",\n \" tool_name = tool_call.function.name\\n\",\n \" arguments = json.loads(tool_call.function.arguments)\\n\",\n \" print(f\\\"Tool called: {tool_name}\\\", flush=True)\\n\",\n \" tool = globals().get(tool_name)\\n\",\n \" result = tool(**arguments) if tool else {}\\n\",\n \" results.append({\\\"role\\\": \\\"tool\\\",\\\"content\\\": json.dumps(result),\\\"tool_call_id\\\": tool_call.id})\\n\",\n \" return results\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Load LinkedIn PDF and summary.txt for user context\\n\",\n \"reader = PdfReader(\\\"me/Profile.pdf\\\")\\n\",\n \"linkedin = \\\"\\\"\\n\",\n \"for page in reader.pages:\\n\",\n \" text = page.extract_text()\\n\",\n \" if text:\\n\",\n \" linkedin += text\\n\",\n \"\\n\",\n \"with open(\\\"me/summary.txt\\\", \\\"r\\\", encoding=\\\"utf-8\\\") as f:\\n\",\n \" summary = f.read()\\n\",\n \"\\n\",\n \"name = \\\"Ian Kisali\\\"\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Build the system prompt for the LLM, including user info and context\\n\",\n \"system_prompt = f\\\"You are acting as {name}. You are answering questions on {name}'s website, \\\\\\n\",\n \"particularly questions related to {name}'s career, background, skills and experience. \\\\\\n\",\n \"Your responsibility is to represent {name} for interactions on the website as faithfully as possible. \\\\\\n\",\n \"You are given a summary of {name}'s background and LinkedIn profile which you can use to answer questions. \\\\\\n\",\n \"Be professional and engaging, as if talking to a potential client or future employer who came across the website. \\\\\\n\",\n \"If you don't know the answer to any question, use your record_unknown_question tool to record the question that you couldn't answer, even if it's about something trivial or unrelated to career. \\\\\\n\",\n \"If the user is engaging in discussion, try to steer them towards getting in touch via email; ask for their email and record it using your record_user_details tool. \\\"\\n\",\n \"\\n\",\n \"system_prompt += f\\\"\\\\n\\\\n## Summary:\\\\n{summary}\\\\n\\\\n## LinkedIn Profile:\\\\n{linkedin}\\\\n\\\\n\\\"\\n\",\n \"system_prompt += f\\\"With this context, please chat with the user, always staying in character as {name}.\\\"\\n\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Main chat function: interacts with LLM, handles tool calls, manages history\\n\",\n \"def chat(message, history):\\n\",\n \" messages = [{\\\"role\\\": \\\"system\\\", \\\"content\\\": system_prompt}] + history + [{\\\"role\\\": \\\"user\\\", \\\"content\\\": message}]\\n\",\n \" done = False\\n\",\n \" while not done:\\n\",\n \"\\n\",\n \" # This is the call to the LLM - see that we pass in the tools json\\n\",\n \"\\n\",\n \" response = deepseek_client.chat.completions.create(model=\\\"deepseek-chat\\\", messages=messages, tools=tools)\\n\",\n \"\\n\",\n \" finish_reason = response.choices[0].finish_reason\\n\",\n \" \\n\",\n \" # If the LLM wants to call a tool, we do that!\\n\",\n \" \\n\",\n \" if finish_reason==\\\"tool_calls\\\":\\n\",\n \" message = response.choices[0].message\\n\",\n \" tool_calls = message.tool_calls\\n\",\n \" results = handle_tool_calls(tool_calls)\\n\",\n \" messages.append(message)\\n\",\n \" messages.extend(results)\\n\",\n \" else:\\n\",\n \" done = True\\n\",\n \" return response.choices[0].message.content\"\n ]\n },\n {\n \"cell_type\": \"code\",\n \"execution_count\": null,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n \"# Launch Gradio chat interface with the chat function\\n\",\n \"gr.ChatInterface(chat, type=\\\"messages\\\").launch()\"\n ]\n }\n ],\n \"metadata\": {\n \"kernelspec\": {\n \"display_name\": \".venv\",\n \"language\": \"python\",\n \"name\": \"python3\"\n },\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_extension\": \".py\",\n \"mimetype\": \"text/x-python\",\n \"name\": \"python\",\n \"nbconvert_exporter\": \"python\",\n \"pygments_lexer\": \"ipython3\",\n \"version\": \"3.12.1\"\n }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"}}}} |