File size: 7,183 Bytes
c82bf42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
{
 "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
}