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 #7 ファンクションコール(2)

0
Last updated at Posted at 2026-03-18

ファンクションコールで取得した値の取り扱い

以前、STROM Platform で外部 API から情報を取得する例を Qiita 上でご説明しました。

その際、取得したデータ(上記の例だと JSON データ)の中身がそれぞれどのような意味合いを持つのか?を定義していないのに、LLM が、それなりに、いいように扱ってくれていることに少しもやもやしていました。
いい感じに扱ってくれてるのはいいんですが、複雑な構造になった場合、本当に正確に理解してくれるんかな?って思いますよね?

なんとなくLLMにいいようにやってもらう

とりあえずの実験として、仮想的な API がある番組の 1)MC 2)メインコメンテーター 3)ゲストコメンテーター の名前を返す環境で、ユーザーからの質問に回答するというフローを作ります。

image.png

仮想的な API は、AWS lambda で下記のような実装です。

import json

def lambda_handler(event, context):
    ret_json = {
        "master_of_ceremony": "神崎 恒一",
        "main_commentator": "白石 麻耶",
        "guest_commentatorperson_in_charge_c": "ゴルゴンゾーラ 明子"
    }

    return {
        'statusCode': 200,
        'body': json.dumps(ret_json, ensure_ascii=False)
    }

この環境で確認してみると
image.png

image.png

理解して動いていますね。
取得した JSON のタグをLLMの方で判断して、いいように取り扱ってくれているようです。

では、データが

{
    "person_in_charge_a": "神崎 恒一",
    "person_in_charge_b": "白石 麻耶",
    "person_in_charge_c": "ゴルゴンゾーラ 明子"
}

の場合、どうなるでしょうか?
image.png

さすがに、わからないようですね。昔の LLM だと勝手に判断していわゆるハルシネーションを起こしていたかもしれません。

データスキーマの追加

ここで説明する手法は、STORM Platform の機能というよりは、一般的な LLM/AI エージェントの手法です

先ほどまでのフローだと
image.png

というようなシステムプロンプトになっていましたが、ここに

出演者情報のスキーマ : 
{
  "type": "object",
  "properties": {
    "person_in_charge_a": {
      "type": "string",
      "description": "MC の氏名"
     },
    "person_in_charge_b": {
      "type": "string",
      "description": "メインコメンテーターの氏名"
    },
    "person_in_charge_c": {
      "type": "string",
      "description": "ゲストコメンテーターの氏名"
    }
   },
   "required": [
     "person_in_charge_a",
     "person_in_charge_b",
     "person_in_charge_c"
   ],
   "additionalProperties": false
}

こちらをシステムプロンプトに追加します。

image.png

期待した動作になりました。

まとめ

API 経由で情報を取得しそのデータを LLM で活用する場合に、特に LLM にデータ構造を指定しなくてもある程度期待した動作になることが多いですが、今回のように、情報を明確に記載し、LLMに対する不明確な情報を与えることを避ける方が、安定して動作すると考えられます。

