前提
claudeのAPIを関数的に組み込んで使いたいとなるとデータ形式が指定されていれば嬉しいシーンは多いと思われる。そんなとき最初に試すのはjson形式ではないだろうか。
残念ながら基本的にClaudeには公式のjsonモードは存在しない。(2024/11/22現在)
一応tool_useを強制することでjson出力を指定することは出来るが…
その場合はこの記事を参考とするとよい。
Amazon Bedrock Converse API で Claude3 の JSON モードを利用する
本記事ではtool_useを使わない方法で各属性ごとに出力する方法を検討する。
こちらの方法での気合パースの公式のcookbookがこちらで公開されている。
cookbookでは以下の関数を例示している(他にもいくつか公開している)
def extract_json(response):
json_start = response.index("{")
json_end = response.rfind("}")
return json.loads(response[json_start:json_end + 1])
しかしそれでも確実な方法ではない。
うまくいくときもあるが複雑なjsonを吐かせると
すぐにjson.loadsが動作しなくなり以下のエラーを吐く。
json.decoder.JSONDecodeError: Invalid control character at: line * column ** (char **)
結論
json出力はパースの観点から非常に不安定なのでCSV出力を使う。
方法
promptに以下の文章を入れればよい。
以下の要素を含むCSVフォーマットで回答する事
"hoge": "hoge属性の説明"
"fuga": "fuga属性の説明"
CSVのみを出力し、CSVフォーマット以外の文字は一切応答に含めないでください。
出力は以下の方法でパース出来る。
import csv
import io
# CSV形式のレスポンスをパース
csv_reader = csv.DictReader(io.StringIO(explanation_response))
response_data = next(csv_reader)
explanation = response_data.get("hoge")
is_correct = response_data.get("fuga")