2024.03.27 6 min read AWS / Lambda / LINEBot / 生成AI / ChatGPT

【Part3】LINEBot × AWS で何か作ってみる【生成AI編】

Part2 で追加した OCR 機能に ChatGPT を組み合わせ、レシート画像から商品名・金額などを抽出して JSON で返す機能をつくる。プロンプトエンジニアリングで OCR テキストを構造化する生成AI編。

AWSLambdaLINEBot生成AIChatGPT

前回までのあらすじ

OCRを活用して送信された画像から文章を抽出する機能を追加しました。

今回作るもの

ユーザが送信した領収書の画像からテキストを抽出し、ChatGPTでテキストから必要な情報を抽出して返却する機能を追加します。

ChatGPT

APIを使用しますので、以下からクレジットカードの登録とAPIキーの作成を行います。

クレジットカード登録

https://platform.openai.com/account/billing/overview

※無料で使えると思っていたのですが、初回チャージが必須で5ドル課金しました。

APIキーの作成

左メニューから[API Keys] > [Create new secret key]で作成します。作成したキーは後ほど使うのでコピーしておきます。

Lambda Layerの作成

必要なライブラリをインストールします。

$ pip install openai

Lambda コードの作成

プロンプトエンジニアリングを行い、OCRから抽出された文章をJSON形式に変換してもらいます。

prompt = f'''
##命令
下記の「##文章」以下の文章から
商品名(name),個数(quantity),価格(price),合計金額(total_price),購入日時(purchase_date),購入店舗(store)をJSON形式で抽出してください。
抽出出来る場合はstatusに「SUCCESSED」、出来ない場合はstatusに「FAILED」を出力すること。

##フォーマット
{{
  "status": "SUCCESSED",
  "purchase": {{
    "items": [
      {{ "name": "商品名1", "quantity": 2, "price": 1000 }},
      {{ "name": "商品名2", "quantity": 1, "price": 1500 }}
    ],
    "total_price": 2500,
    "purchase_date": "2024/03/25 12:00",
    "store": "購入店舗名"
  }}
}}

##文章
{output_text}
'''

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "user", "content": prompt}
    ],
    temperature=0
)
openai_text = response['choices'][0]['message']['content']

実際に以下の文章を与えて検証してみます。

ChatGPTに与える文字列

LAWSON
S OSL ekimo 天王寺 店 登録 番号 ;
大阪 府 大阪 市 阿倍野 区 阿倍野筋 1-1-48
電話 :
店 コード
2024 年 3 月 27 日 ( 水 ) 18:29
レジ #
貴 : HOSS
クレジット 売上 票
[ お客様 控え ] レッドブル エナジー ドリンク 355ml ブルボン アル フォート ミニ ホワイト
279 軽
131
PM テリア スムース RE 1P
580
レジ 袋
3
合 計 ¥ 993
( 内 消費 税 等 ¥ 83 )
( 10 % 対象 ¥ 583 )
( 内 消費 税額 ¥ 53 )
( 8 % 対象 ¥ 410 )
( 内 消費 税額 ¥ 30 )
点 数 4 個
印 は 軽減 税率 対象 商品 です 。
上 金額 ¥ 993
¥ 993

ChatGPTから返却された文字列

{
  "status": "SUCCESSED",
  "purchase": {
    "items": [
      { "name": "レッドブル エナジー ドリンク 355ml", "quantity": 1, "price": 279 },
      { "name": "ブルボン アル フォート ミニ ホワイト", "quantity": 1, "price": 131 },
      { "name": "PM テリア スムース RE 1P", "quantity": 1, "price": 580 },
      { "name": "レジ 袋", "quantity": 1, "price": 3 }
    ],
    "total_price": 993,
    "purchase_date": "2024/03/27 18:29",
    "store": "LAWSON"
  }
}

きちんとJSONに落とし込んでくれています。

あとはこのJSONを使用してLINEBotにメッセージを送信してあげれば完成です。

if data['status'] == 'SUCCESSED':
    item_text = ''
    for item in data['purchase']['items']:
        item_text = f"{item_text}{item['name']}\n{item['quantity']}\n{item['price']}\n\n"
    response_text = f"{data['purchase']['purchase_date']}\n{data['purchase']['store']}\n{item_text}{data['purchase']['total_price']}円"

試してみる

出来ました。

与えられた文章から情報が抜き出せない場合はステータスに「FAILED」を返すようにしているので、レシートじゃない画像を送信してもきちんと対応してくれます。

最後に

はじめはJSONに変換してくれなかったりしたのですが、文章を調整してJSONへの変換率はほぼ100%になりました。

ですが実用面を考えると、コスト面やレスポンス速度を向上させるために命令文章をより明確かつコンパクトに調整する必要があると感じたので、これからも調整をがんばります。

次回は入力されたレシート情報を学習させてAIチャットボットを作成します。(多分)

← 新しい記事
【Part2】LINEBot × AWS で何か作ってみる【OCR編】
記事一覧にもどる