|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "id": "d006b2ea-9dfe-49c7-88a9-a5a0775185fd", |
| 6 | + "metadata": {}, |
| 7 | + "source": [ |
| 8 | + "# A tool to evaluate a mathematical expression\n", |
| 9 | + "\n", |
| 10 | + "This week the tool used in FlightAI was a database lookup function.\n", |
| 11 | + "\n", |
| 12 | + "Here I implement a python code interpreter function as tool." |
| 13 | + ] |
| 14 | + }, |
| 15 | + { |
| 16 | + "cell_type": "code", |
| 17 | + "execution_count": null, |
| 18 | + "id": "7b0e8691-71f9-486c-859d-ea371401dfa9", |
| 19 | + "metadata": {}, |
| 20 | + "outputs": [], |
| 21 | + "source": [ |
| 22 | + "import os\n", |
| 23 | + "import json\n", |
| 24 | + "from dotenv import load_dotenv\n", |
| 25 | + "from openai import OpenAI\n", |
| 26 | + "import gradio as gr" |
| 27 | + ] |
| 28 | + }, |
| 29 | + { |
| 30 | + "cell_type": "code", |
| 31 | + "execution_count": null, |
| 32 | + "id": "8e2792ae-ff53-4b83-b2c3-866533ba2b29", |
| 33 | + "metadata": {}, |
| 34 | + "outputs": [], |
| 35 | + "source": [ |
| 36 | + "# Load environment variables in a file called .env\n", |
| 37 | + "# Print the key prefixes to help with any debugging\n", |
| 38 | + "\n", |
| 39 | + "load_dotenv()\n", |
| 40 | + "openai_api_key = os.getenv('OPENAI_API_KEY')\n", |
| 41 | + "anthropic_api_key = os.getenv('ANTHROPIC_API_KEY')\n", |
| 42 | + "google_api_key = os.getenv('GOOGLE_API_KEY')\n", |
| 43 | + "\n", |
| 44 | + "if openai_api_key:\n", |
| 45 | + " print(f\"OpenAI API Key exists and begins {openai_api_key[:8]}\")\n", |
| 46 | + "else:\n", |
| 47 | + " print(\"OpenAI API Key not set\")\n", |
| 48 | + " \n", |
| 49 | + "if anthropic_api_key:\n", |
| 50 | + " print(f\"Anthropic API Key exists and begins {anthropic_api_key[:7]}\")\n", |
| 51 | + "else:\n", |
| 52 | + " print(\"Anthropic API Key not set\")\n", |
| 53 | + "\n", |
| 54 | + "if google_api_key:\n", |
| 55 | + " print(f\"Google API Key exists and begins {google_api_key[:8]}\")\n", |
| 56 | + "else:\n", |
| 57 | + " print(\"Google API Key not set\")" |
| 58 | + ] |
| 59 | + }, |
| 60 | + { |
| 61 | + "cell_type": "code", |
| 62 | + "execution_count": null, |
| 63 | + "id": "79e44ee9-af02-448c-a747-17780ee55791", |
| 64 | + "metadata": {}, |
| 65 | + "outputs": [], |
| 66 | + "source": [ |
| 67 | + "openai = OpenAI()\n", |
| 68 | + "MODEL = \"gpt-4o-mini\"" |
| 69 | + ] |
| 70 | + }, |
| 71 | + { |
| 72 | + "cell_type": "markdown", |
| 73 | + "id": "33ec55b1-0eff-43f1-9346-28145fa2fc47", |
| 74 | + "metadata": {}, |
| 75 | + "source": [ |
| 76 | + "# Defining the tool function\n", |
| 77 | + "\n", |
| 78 | + "Add print statements to make sure the function is used instead of the native gpt interpreter capability.\n", |
| 79 | + "\n", |
| 80 | + "I used multi shot in the system prompt to make sure gpt generate the code in the format that the tool accept." |
| 81 | + ] |
| 82 | + }, |
| 83 | + { |
| 84 | + "cell_type": "code", |
| 85 | + "execution_count": null, |
| 86 | + "id": "94e0e171-4975-457b-88cb-c0d90f51ca65", |
| 87 | + "metadata": {}, |
| 88 | + "outputs": [], |
| 89 | + "source": [ |
| 90 | + "def evaluate_math_expression(my_code):\n", |
| 91 | + " print(f\"EXECUTING FUNCTION WITH CODE: {my_code}\")\n", |
| 92 | + " exec(my_code)\n", |
| 93 | + " r = locals()['interpreter_result'] \n", |
| 94 | + " return r\n", |
| 95 | + "\n", |
| 96 | + "\n", |
| 97 | + "math_function = {\n", |
| 98 | + " \"name\": \"evaluate_math_expression\",\n", |
| 99 | + " \"description\": \"Give the result of a math expression. \\\n", |
| 100 | + " Call this whenever you need to know the result of a mathematical expression. \\\n", |
| 101 | + " Generate python code ALWAYS with the final result assigned to a variable called 'interpreter_result'. \\\n", |
| 102 | + " For example when a user asks 'What is 2+2' generate 'interpreter_result = 2+2', and pass this code to the tool. \\\n", |
| 103 | + " Another example if a user ask 'What is log(5)' generate 'import math; interpreter_result = math.log(5)' and pass this code to the tool.\",\n", |
| 104 | + " \n", |
| 105 | + " \"parameters\": {\n", |
| 106 | + " \"type\": \"object\",\n", |
| 107 | + " \"properties\": {\n", |
| 108 | + " \"my_code\": {\n", |
| 109 | + " \"type\": \"string\",\n", |
| 110 | + " \"description\": \"The python math expression to evaluate\",\n", |
| 111 | + " },\n", |
| 112 | + " },\n", |
| 113 | + " \"required\": [\"my_code\"],\n", |
| 114 | + " \"additionalProperties\": False\n", |
| 115 | + " }\n", |
| 116 | + "}\n", |
| 117 | + "\n", |
| 118 | + "tools = [{\"type\": \"function\", \"function\": math_function}]" |
| 119 | + ] |
| 120 | + }, |
| 121 | + { |
| 122 | + "cell_type": "code", |
| 123 | + "execution_count": null, |
| 124 | + "id": "c85c01cc-776e-4a9d-b506-ea0d68fc072d", |
| 125 | + "metadata": {}, |
| 126 | + "outputs": [], |
| 127 | + "source": [ |
| 128 | + "evaluate_math_expression(\"import math; interpreter_result = math.log(5)\")" |
| 129 | + ] |
| 130 | + }, |
| 131 | + { |
| 132 | + "cell_type": "markdown", |
| 133 | + "id": "858c5848-5835-4dff-9dc0-68babd367e11", |
| 134 | + "metadata": {}, |
| 135 | + "source": [ |
| 136 | + "# Using the tool in a UI program\n", |
| 137 | + "\n", |
| 138 | + "You can ask messages like:\n", |
| 139 | + "- \"What is 2+2?\"\n", |
| 140 | + "- \"What is 3 power 2?\"\n", |
| 141 | + "- \"I have 25 apples. I buy 10 apples. How manny apples do I have?\"" |
| 142 | + ] |
| 143 | + }, |
| 144 | + { |
| 145 | + "cell_type": "code", |
| 146 | + "execution_count": null, |
| 147 | + "id": "c119b48b-d4b4-41ae-aa2f-2ec2f09af2f0", |
| 148 | + "metadata": {}, |
| 149 | + "outputs": [], |
| 150 | + "source": [ |
| 151 | + "system_message = \"You are a math assistant. \\\n", |
| 152 | + "Generate python code to give result of a math expression, always name the result 'interpreter_result'. \\\n", |
| 153 | + "For example when a user asks 'What is 2+2', generate 'interpreter_result = 2+2' and pass this code to the tool. \\\n", |
| 154 | + "Another example: if a user ask 'What is log(5)' generate 'import math; interpreter_result = math.log(5)'\"\n", |
| 155 | + "\n", |
| 156 | + "def chat(message, history):\n", |
| 157 | + " messages = [{\"role\": \"system\", \"content\": system_message}] + history + [{\"role\": \"user\", \"content\": message}]\n", |
| 158 | + " response = openai.chat.completions.create(model=MODEL, messages=messages, tools=tools)\n", |
| 159 | + "\n", |
| 160 | + " if response.choices[0].finish_reason==\"tool_calls\":\n", |
| 161 | + " message = response.choices[0].message\n", |
| 162 | + " print(message)\n", |
| 163 | + " response = handle_tool_call(message)\n", |
| 164 | + " print(response)\n", |
| 165 | + " messages.append(message)\n", |
| 166 | + " messages.append(response)\n", |
| 167 | + " response = openai.chat.completions.create(model=MODEL, messages=messages)\n", |
| 168 | + " \n", |
| 169 | + " return response.choices[0].message.content\n", |
| 170 | + "\n", |
| 171 | + "\n", |
| 172 | + "def handle_tool_call(message):\n", |
| 173 | + " tool_call = message.tool_calls[0]\n", |
| 174 | + " arguments = json.loads(tool_call.function.arguments)\n", |
| 175 | + " my_code = arguments.get('my_code')\n", |
| 176 | + " interpreter_result = evaluate_math_expression(my_code)\n", |
| 177 | + " response = {\n", |
| 178 | + " \"role\": \"tool\",\n", |
| 179 | + " \"content\": json.dumps({\"my_code\": my_code,\"interpreter_result\": interpreter_result}),\n", |
| 180 | + " \"tool_call_id\": tool_call.id\n", |
| 181 | + " }\n", |
| 182 | + " return response" |
| 183 | + ] |
| 184 | + }, |
| 185 | + { |
| 186 | + "cell_type": "code", |
| 187 | + "execution_count": null, |
| 188 | + "id": "a3e50093-d7b6-4972-a8ba-6964f22218d3", |
| 189 | + "metadata": {}, |
| 190 | + "outputs": [], |
| 191 | + "source": [ |
| 192 | + "gr.ChatInterface(fn=chat, type=\"messages\").launch()" |
| 193 | + ] |
| 194 | + }, |
| 195 | + { |
| 196 | + "cell_type": "code", |
| 197 | + "execution_count": null, |
| 198 | + "id": "75c81d73-d2d6-4e6b-8511-94d4a725f595", |
| 199 | + "metadata": {}, |
| 200 | + "outputs": [], |
| 201 | + "source": [] |
| 202 | + } |
| 203 | + ], |
| 204 | + "metadata": { |
| 205 | + "kernelspec": { |
| 206 | + "display_name": "Python 3 (ipykernel)", |
| 207 | + "language": "python", |
| 208 | + "name": "python3" |
| 209 | + }, |
| 210 | + "language_info": { |
| 211 | + "codemirror_mode": { |
| 212 | + "name": "ipython", |
| 213 | + "version": 3 |
| 214 | + }, |
| 215 | + "file_extension": ".py", |
| 216 | + "mimetype": "text/x-python", |
| 217 | + "name": "python", |
| 218 | + "nbconvert_exporter": "python", |
| 219 | + "pygments_lexer": "ipython3", |
| 220 | + "version": "3.11.11" |
| 221 | + } |
| 222 | + }, |
| 223 | + "nbformat": 4, |
| 224 | + "nbformat_minor": 5 |
| 225 | +} |
0 commit comments