ワークフロー
{
  "schema_version": 1,
  "nodes": [
    {
      "id": 1,
      "type": "storm/request",
      "properties": {},
      "metadata": {
        "position": {"x": 12, "y": 41},
        "size": {"width": 300, "height": 51},
        "virtualId": "Dg7KhjnMfz"
      }
    },
    {
      "id": 2,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "gpt-5-mini-2025-08-07",
          "chat_engine": "openai",
          "stop": [],
          "tools": [
            {
              "type": "function",
              "function": {
                "name": "get_commentators",
                "description": "出演者情報を取得する。",
                "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": 41},
        "size": {"width": 300, "height": 51},
        "formDraft": {
          "propertiesHash": "11azu82hs6j",
          "fields": {
            "model": "gpt-5-mini-2025-08-07",
            "functions": [
              {
                "name": "get_commentators",
                "parameters": "{\n  \"type\": \"object\",\n  \"properties\": {},\n  \"additionalProperties\": false \n}",
                "description": "出演者情報を取得する。"
              }
            ],
            "modelSettings": {"chat_engine": "openai"},
            "user_template": "question : {{query}}",
            "modelParameters": {
              "stop": [],
              "extra_params": "",
              "max_tokens_fallback": 2048
            },
            "system_template": "あなたは、ユーザーの質問を理解して、呼び出す関数を決定するエージェントです。",
            "num_latest_chats": 5,
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "3Tu0hvBqQ7"
      }
    },
    {
      "id": 3,
      "type": "storm/response",
      "properties": {"result_list": ["{{custom_variables}}"]},
      "metadata": {
        "position": {"x": 1792, "y": 40.99999999999999},
        "size": {"width": 300, "height": 51},
        "virtualId": "1iIhOVuFio"
      }
    },
    {
      "id": 4,
      "type": "storm/ifelse",
      "properties": {
        "if": [
          {
            "note": "",
            "logic": "AND",
            "condition": [
              {
                "operator": "EQUAL",
                "value": "get_commentators",
                "comparison_target": "{{result.name:2}}"
              }
            ],
            "idx": 0,
            "links": [4]
          }
        ],
        "else": {"idx": 1, "links": [5], "note": ""}
      },
      "metadata": {
        "position": {"x": 692, "y": 12},
        "size": {"width": 300, "height": 109},
        "extra": {"use_json": false},
        "virtualId": "IAwOaZoEvS"
      }
    },
    {
      "id": 5,
      "type": "storm/llm",
      "properties": {
        "llm": {
          "model": "claude-sonnet-4-20250514",
          "chat_engine": "claude",
          "max_tokens": 20000,
          "tools": []
        },
        "system_template": "出演者情報 : {{body:6}}\n出演者情報のスキーマ : \n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"person_in_charge_a\": {\n      \"type\": \"string\",\n      \"description\": \"MC の氏名\"\n     },\n    \"person_in_charge_b\": {\n      \"type\": \"string\",\n      \"description\": \"メインコメンテーターの氏名\"\n    },\n    \"person_in_charge_c\": {\n      \"type\": \"string\",\n      \"description\": \"ゲストコメンテーターの氏名\"\n    }\n   },\n   \"required\": [\n     \"person_in_charge_a\",\n     \"person_in_charge_b\",\n     \"person_in_charge_c\"\n   ],\n   \"additionalProperties\": false\n}\n\n出演者情報の情報をもとにユーザーの質問に回答してください。\n",
        "user_template": "question : {{query}}",
        "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}",
        "num_latest_chats": 5
      },
      "metadata": {
        "position": {"x": 1452, "y": 40.99999999999999},
        "size": {"width": 300, "height": 51},
        "formDraft": {
          "propertiesHash": "1dtv5ifi2kj",
          "fields": {
            "model": "claude-sonnet-4-20250514",
            "functions": [],
            "modelSettings": {"chat_engine": "claude"},
            "user_template": "question : {{query}}",
            "modelParameters": {
              "max_tokens": 20000,
              "extra_params": "",
              "max_tokens_fallback": 20000
            },
            "system_template": "出演者情報 : {{body:6}}\n出演者情報のスキーマ : \n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"person_in_charge_a\": {\n      \"type\": \"string\",\n      \"description\": \"MC の氏名\"\n     },\n    \"person_in_charge_b\": {\n      \"type\": \"string\",\n      \"description\": \"メインコメンテーターの氏名\"\n    },\n    \"person_in_charge_c\": {\n      \"type\": \"string\",\n      \"description\": \"ゲストコメンテーターの氏名\"\n    }\n   },\n   \"required\": [\n     \"person_in_charge_a\",\n     \"person_in_charge_b\",\n     \"person_in_charge_c\"\n   ],\n   \"additionalProperties\": false\n}\n\n出演者情報の情報をもとにユーザーの質問に回答してください。\n",
            "num_latest_chats": 5,
            "customModelSettings": "{\"chat_engine\": \"claude\"}",
            "retrieval_chunks_template": "[[#{{no}}]] filename: {{filename}}, pagename: {{pagename}}\nContext: {{context}}"
          }
        },
        "virtualId": "S4dGos3q9z"
      }
    },
    {
      "id": 6,
      "type": "storm/apicall",
      "properties": {
        "method": "GET",
        "url": "https://hogehoge",
        "timeout": {
          "response_timeout": 5000,
          "read_timeout": 5000,
          "write_timeout": 5000
        }
      },
      "metadata": {
        "position": {"x": 1072, "y": 59.24999999999999},
        "size": {"width": 300, "height": 51},
        "virtualId": "mbdFkWTAVY"
      }
    }
  ],
  "links": [[1, 1, 2], [3, 2, 4], [4, 4, 6], [5, 4, 5], [6, 6, 5], [7, 5, 3]],
  "custom_variables": {}
}

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?