0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

STORM Platform #6 ファンクションコール(1)

0
Last updated at Posted at 2026-03-02

ファンクションコール

ファンクションコールは、LLM によって、タスクを実現するために ファンクション(通常 API)を行うかどうか、また、その際のパラメーターに何を指定するかを決定する機能です。

以前にご紹介した API呼び出し と今回ご紹介するファンクションコールが、イメージ的に被ってしまいちょっと混乱します。実際のところ、この二つは密接に関係しており、ファンクションコールで決定された API を呼び出すことでタスクを実現します。

LLM が、会話の流れを理解し 呼び出す API を自分自身で決めていくことができるのは、非常に AI エージェントっぽい機能な感じがしてどんどん夢が広がっていく気がします。

LLMの機能というと、入力された文章に対して返事をするための文章を生成するという機能が最初に思い浮かぶと思いますが、タスクを実施するために何をするべきかを判断するというのがよりAIエージェントっぽいですね。

STORM Platform の アカウント作成についてはこちらをご覧ください。

実装

タスクを実現するために、どの ファンクション(関数) を呼ぶか、 もしくはどの ファンクション(関数) も 呼ばないかの判断

最初の例として、最もプリミティブな実装を試します。正直、この例は全然実践的ではないのですが、機能の原理を把握するためにやってみます。

全体像

https://dummyjson.com/products/1

この Web API は、ダミーの製品情報を返す無料API の中の一つの API の呼び方です。このAPIを呼び出すべきか否かを LLM に判断してもらいます。

image.png

ファンクションコール

最初の LLM(ID:7) で、ユーザーの質問を理解し、呼び出すファンクション(関数)を決定します。呼び出すべきではない場合、呼び出すファンクション(関数)は指定されません。

image.png

この内容で指定します。この ノード の中で指定しているのが「ファンクションコール」です。
ちょっと、勘違いしやすいのが、このノード内で行うのは、呼び出すファンクション(関数)とパラメータのみで実際のファンクションの呼び出し(通常 API呼び出し)は、その後続のノードで行います。

このファンクションコール自体の仕様は、OpenAI の Function Calling の仕様にほぼ近いものとなっています。

今回呼び出す API は、パラメーターを特定する必要がないため、プロパティの指定は不要な気がしますが、プロパティが空だと、OpenAI の仕様によりエラーになるため、中身空っぽのプロパティを指定してください。

If Else

ファンクションコール(LLM)のノードの後続に If Else ノードをつなぎ下記のように判定させます。
image.png

ここでの判定で、IF 1 の条件が True となる場合のみ API を呼び出すフローにします。

image.png

これにより、ユーザーとの会話の流れで LLM 自身が 求められたタスクを実施するうえで、どの 外部 API を呼び出すかどうかの判断とその API を呼び出すという実装ができます。

確認

ファンクション(関数) を呼ぶ場合

image.png

image.png

API を呼ばない場合

image.png

image.png

ファンクション(関数) を呼ぶか呼ばないかの判断ができているのが確認できると思います。

ワークフロー
{
  "schema_version": 1,
  "nodes": [
    {
      "id": 1,
      "type": "storm/request",
      "properties": {},
      "metadata": {
        "position": {"x": 12, "y": 68},
        "size": {"width": 255.9375, "height": 52},
        "virtualId": "geA12hAHYQd0IREjn7Szy"
      }
    },
    {
      "id": 3,
      "type": "storm/response",
      "properties": {"result_list": ["{{custom_variables}}"]},
      "metadata": {
        "position": {"x": 1792, "y": 68},
        "size": {"width": 255.9375, "height": 52},
        "virtualId": "cKuOJRz-JQ6A5wA1p4pdJ"
      }
    },
    {
      "id": 4,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "claude-sonnet-4-20250514",
          "chat_engine": "claude",
          "seed": 42,
          "stop": [],
          "top_p": 0.1,
          "max_tokens": 640,
          "temperature": 0.1,
          "presence_penalty": 0.1,
          "frequency_penalty": 0.1,
          "tools": []
        },
        "system_template": "API のレスポンスを参照し、ユーザーの問い合わせに対する回答を生成してください。\n\n API レスポンス : {{body:8}}",
        "user_template": "question : ユーザー入力: {{query}}",
        "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}",
        "num_latest_chats": 5
      },
      "metadata": {
        "position": {"x": 1412, "y": 124},
        "size": {"width": 255.9375, "height": 52},
        "formDraft": {
          "propertiesHash": "23hd15lfmny",
          "fields": {
            "model": "claude-sonnet-4-20250514",
            "functions": [],
            "modelSettings": {"chat_engine": "claude"},
            "user_template": "question : ユーザー入力: {{query}}",
            "modelParameters": {
              "seed": 42,
              "stop": [],
              "top_p": 0.1,
              "max_tokens": 640,
              "temperature": 0.1,
              "extra_params": "{}",
              "presence_penalty": 0.1,
              "frequency_penalty": 0.1
            },
            "system_template": "API のレスポンスを参照し、ユーザーの問い合わせに対する回答を生成してください。\n\n API レスポンス : {{body:8}}",
            "num_latest_chats": 5,
            "customModelSettings": "{\"chat_engine\": \"claude\"}",
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "k7FpCW5W6dMDZpvqg39bb"
      }
    },
    {
      "id": 5,
      "type": "storm/ifelse",
      "properties": {
        "if": [
          {
            "note": "",
            "logic": "AND",
            "condition": [
              {
                "operator": "EQUAL",
                "value": "get_product_info",
                "comparison_target": "{{result.name:7}}"
              }
            ],
            "idx": 0,
            "links": [18]
          }
        ],
        "else": {"idx": 1, "links": [6], "note": ""}
      },
      "metadata": {
        "position": {"x": 692, "y": 38.00000000000001},
        "size": {"width": 327.96875, "height": 112},
        "extra": {"use_json": false},
        "virtualId": "p003SFxeaiXdK5KfNjEpk"
      }
    },
    {
      "id": 6,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "claude-sonnet-4-20250514",
          "chat_engine": "claude",
          "seed": 42,
          "stop": [],
          "top_p": 0.1,
          "max_tokens": 640,
          "temperature": 0.1,
          "presence_penalty": 0.1,
          "frequency_penalty": 0.1,
          "tools": []
        },
        "system_template": "あなたは特定の製品の情報について回答するエージェントです。\nユーザーの質問が製品に関するものではなかった場合、質問には回答できない旨を伝えてください。",
        "user_template": "question : {{query}}",
        "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}",
        "num_latest_chats": 5
      },
      "metadata": {
        "position": {"x": 1412, "y": 12},
        "size": {"width": 255.9375, "height": 52},
        "formDraft": {
          "propertiesHash": "mn1weoq50a",
          "fields": {
            "model": "claude-sonnet-4-20250514",
            "functions": [],
            "modelSettings": {"chat_engine": "claude"},
            "user_template": "question : {{query}}",
            "modelParameters": {
              "seed": 42,
              "stop": [],
              "top_p": 0.1,
              "max_tokens": 640,
              "temperature": 0.1,
              "extra_params": "{}",
              "presence_penalty": 0.1,
              "frequency_penalty": 0.1
            },
            "system_template": "あなたは特定の製品の情報について回答するエージェントです。\nユーザーの質問が製品に関するものではなかった場合、質問には回答できない旨を伝えてください。",
            "num_latest_chats": 5,
            "customModelSettings": "{\"chat_engine\": \"claude\"}",
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "QvFb9OAzO9MzUTfCgy2E6"
      }
    },
    {
      "id": 7,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "gpt-5-mini-2025-08-07",
          "chat_engine": "openai",
          "seed": 42,
          "stop": [],
          "max_tokens": 2048,
          "tools": [
            {
              "type": "function",
              "function": {
                "name": "get_product_info",
                "description": "check for a product infomation.",
                "parameters": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": false
                }
              }
            }
          ]
        },
        "system_template": "あなたは、ユーザーの質問を理解して、呼び出す関数を決定するエージェントです。\n",
        "user_template": "question : ユーザー入力: {{query}}",
        "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}",
        "num_latest_chats": 5
      },
      "metadata": {
        "position": {"x": 352, "y": 68},
        "size": {"width": 255.9375, "height": 52},
        "formDraft": {
          "propertiesHash": "zssogwd7hu",
          "fields": {
            "model": "gpt-5-mini-2025-08-07",
            "functions": [
              {
                "name": "get_product_info",
                "parameters": "{\n  \"type\": \"object\",\n  \"properties\": {},\n  \"additionalProperties\": false\n}",
                "description": "check for a product infomation."
              }
            ],
            "modelSettings": {"chat_engine": "openai"},
            "user_template": "question : ユーザー入力: {{query}}",
            "modelParameters": {
              "seed": 42,
              "stop": [],
              "max_tokens": 2048,
              "extra_params": "{}"
            },
            "system_template": "あなたは、ユーザーの質問を理解して、呼び出す関数を決定するエージェントです。\n",
            "num_latest_chats": 5,
            "customModelSettings": "{\"chat_engine\": \"openai\"}",
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "LwUHNJ3-ianoorhkQCgGR"
      }
    },
    {
      "id": 8,
      "type": "storm/apicall",
      "properties": {
        "method": "GET",
        "url": "https://dummyjson.com/products/1",
        "timeout": {
          "response_timeout": 5000,
          "read_timeout": 5000,
          "write_timeout": 5000
        }
      },
      "metadata": {
        "position": {"x": 1072, "y": 124},
        "size": {"width": 300, "height": 52},
        "virtualId": "sfYaZHU96rnz6lsKKCuPp"
      }
    }
  ],
  "links": [
    [3, 4, 3],
    [6, 5, 6],
    [7, 6, 3],
    [8, 1, 7],
    [13, 7, 5],
    [15, 8, 4],
    [18, 5, 8]
  ],
  "custom_variables": {}
}

複数の ファンクション(関数) を選択する

上記の例では、1個のファンクション(関数)を呼ぶ or 呼ばない の選択をしていました。
LLMのノードのファンクションコールには、複数の関数を登録することができます。

https://dummyjson.com/recipes/1

この Web API は、ダミーのレシピを返す無料API の中の一つの API の呼び方です。先に登録済の製品情報のファンクション(関数)に加えて、このファンクション(関数)を呼び出すべきか否かを LLM に判断してもらいます。

image.png

合わせて If Else のノードも変更します。
image.png

確認

image.png

image.png

image.png

それぞれ、質問に応じて、複数のファンクション(関数)からどのファンクション(関数)を呼ぶか、一切呼ばないかの判断ができていることが確認できます。

ワークフロー
{
  "schema_version": 1,
  "nodes": [
    {
      "id": 1,
      "type": "storm/request",
      "properties": {},
      "metadata": {
        "position": {"x": 12, "y": 86.5},
        "size": {"width": 255.9375, "height": 52},
        "virtualId": "geA12hAHYQd0IREjn7Szy"
      }
    },
    {
      "id": 3,
      "type": "storm/response",
      "properties": {"result_list": ["{{custom_variables}}"]},
      "metadata": {
        "position": {"x": 1832, "y": 86.5},
        "size": {"width": 255.9375, "height": 52},
        "virtualId": "cKuOJRz-JQ6A5wA1p4pdJ"
      }
    },
    {
      "id": 4,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "claude-sonnet-4-20250514",
          "chat_engine": "claude",
          "seed": 42,
          "stop": [],
          "top_p": 0.1,
          "max_tokens": 640,
          "temperature": 0.1,
          "presence_penalty": 0.1,
          "frequency_penalty": 0.1,
          "tools": []
        },
        "system_template": "API のレスポンスを参照し、ユーザーの問い合わせに対する回答を生成してください。\n\n API レスポンス : {{body:8}}",
        "user_template": "question : ユーザー入力: {{query}}",
        "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}",
        "num_latest_chats": 5
      },
      "metadata": {
        "position": {"x": 1452, "y": 142.5},
        "size": {"width": 255.9375, "height": 52},
        "formDraft": {
          "propertiesHash": "23hd15lfmny",
          "fields": {
            "model": "claude-sonnet-4-20250514",
            "functions": [],
            "modelSettings": {"chat_engine": "claude"},
            "user_template": "question : ユーザー入力: {{query}}",
            "modelParameters": {
              "seed": 42,
              "stop": [],
              "top_p": 0.1,
              "max_tokens": 640,
              "temperature": 0.1,
              "extra_params": "{}",
              "presence_penalty": 0.1,
              "frequency_penalty": 0.1
            },
            "system_template": "API のレスポンスを参照し、ユーザーの問い合わせに対する回答を生成してください。\n\n API レスポンス : {{body:8}}",
            "num_latest_chats": 5,
            "customModelSettings": "{\"chat_engine\": \"claude\"}",
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "k7FpCW5W6dMDZpvqg39bb"
      }
    },
    {
      "id": 5,
      "type": "storm/ifelse",
      "properties": {
        "if": [
          {
            "note": "",
            "logic": "AND",
            "condition": [
              {
                "operator": "EQUAL",
                "value": "get_product_info",
                "comparison_target": "{{result.name:7}}"
              }
            ],
            "idx": 0,
            "links": [18]
          },
          {
            "note": "",
            "logic": "AND",
            "condition": [
              {
                "operator": "EQUAL",
                "value": "get_recipe_info",
                "comparison_target": "{{result.name:7}}"
              }
            ],
            "idx": 2,
            "links": [19]
          }
        ],
        "else": {"idx": 1, "links": [6], "note": ""}
      },
      "metadata": {
        "position": {"x": 692, "y": 41.5},
        "size": {"width": 327.96875, "height": 142},
        "extra": {"use_json": false},
        "virtualId": "p003SFxeaiXdK5KfNjEpk"
      }
    },
    {
      "id": 6,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "claude-sonnet-4-20250514",
          "chat_engine": "claude",
          "seed": 42,
          "stop": [],
          "top_p": 0.1,
          "max_tokens": 640,
          "temperature": 0.1,
          "presence_penalty": 0.1,
          "frequency_penalty": 0.1,
          "tools": []
        },
        "system_template": "あなたは特定の製品の情報もしくは、料理について回答するエージェントです。\nユーザーの質問が製品・料理に関するものではなかった場合、質問には回答できない旨を伝えてください。",
        "user_template": "question : {{query}}",
        "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}",
        "num_latest_chats": 5
      },
      "metadata": {
        "position": {"x": 1452, "y": 12},
        "size": {"width": 255.9375, "height": 52},
        "formDraft": {
          "propertiesHash": "28mtwnaipra",
          "fields": {
            "model": "claude-sonnet-4-20250514",
            "functions": [],
            "modelSettings": {"chat_engine": "claude"},
            "user_template": "question : {{query}}",
            "modelParameters": {
              "seed": 42,
              "stop": [],
              "top_p": 0.1,
              "max_tokens": 640,
              "temperature": 0.1,
              "extra_params": "{}",
              "presence_penalty": 0.1,
              "frequency_penalty": 0.1
            },
            "system_template": "あなたは特定の製品の情報もしくは、料理について回答するエージェントです。\nユーザーの質問が製品・料理に関するものではなかった場合、質問には回答できない旨を伝えてください。",
            "num_latest_chats": 5,
            "customModelSettings": "{\"chat_engine\": \"claude\"}",
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "QvFb9OAzO9MzUTfCgy2E6"
      }
    },
    {
      "id": 7,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "gpt-5-mini-2025-08-07",
          "chat_engine": "openai",
          "seed": 42,
          "stop": [],
          "max_tokens": 2048,
          "tools": [
            {
              "type": "function",
              "function": {
                "name": "get_product_info",
                "description": "check for a product infomation.",
                "parameters": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": false
                }
              }
            },
            {
              "type": "function",
              "function": {
                "name": "get_recipe_info",
                "description": "Retrieving a cooking recipe.",
                "parameters": {
                  "type": "object",
                  "properties": {},
                  "additionalProperties": false
                }
              }
            }
          ]
        },
        "system_template": "あなたは、ユーザーの質問を理解して、呼び出す関数を決定するエージェントです。",
        "user_template": "question : ユーザー入力: {{query}}",
        "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}",
        "num_latest_chats": 5
      },
      "metadata": {
        "position": {"x": 352, "y": 86.5},
        "size": {"width": 255.9375, "height": 52},
        "formDraft": {
          "propertiesHash": "l175rfoqno",
          "fields": {
            "model": "gpt-5-mini-2025-08-07",
            "functions": [
              {
                "name": "get_product_info",
                "parameters": "{\n  \"type\": \"object\",\n  \"properties\": {},\n  \"additionalProperties\": false\n}",
                "description": "check for a product infomation."
              },
              {
                "name": "get_recipe_info",
                "parameters": "{\"type\": \"object\", \"properties\": {}, \"additionalProperties\": false}",
                "description": "Retrieving a cooking recipe."
              }
            ],
            "modelSettings": {"chat_engine": "openai"},
            "user_template": "question : ユーザー入力: {{query}}",
            "modelParameters": {
              "seed": 42,
              "stop": [],
              "max_tokens": 2048,
              "extra_params": "{}"
            },
            "system_template": "あなたは、ユーザーの質問を理解して、呼び出す関数を決定するエージェントです。",
            "num_latest_chats": 5,
            "customModelSettings": "{\"chat_engine\": \"openai\"}",
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "LwUHNJ3-ianoorhkQCgGR"
      }
    },
    {
      "id": 8,
      "type": "storm/apicall",
      "properties": {
        "method": "GET",
        "url": "https://dummyjson.com/products/1",
        "timeout": {
          "response_timeout": 5000,
          "read_timeout": 5000,
          "write_timeout": 5000
        }
      },
      "metadata": {
        "position": {"x": 1072, "y": 86.5},
        "size": {"width": 300, "height": 52},
        "virtualId": "sfYaZHU96rnz6lsKKCuPp"
      }
    },
    {
      "id": 9,
      "type": "storm/apicall",
      "properties": {
        "method": "GET",
        "url": "https://dummyjson.com/recipes/1",
        "timeout": {
          "response_timeout": 5000,
          "read_timeout": 5000,
          "write_timeout": 5000
        }
      },
      "metadata": {
        "position": {"x": 1072, "y": 198.5},
        "size": {"width": 300, "height": 52},
        "virtualId": "lD5E7Y4hii"
      }
    },
    {
      "id": 10,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "claude-sonnet-4-20250514",
          "chat_engine": "claude",
          "seed": 42,
          "stop": [],
          "max_tokens": 2048,
          "tools": []
        },
        "system_template": "API のレスポンスを参照し、ユーザーの問い合わせに対する回答を生成してください。\n API レスポンス : {{body:9}}",
        "user_template": "question : ユーザー入力: {{query}}",
        "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}",
        "num_latest_chats": 5
      },
      "metadata": {
        "position": {"x": 1431.24854971673, "y": 224.5722928144683},
        "size": {"width": 300, "height": 52},
        "formDraft": {
          "propertiesHash": "1py00eb9ohn",
          "fields": {
            "model": "claude-sonnet-4-20250514",
            "functions": [],
            "modelSettings": {"chat_engine": "claude"},
            "user_template": "question : ユーザー入力: {{query}}",
            "modelParameters": {
              "seed": 42,
              "stop": [],
              "max_tokens": 2048,
              "extra_params": ""
            },
            "system_template": "API のレスポンスを参照し、ユーザーの問い合わせに対する回答を生成してください。\n API レスポンス : {{body:9}}",
            "num_latest_chats": 5,
            "customModelSettings": "{\"chat_engine\": \"claude\"}",
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "40f38Eozyc"
      }
    }
  ],
  "links": [
    [3, 4, 3],
    [6, 5, 6],
    [7, 6, 3],
    [8, 1, 7],
    [13, 7, 5],
    [15, 8, 4],
    [18, 5, 8],
    [19, 5, 9],
    [21, 9, 10],
    [22, 10, 3]
  ],
  "custom_variables": {}
}

まとめ

今回は、LLM による ファンクション(関数)の呼び出しを判定する実装を行いました。ファンクション(関数)の呼び出し(Function Calling) は、AI エージェントによるタスクの自動実行において非常に重要な役割を果たします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?