OpenAI APIからの提案を機械的にパースできるように工夫してみた

はじめに

こんにちは。この記事は、Insurtechラボ202306アドベントカレンダーの10日目の投稿として書いています。
Insurtech研究所の取り組みでOpenAI APIを使い、AIからおすすめの保険商品を提案してもらえる機能を開発しました。その中からAIに提案してもらうためのプロンプト、APIのレスポンスを機械的に処理するための工夫をご紹介したいと思います。

過去にいちろ〜さんが投稿した「ChatGPTでサービスを作ってみた!」も参考にしていただけるとよりわかりやすいかと思います。(今回の取り組みでかなり参考にさせていただきました)

提案してほしい商品情報の整理

提案してほしい商品の情報をあらかじめ渡しておき、その中からAIが勝手に考えて選んでくれる様にしたかったので、プロンプト作成前にインプットに使う情報を以下のように整理しました。

プロンプトを作る

次はプロンプトです。APIの仕様上過去のやりとりを毎回記憶しているわけではないので、商品情報などはまとめて送信する必要があります。

以下の点を意識しながら、今回使用するプロンプトを作成していきます。

  • AI側の役割
  • 商品情報
  • 提案する際のフォーマット
  • 提案した理由の説明

そして出来上がったのがこちら

※ role: user がインプット、role: assistant がレスポンスです。

"messages": [
  {
    "role": "user",
    "content": "あなたにこれから保険の商品を提案するロボッドアドバイザーになってもらいます。私があなたに@@@ロボGo@@@と伝えるまでは情報を与え続けるので受け取っていってください。受取っている最中は、回答は「受け取りOK」のみで良いです。"
  },
  {
    "role": "assistant",
    "content": "受け取りOK"
  },
  {
    "role": "user",
    "content": "商品名:医療\nプラン:お手頃\n入院給付金日額:5000円\n支払い日数限度:60日\n手術給付金の型:入院日額×5倍\n入院一時給付特約:0円\n先進医療特約:付与しない\nがん一時給付金特約:0円\n月額保険料:1732円\n"
  },
  {
    "role": "assistant",
    "content": "受け取りOK"
  },
  {
    "role": "user",
    "content": "商品名:医療\nプラン:標準\n入院給付金日額:5000円\n支払い日数限度:60日\n手術給付金の型:入院日額×5倍\n入院一時給付特約:50000円\n先進医療特約:付与する\nがん一時給付金特約:0円\n月額保険料:2194円\n"
  },
  {
    "role": "assistant",
    "content": "受け取りOK"
  },
  {
    "role": "user",
    "content": "商品名:医療\nプラン:充実\n入院給付金日額:10000円\n支払い日数限度:60日\n手術給付金の型:入院日額×5倍\n入院一時給付特約:50000円\n先進医療特約:付与する\nがん一時給付金特約:500000円\n月額保険料:3926円\n"
  },
  {
    "role": "assistant",
    "content": "受け取りOK"
  },
  {
    "role": "user",
    "content": "商品情報は終わりです。"
  },
  {
    "role": "assistant",
    "content": "受け取りOK、理解しました。"
  },
 {
   "role": "user",
   "content": "次に質問の後の商品提案のフォーマットです。商品提案は以下のJSON形式でのみ行ってください。\n{\"product\": \"(商品名)\", \"planName\": \"(プラン名)\", \"reason\": \"(提案理由)\", \"matchpercent\": \"\"}"
 },
 {
   "role": "assistant",
   "content": "受け取りOK、理解しました。"
 },
  {
    "role": "user",
   "content": "では、ロボッドアドバイザーを開始してください。\n先ほど伝えた商品情報から提案に必要な5つの質問をあなたが考えて、私に質問をしてください。\n最後に回答内容からマッチする商品を一つだけ提案しその根拠を説明してください。マッチした商品とプランの組み合わせをおすすめする詳細な理由を、小学生でも全体に納得できるようなわかりやすい説明してください。\n提案のしかたは以下の2つです。妥当だと思う行動を行ってください。\n・商品名:医療の中から1商品のみを提案する\n・マッチしないので、何も商品を提案しない\n@@@ロボGo@@@"
  },
  {
    "role": "assistant",
    "content": "質問1: ご年齢はいくつですか?\n質問2: ご職業は何ですか?\n質問3: ご家族の人数は何人ですか?\n質問4: 月々のご予算を教えてください\n質問5: 他に気になることはありますか?"
  }
]

使ってみる

一度作成したプロンプトを使ってみて商品を選んでくれるかの確認をしたいと思います。
role: user で質問に対しての回答を行いAPIを叩くだけです。

/////以下を末尾に追加/////
{
  "role": "user",
  "content": "質問1: 24歳\n質問2: エンジニア\n質問3: 1人\n質問4: 4000円くらい\n質問5: 特にないです"
}

以下のレスポンスが返ってきました。
なんとなく考えてくれた風のメッセージですね。

  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "提案します。\n\n{\"product\": \"医療\", \"planName\": \"お手頃\", \"reason\": \"あなたの年齢や職業、家族構成を考慮し、お手頃なプランを提案します。入院給付金日額は5000円で、支払い日数限度は60日です。手術給付金の型は入院日額の5倍で、入院一時給付特約は0円です。先進医療特約やがん一時給付金特約は付与されません。月額保険料は1732円です。予算の範囲内で、必要な保障を提供するプランです。\", \"matchpercent\": \"80%\"}\n\nこの提案は、あなたの年齢や職業、家族構成、予算を考慮してお手頃なプランを提案しています。入院給付金や手術給付金の保障があり、月額保険料も予算内で抑えられています。また、先進医療特約やがん一時給付金特約は付与されませんが、現時点ではそれらの特約が必要ないと判断されました。\n\nこのプランは、あなたのニーズに合った保険商品であり、予算内で必要な保障を提供しています。保険料も比較的低く抑えられているため、経済的な負担も軽減されます。\n\n以上が提案の根拠となります。ご検討ください。"
      },
      "finish_reason": "stop"
    }
  ],

レスポンスをJSONだけにしてみる

当時我々が使用していたプラットフォームの都合で、提案理由のJSONから値を抽出するようなコードが書けないため、プロンプトを工夫しJSONのレスポンスのみが返ってくるようにする必要がありました。

インプットに色々条件を付け足してみるもどうしても”提案します{提案内容}以上です”のように日本語が含まれてしまっていました、しかし提案の途中までAI側が回答したことにすることで、パースできるJSONの形で返ってくるようになりました。

/////以下を回答の後に付け足す/////
{
  "role": "assistant",
  "content": "以下が提案内容のJSONです。"
}

上記、取り込み後のレスポンスが以下です。

  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "{\"product\": \"医療\", \"planName\": \"お手頃\", \"reason\": \"お手頃プランは月額保険料が比較的低く、入院給付金日額も5000円と十分な補償が得られます。フリーターの方にとって、予算を抑えながらも医療費のリスクをカバーすることが重要です。また、ご家族の人数が1人であるため、家族の保険料負担も軽減されます。さらに、特に気になることがないとのことですので、お手頃プランが適していると考えます。\", \"matchpercent\": \"100%\"}"
      },
      "finish_reason": "stop"
    }
  ],

これでうまくパースできるようになりました。いやーよかったよかった😄

終わりに

以上、AIに商品提案してもらうためのプロンプト、APIのレスポンスを機械的に処理するための工夫をご紹介しました。
ご参考になれば幸いです。