{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Function Calling Example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 0. Import OpenAI API Key\n", "- Firstly, load OpenAI API key from `.env` file\n", "- Please create a .env file in the root directory of this project\n", "and add `OPENAI_API_KEY=sk-*******`\n", "or just replace the value of OPENAI_API_KEY below!" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from os import environ\n", "from dotenv import load_dotenv\n", "\n", "\n", "load_dotenv()\n", "OPENAI_API_KEY = environ[\"OPENAI_API_KEY\"]\n", "assert OPENAI_API_KEY is not None, \"Please set OPENAI_API_KEY in .env file\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1. Load function call from FunctionCalls class\n", "\n", "- `FunctionCalls` class is a collection of functions.\n", "- It contains many pre-defined functions.\n", "- The functions will be parsed into `FunctionCall` objects only once when Python starts.\n", "- You can get `FunctionCall` object by calling `FunctionCalls.get_function_call` method.\n", "- The argument of `FunctionCalls.get_function_call` method is a function to parse." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "from typing import Literal\n", "from app.models.function_calling.base import FunctionCall\n", "from app.models.function_calling.functions import FunctionCalls\n", "\n", "web_search_function: FunctionCall = FunctionCalls.get_function_call(\n", " FunctionCalls.web_search\n", ")\n", "\n", "# `functions` contains a list of all the functions that can be called\n", "functions: list[FunctionCall] = [web_search_function]\n", "\n", "# \"auto\" will automatically select a function based on the prompt\n", "function_call: FunctionCall | Literal[\"auto\", \"none\"] = \"auto\"\n", "\n", "# \"none\" will not call any function\n", "function_call = \"none\"\n", "\n", "# A specific function is forcibly called by passing the function call object.\n", "# NOTE: `function_call` must be in the `functions`,\n", "# if you define `function_call` as a `FunctionCall` object.\n", "function_call = web_search_function" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "- function name: web_search\n", "- function arguments: {'query_to_search': 'current price of AAPL stock'}\n" ] } ], "source": [ "from app.models.completion_models import FunctionCallParsed\n", "from app.utils.function_calling.request import request_function_call\n", "\n", "# `messages` contains a list of messages to send\n", "messages: list[dict[str, str]] = [\n", " {\"role\": \"user\", \"content\": \"What is price of AAPL now?\"}\n", "]\n", "\n", "# `function_call_parsed` is a dictionary containing `name` and `arguments` of the function call\n", "# NOTE:\n", "function_call_parsed: FunctionCallParsed = await request_function_call(\n", " messages=messages,\n", " functions=functions,\n", " function_call=function_call,\n", " model=\"gpt-3.5-turbo\",\n", " api_key=OPENAI_API_KEY,\n", ")\n", "\n", "print(f\"- function name: {function_call_parsed['name']}\")\n", "print(f\"- function arguments: {function_call_parsed.get('arguments')}\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from typing import Optional\n", "from app.models.completion_models import FunctionCallParsed\n", "from app.utils.function_calling.request import request_function_call\n", "\n", "# `messages` contains a list of messages to send\n", "messages: list[dict[str, str]] = [\n", " {\"role\": \"user\", \"content\": \"What is price of AAPL now?\"}\n", "]\n", "\n", "# `function_call_parsed` is a dictionary containing `name` and `arguments` of the function call\n", "# NOTE: if `function_call` is \"none\", an error will be raised when requesting a function call.\n", "is_error_raised: bool = False\n", "try:\n", " function_call_parsed: Optional[\n", " FunctionCallParsed\n", " ] = await request_function_call(\n", " messages=messages,\n", " functions=functions,\n", " function_call=\"none\",\n", " model=\"gpt-3.5-turbo\",\n", " api_key=OPENAI_API_KEY,\n", " )\n", "except ValueError:\n", " is_error_raised = True\n", "\n", "assert is_error_raised" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. Define a custom function" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "- function name: weather\n", "- function arguments: {'location': 'Boston', 'unit': 'celsius'}\n" ] } ], "source": [ "from typing import Annotated\n", "from app.utils.function_calling.parser import parse_function_call_from_function\n", "from app.utils.function_calling.request import request_function_call\n", "\n", "\n", "def weather(\n", " location: Annotated[\n", " str,\n", " \"The location to get the weather for.\",\n", " ],\n", " unit: Annotated[\n", " str,\n", " [\"celsius\", \"fahrenheit\"],\n", " \"The unit of temperature.\",\n", " ],\n", "):\n", " \"\"\"Get the weather for a location.\"\"\"\n", " pass\n", "\n", "\n", "messages: list[dict[str, str]] = [\n", " {\"role\": \"user\", \"content\": \"What’s the weather like in Boston?\"}\n", "]\n", "function_call: FunctionCall = parse_function_call_from_function(weather)\n", "functions: list[FunctionCall] = [function_call]\n", "function_call_parsed: FunctionCallParsed = await request_function_call(\n", " messages=messages,\n", " functions=functions,\n", " function_call=function_call,\n", " model=\"gpt-3.5-turbo\",\n", " api_key=OPENAI_API_KEY,\n", ")\n", "print(f\"- function name: {function_call_parsed['name']}\")\n", "print(f\"- function arguments: {function_call_parsed.get('arguments')}\")" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.4" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }