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?

SPIRAL ver.1 で、お問合せからFAQをOpenAIで生成する

0
Last updated at Posted at 2026-02-02

SPIRALは、主にエンタープライズ向けのローコードプラットフォームになります。ローコードプラットフォームなので、プログラミング知識がなくともWebアプリケーションを開発できるのが魅力です。

今回は、SPIRALのデータベースにあるお問い合わせデータを元にして、FAQを生成してみます。

元データについて

例えば以下のような内容です。

  • 問い合わせ内容
    パスワードを忘れてログインできません。再設定方法を教えてください。
  • 回答
    ログイン画面の「パスワードをお忘れの方」から登録メールアドレスを入力してください。再設定用リンクをお送りします。

このような内容を元に、FAQの文章をOpenAIのAPIを使って生成します。

元データのテーブル構造について

問い合わせデータを受け取るテーブルは以下のような形式となっています。 bodyresponse 以外は今回は利用していません。

No. フィールド名 フィールドタイプ 差替キーワード
1 問い合わせ日時 日付(○年○月○日 ○時○分) contacted_at
2 問い合わせ内容 テキストエリア(1024 bytes) body
3 回答内容 テキストエリア(1024 bytes) response
4 カテゴリ テキストフィールド(64 bytes) category
5 チャネル テキストフィールド(64 bytes) channel
6 顧客ID テキストフィールド(64 bytes) customer_id
7 満足度 数字・記号・アルファベット(6 bytes) satisfaction

FireShot Capture 242 - 通常DB一覧 - [pi-pe.smp.ne.jp].png

FAQ格納用テーブルについて

続いて、FAQを格納するテーブルです。こちらは元データのIDと、生成される内容を保存するフィールドだけあります。このテーブルは FAQList とします。

両フィールドとも入力必須としておきます。ここがポイントです。

No. フィールド名 フィールドタイプ 差替キーワード
1 内容 テキストエリア body
2 id 数字・記号・アルファベット contact_id

FireShot Capture 248 - 通常DB一覧 - [pi-pe.smp.ne.jp].png

フォームを作成する

FAQListを対象として、フォームを作成します。

入力フォームは2つカスタマイズします。

  1. contact_id の入力は、お問い合わせ内容から選択する形にする
  2. 内容は初期表示では不要

contact_id の入力は、お問い合わせ内容から選択する形にする

入力フォーム時の表示をカスタマイズします。

<title></title> <!-- この下に追加 -->
<?php // <!-- SMP_DYNAMIC_PAGE DISPLAY_ERRORS=ON NAME=FAQ --> ?>
<?php

$selectdb = $SPIRAL->getDataBase("Contact");
$selectdb->addSelectFields("id", "body");
$searchResult = $selectdb->doSelect();
?>

これで $searchResult にお問い合わせ内容のデータが入ってくるので、 contact_id の入力を変更します。

<dl class="cf">
  <dt class="title">
    問い合わせ
  </dt><dd class="data num">
    <select name="contact_id" class="$errorInputColor:contact_id$">
    <option value="">選択してください</option>
    <?php
      $list = $searchResult["data"];
      foreach ($list as $select) {
        $id = $select["id"];
        $body = $select["body"];
        $check = ($id == $SPIRAL->getParam("contact_id")) ? "selected" : "";
        echo "<option value='" . $SPIRAL->escapeHtml($id) . "'" . $check . ">" . $SPIRAL->escapeHtml($body) . "</option>\n";
      }
    ?>
    </select><br>
    <span class="msg">$error:contact_id$</span>
  </dd>
</dl>

さらに、body は自動生成される内容なので、初期表示から消しておきます。

<?php if ($SPIRAL->getParam("contact_id") != "") { ?>
  <dl class="cf">
    <dt class="title">
      内容
    </dt><dd class="data ">
      <textarea class="$errorInputColor:body$" name="body" rows="15" wrap="soft" ><?php echo $SPIRAL->escapeHtml($faqMarkdown); ?></textarea><br>
      <span class="msg">$error:body$</span>
    </dd>
  </dl>
<?php } ?>

image.png

こうすると、最初の送信時には body がないので入力エラーになります。

初回送信時の処理

body がないので入力エラーになり、再度入力画面が呼ばれます。この時に、OpenAIのAPIを呼び出してFAQを生成します。

// 初回表示かどうかの判定
if ($SPIRAL->getParam("contact_id") != "") {
  // 対象お問い合わせデータを取得
	$id = $SPIRAL->getParam("contact_id");
	$selectdb = $SPIRAL->getDataBase("Contact");
	$selectdb->addEqualCondition("id", $id);
	$selectdb->addSelectFields("id", "body", "response");
	$searchResult = $selectdb->doSelect();
	$result = $searchResult['data'][0];
	// OpenAIのAPIキー
	$apiKey = 'sk-proj-...';
	// お問い合わせのデータ
	$body = $result['body'];
	$response = $result['response'];
	// LLM用プロンプト
	$prompt = <<<PROMPT
	以下の2つの情報をもとに、FAQとしてそのまま使えるMarkdown文言を生成してください。
	
	- 問い合わせ時のタイトル: {$body}
	- 問い合わせへの返答: {$response}
	
	要件:
	- Markdown形式
	- 簡潔で実務向け
	- 個人情報や特定の業務要件を排除し、誰にとっても役立つ形
	- 分かりやすく、可読性の高い文章
	PROMPT;
	
	$data = [
	'model' => 'gpt-4.1-mini',
	'input' => $prompt,
	];
	// APIリクエスト
	$ch = curl_init('https://api.openai.com/v1/responses');
	curl_setopt_array($ch, [
	CURLOPT_POST => true,
	CURLOPT_RETURNTRANSFER => true,
	CURLOPT_HTTPHEADER => [
	'Content-Type: application/json',
	'Authorization: Bearer ' . $apiKey,
	],
	CURLOPT_POSTFIELDS => json_encode($data),
	]);
	
	$result = curl_exec($ch);
	curl_close($ch);
	
	$json = json_decode($result, true);
	// APIレスポンスを取得
	$faqMarkdown = '';
	if (isset($json['output']) && is_array($json['output'])) {
		foreach ($json['output'] as $out) {
			if (!isset($out['content']) || !is_array($out['content'])) continue;
			foreach ($out['content'] as $c) {
				if (($c['type'] ?? '') === 'output_text' && isset($c['text'])) {
					$faqMarkdown .= $c['text'];
				}
			}
		}
	}
  // ```markdown となっている部分を除去
	$faqMarkdown = preg_replace('/```markdown\n(.*?)```/s', '$1', $faqMarkdown);
}

これで $faqMarkdown にFAQ本文が入りますので、表示を行います。

<?php if ($SPIRAL->getParam("contact_id") != "") { ?>
  <dl class="cf">
    <dt class="title">
      内容
    </dt><dd class="data ">
      <textarea class="$errorInputColor:body$" name="body" rows="15" wrap="soft" ><?php echo $SPIRAL->escapeHtml($faqMarkdown); ?></textarea><br>
      <span class="msg">$error:body$</span>
    </dd>
  </dl>
<?php } ?>

FireShot Capture 249 -  - [www.pi-pe.co.jp].png

これでFAQが生成され、 contact_idbody にデータが入るので、確認画面に遷移してデータ登録できます。

まとめ

LLMを使うことで、業務システムが省力化されたり、便利になるでしょう。ぜひSPIRALと組み合わせて使ってみてください。

現在、SPIRALではエンジニアβという無料アカウントを配布しています。SPIRALに興味がある型はこちらから試してみてください。

API SPIRAL ver.1 サポートサイト

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?