【Part3】LINEBot × AWS で何か作ってみる【生成AI編】
Part2 で追加した OCR 機能に ChatGPT を組み合わせ、レシート画像から商品名・金額などを抽出して JSON で返す機能をつくる。プロンプトエンジニアリングで OCR テキストを構造化する生成AI編。
前回までのあらすじ
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チャットボットを作成します。(多分)