{"id":96974,"date":"2025-02-11T08:55:43","date_gmt":"2025-02-11T05:25:43","guid":{"rendered":"https:\/\/nabfollower.com\/blog\/openai-tool-calling-example-45l6\/"},"modified":"2025-02-11T08:55:43","modified_gmt":"2025-02-11T05:25:43","slug":"openai-tool-calling-example-45l6","status":"publish","type":"post","link":"https:\/\/nabfollower.com\/blog\/openai-tool-calling-example-45l6\/","title":{"rendered":"\u0627\u0628\u0632\u0627\u0631 OpenAi \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644 &#8211; \u062c\u0627\u0645\u0639\u0647 dev"},"content":{"rendered":"<div data-article-id=\"2270484\" id=\"article-body\">\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">from<\/span> <span class=\"n\">json<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">loads<\/span>\n<span class=\"kn\">from<\/span> <span class=\"n\">signal<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">signal<\/span><span class=\"p\">,<\/span> <span class=\"n\">SIGINT<\/span>\n\n<span class=\"kn\">from<\/span> <span class=\"n\">requests<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">get<\/span>  <span class=\"c1\"># pip install requests\n<\/span><span class=\"kn\">from<\/span> <span class=\"n\">openai<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">OpenAI<\/span>  <span class=\"c1\"># pip install openai\n<\/span>\n<span class=\"c1\"># suppressing \"KeyboardInterrupt\" message\n<\/span><span class=\"nf\">signal<\/span><span class=\"p\">(<\/span><span class=\"n\">SIGINT<\/span><span class=\"p\">,<\/span> <span class=\"k\">lambda<\/span> <span class=\"n\">_<\/span><span class=\"p\">,<\/span> <span class=\"n\">__<\/span><span class=\"p\">:<\/span> <span class=\"nf\">exit<\/span><span class=\"p\">())<\/span>\n\n\n<span class=\"k\">def<\/span> <span class=\"nf\">get_weather<\/span><span class=\"p\">(<\/span><span class=\"n\">latitude<\/span><span class=\"p\">,<\/span> <span class=\"n\">longitude<\/span><span class=\"p\">):<\/span>\n    <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">https:\/\/api.open-meteo.com\/v1\/forecast?latitude=<\/span><span class=\"si\">{<\/span><span class=\"n\">latitude<\/span><span class=\"si\">}<\/span><span class=\"s\">&amp;longitude=<\/span><span class=\"si\">{<\/span><span class=\"n\">longitude<\/span><span class=\"si\">}<\/span><span class=\"s\">&amp;current=temperature_2m<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">data<\/span> <span class=\"o\">=<\/span> <span class=\"n\">response<\/span><span class=\"p\">.<\/span><span class=\"nf\">json<\/span><span class=\"p\">()<\/span>\n    <span class=\"n\">temperature<\/span> <span class=\"o\">=<\/span> <span class=\"n\">data<\/span><span class=\"p\">[<\/span><span class=\"sh\">'<\/span><span class=\"s\">current<\/span><span class=\"sh\">'<\/span><span class=\"p\">][<\/span><span class=\"sh\">'<\/span><span class=\"s\">temperature_2m<\/span><span class=\"sh\">'<\/span><span class=\"p\">]<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">temperature<\/span><span class=\"p\">)<\/span>\n\n\n<span class=\"n\">tools<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[{<\/span>\n    <span class=\"sh\">\"<\/span><span class=\"s\">type<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">function<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span>\n    <span class=\"sh\">\"<\/span><span class=\"s\">function<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n        <span class=\"sh\">\"<\/span><span class=\"s\">name<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">get_weather<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span>\n        <span class=\"sh\">\"<\/span><span class=\"s\">description<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">Get current temperature for provided coordinates in celsius.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span>\n        <span class=\"sh\">\"<\/span><span class=\"s\">parameters<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">type<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">object<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">properties<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\n                <span class=\"sh\">\"<\/span><span class=\"s\">latitude<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span><span class=\"sh\">\"<\/span><span class=\"s\">type<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">number<\/span><span class=\"sh\">\"<\/span><span class=\"p\">},<\/span>\n                <span class=\"sh\">\"<\/span><span class=\"s\">longitude<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span><span class=\"sh\">\"<\/span><span class=\"s\">type<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">number<\/span><span class=\"sh\">\"<\/span><span class=\"p\">}<\/span>\n            <span class=\"p\">},<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">required<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">latitude<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">longitude<\/span><span class=\"sh\">\"<\/span><span class=\"p\">],<\/span>\n            <span class=\"sh\">\"<\/span><span class=\"s\">additionalProperties<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"bp\">False<\/span>\n        <span class=\"p\">},<\/span>\n        <span class=\"sh\">\"<\/span><span class=\"s\">strict<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"bp\">True<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}]<\/span>\n\n<span class=\"c1\"># OpenAI client and chat history with the first (system) message\n<\/span><span class=\"n\">client<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">OpenAI<\/span><span class=\"p\">()<\/span>\n<span class=\"n\">messages<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[{<\/span><span class=\"sh\">\"<\/span><span class=\"s\">role<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">system<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">content<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">You are a weather assistant.<\/span><span class=\"sh\">\"<\/span><span class=\"p\">}]<\/span>\n\n<span class=\"k\">while<\/span> <span class=\"bp\">True<\/span><span class=\"p\">:<\/span>\n\n    <span class=\"c1\"># sending message and getting a response back (chat completion)\n<\/span>    <span class=\"n\">completion<\/span> <span class=\"o\">=<\/span> <span class=\"n\">client<\/span><span class=\"p\">.<\/span><span class=\"n\">chat<\/span><span class=\"p\">.<\/span><span class=\"n\">completions<\/span><span class=\"p\">.<\/span><span class=\"nf\">create<\/span><span class=\"p\">(<\/span><span class=\"n\">model<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">gpt-4o-mini<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">messages<\/span><span class=\"o\">=<\/span><span class=\"n\">messages<\/span><span class=\"p\">,<\/span> <span class=\"n\">tools<\/span><span class=\"o\">=<\/span><span class=\"n\">tools<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"c1\"># getting the first choice (is it possible to get more than one at a time?)\n<\/span>    <span class=\"n\">choice<\/span> <span class=\"o\">=<\/span> <span class=\"n\">completion<\/span><span class=\"p\">.<\/span><span class=\"n\">choices<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n\n    <span class=\"c1\"># appending the message to the conversation history\n<\/span>    <span class=\"n\">messages<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">(<\/span><span class=\"n\">choice<\/span><span class=\"p\">.<\/span><span class=\"n\">message<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"c1\"># switch based on the finish reason\n<\/span>    <span class=\"n\">match<\/span> <span class=\"n\">choice<\/span><span class=\"p\">.<\/span><span class=\"n\">finish_reason<\/span><span class=\"p\">:<\/span>\n\n        <span class=\"c1\"># stop (weirdly) means we got a message response\n<\/span>        <span class=\"n\">case<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">stop<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n\n            <span class=\"c1\"># asking for the user for a prompt\n<\/span>            <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"se\">\\n<\/span><span class=\"s\">ChatGPT:<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">choice<\/span><span class=\"p\">.<\/span><span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"n\">content<\/span><span class=\"p\">)<\/span>\n            <span class=\"n\">prompt<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">input<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"se\">\\n<\/span><span class=\"s\">User: <\/span><span class=\"sh\">\"<\/span><span class=\"p\">).<\/span><span class=\"nf\">strip<\/span><span class=\"p\">()<\/span>\n\n            <span class=\"c1\"># appending the user message to the conversation history\n<\/span>            <span class=\"n\">messages<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">({<\/span><span class=\"sh\">\"<\/span><span class=\"s\">role<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">user<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">content<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">prompt<\/span><span class=\"p\">})<\/span>\n\n        <span class=\"c1\"># in case we got a tool call\n<\/span>        <span class=\"n\">case<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">tool_calls<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n\n            <span class=\"c1\"># getting the first tool call (is it possible to get more than one at a time?)\n<\/span>            <span class=\"n\">tool_call<\/span> <span class=\"o\">=<\/span> <span class=\"n\">choice<\/span><span class=\"p\">.<\/span><span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"n\">tool_calls<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n\n            <span class=\"c1\"># function name and arguments\n<\/span>            <span class=\"n\">function_name<\/span> <span class=\"o\">=<\/span> <span class=\"n\">tool_call<\/span><span class=\"p\">.<\/span><span class=\"n\">function<\/span><span class=\"p\">.<\/span><span class=\"n\">name<\/span>\n            <span class=\"n\">arguments<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">loads<\/span><span class=\"p\">(<\/span><span class=\"n\">tool_call<\/span><span class=\"p\">.<\/span><span class=\"n\">function<\/span><span class=\"p\">.<\/span><span class=\"n\">arguments<\/span><span class=\"p\">)<\/span>\n\n            <span class=\"n\">match<\/span> <span class=\"n\">function_name<\/span><span class=\"p\">:<\/span>\n\n                <span class=\"c1\"># calling the function and appending the result to conversation history\n<\/span>                <span class=\"n\">case<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">get_weather<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n                    <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">get_weather<\/span><span class=\"p\">(<\/span><span class=\"o\">**<\/span><span class=\"n\">arguments<\/span><span class=\"p\">)<\/span>\n                    <span class=\"n\">messages<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">({<\/span><span class=\"sh\">\"<\/span><span class=\"s\">role<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">tool<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">tool_call_id<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">tool_call<\/span><span class=\"p\">.<\/span><span class=\"nb\">id<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">content<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">result<\/span><span class=\"p\">})<\/span>\n\n                <span class=\"n\">case<\/span> <span class=\"n\">unexpected_function<\/span><span class=\"p\">:<\/span>\n                    <span class=\"k\">raise<\/span> <span class=\"nc\">Exception<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Unexpected function call: <\/span><span class=\"si\">{<\/span><span class=\"n\">unexpected_function<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n        <span class=\"n\">case<\/span> <span class=\"n\">unexpected_reason<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">raise<\/span> <span class=\"nc\">Exception<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Unexpected <\/span><span class=\"se\">\\\"<\/span><span class=\"s\">finish_reason<\/span><span class=\"se\">\\\"<\/span><span class=\"s\">: <\/span><span class=\"si\">{<\/span><span class=\"n\">unexpected_reason<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0627\u062c\u0631\u0627\u06cc \u0622\u0646:<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight plaintext\"><code>ChatGPT: How can I assist you with the weather today?\n\nUser: whats the weather in ny right now\n\nChatGPT: The current temperature in New York is -2.9\u00b0C. If you need more information about the weather or forecast, just let me know!\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>from json import loads from signal import signal, SIGINT from requests import get # pip install requests from openai import OpenAI # pip install openai # suppressing &#8220;KeyboardInterrupt&#8221; message signal(SIGINT, lambda _, __: exit()) def get_weather(latitude, longitude): response = get(f&#8221;https:\/\/api.open-meteo.com\/v1\/forecast?latitude={latitude}&amp;longitude={longitude}&amp;current=temperature_2m&#8221;) data = response.json() temperature = data[&#8216;current&#8217;][&#8216;temperature_2m&#8217;] return str(temperature) tools = [{ &#8220;type&#8221;: &#8220;function&#8221;, &#8220;function&#8221;: { &hellip;<\/p>\n","protected":false},"author":2,"featured_media":96975,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"","fifu_image_alt":"","footnotes":""},"categories":[339],"tags":[],"class_list":["post-96974","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/96974","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/comments?post=96974"}],"version-history":[{"count":0,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/96974\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media\/96975"}],"wp:attachment":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media?parent=96974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/categories?post=96974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/tags?post=96974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}