挨拶
ども!久しぶりにブログを連続で執筆していて、日常の至るところでブログのネタを考えていますね。非常に便利な習慣が戻ってきている龍ちゃんです。
今回は「Dify上で、LLMからの出力から構造化情報(JSON)を作成して返答」となります。LLMからの出力をJSONに成型してアプリに組み込む方法に関しては、Azure OpenAI Serviceを活用していた際にもぶつかっていた問題になります。(AOAI:Gpt-4oでJSON出力に失敗する対症療法)
LLMから構造化データを作成することができればアプリの表現の幅が大幅に広がります。方法としては、「コードブロックでオブジェクトを詰め替える」という力技で実現しています。
2025/02/17時点でのDify Cloudの情報となります。
おそらく、バージョンアップで「終了」ブロックで対応されるかなと予想中。
実現したいこと
Dify(API)では、レスポンスは【終了】ブロックで書いた情報がJSONで返答されます。ですが、単純に記述するだけでは、以下のようなレスポンスになってしまいます。
{
"name":"TEST User",
"age":24,
"job":"WEBデザイナー",
"profile":"都内で一流のデザイナーを目指す、駆け出しWEBデザイナー"
}
返答する情報量が少ない場合、こちらのままでも問題ありません。ですが、複数の事柄に関する情報を返答する場合は、情報が同一階層に表示されることで不都合が生じます。命名の工夫や呼び出し側での整形で対応できますが、Dify側でObjectとして返してあげるほうが自然です。
以下のような返答を送れるように情報を成形して渡す方法を解説していきます。
{
"user":{
"name":"TEST User",
"age":24,
"job":"WEBデザイナー",
"profile":"都内で一流のデザイナーを目指す、駆け出しWEBデザイナー"
}
}
ワークフローで構造化情報(JSON)を返答する
説明のために「架空の人物情報(名前・年齢・職業・説明)を生成AIを活用して生成して、情報をuserというオブジェクトで取得」という仮のユースケースを使用して進めていきます。
全体感としては、以下のようなステップのシンプルなワークフローとなります。

- LLM:架空のユーザーを作成するプロンプト
- パラメータ抽出:LLMの出力から情報を抽出(name, job, age, profile)
- コード:パラメータ抽出のアウトプットを引数としてuserオブジェクトを作成
- 終了:userオブジェクトを返信
架空のユーザー作成プロンプト
以下の手順に従ってください。
1. 広い選択肢からランダムに職業を1つ選択してください。
2. 名前と年齢を決定してください。名前は広い選択肢の中からより現実的な情報にしてください。
3. 人物の説明を500文字程度で作成してください。趣味嗜好などの情報や特筆した情報があると素晴らしいです。
最終的な出力は、以下の情報のみにしてください。
名前:
職業:
年齢:
説明:
プロンプトで注目する点は、次のブロックである【パラメータ抽出】で抽出しやすいようにプロンプトを調整している部分です。余分な情報をそぎ落とすことで、【パラメータ抽出】の精度を上げています。
名前:佐藤健一
職業:公務員
年齢:34歳
説明:佐藤健一は、東京都内に住む34歳の公務員です。彼は地元の市役所で、地域の福祉政策を担当しており、住民の生活向上に貢献することに情熱を注いでいます。大学では社会学を専攻し、卒業後すぐに公務員試験に合格して現在の職に就きました。仕事に対する責任感が強く、特に高齢者支援のプロジェクトに深く関与しており、地域のボランティア団体と連携しながら活動しています。\n\n趣味はハイキングと料理で、週末には友人たちと近郊の山を登ったり、自宅で新しいレシピに挑戦したりしています。特にイタリア料理が得意で、パスタやリゾットを作るのが好きです。また、彼は猫を飼っており、愛猫の「ミケ」と一緒に過ごす時間が何よりの癒しとなっています。健一は、身近な人々との交流を大切にしており、地域のイベントにも積極的に参加することで、コミュニティの一員としてのつながりを大事にしています。将来的には、より多くの人々に影響を与えられるよう、政策提案を行う立場にステップアップしたいと考えています。
パラメータ抽出

ここでは、LLMを使用してテキスト情報から特定の情報を抽出します。前段【LLM:架空のユーザー作成プロンプト】の生成文を入力とします。抽出する情報は以下となります。
名前 | タイプ | 説明 |
---|---|---|
name | String | キャラクターの名前 |
job | String | キャラクターの職業 |
age | Number | キャラクターの年齢 |
profile | String | キャラクターの説明 |
名前と説明を適切に設定することで、追加でプロンプト(指示)を与えることなく動作します。もし抽出がうまくいかない場合は、以下の二つに注目してみてください。
- 抽出しやすい入力になるように成型しておく(今回の方法)
- 追加のプロンプトを設定して抽出方法を調整する
コード:userオブジェクトを生成
パラメータ抽出で取得した情報をuserオブジェクトに詰め替えて処理を終了します。入力変数・コード・出力変数を一致させる必要があります。今回使用しているコードは以下になります。
def main(name: str, job: str, age: int, profile:str):
return {
"user":{
"name":name,
"age":age,
"job":job,
"profile":profile
}
}
入力変数と出力変数はそれぞれ、コードの引数と出力と一致させてください。出力はuser
でObject
を指定します。
特に出力変数はリターン内で自分で定義した命名と完全に一致させてください。
命名と型指定を忘れずに!!

終了:情報を返答していく
ここでは、コードブロックの出力をそのまま出力してください。入力を選択した際にuser
がオブジェクトの型定義がついていれば一安心です。

終わり
今回はLLMからの出力を構造化情報(JSON)として取得する方法を解説しました。パラメータ抽出を活用することで、プロンプトの出力を簡単に構造化できることが分かりましたね。この手法を応用することで、より複雑なJSONデータの生成も可能になるはずです。