$ cat してAmazon Bedrock ~ターミナルからClaude 3 Sonnetを活用~

AWS

2024.3.30

Topics

はじめに

日々、ターミナルで$ curlして| jq .したり、$ grepして| sort | uniq -c | sort -nrしたり、$ for file in *.txt; do ...したり、コマンドベースでテキスト処理をしている皆さんへ!

そのままChatGPTのような生成AIに繋げたら、様々な可能性が広がると思いませんか?私は思いました!

というわけで、本記事ではAmazon Bedrockを利用し、Anthropic社の生成AIモデル「Claude 3 Sonnet」をコマンドから利用できる環境を整えます。

ask_sonnet 完成イメージ

完成イメージ (Windows WSL環境での実行例)

前提条件

あらかじめ以下の準備が必要です。

スクリプトの設置

以下Pythonによる参考実装です。お好みの場所(/usr/bin/ask_sonnetなど)に配置し、実行権限を付与してください。

#!/usr/bin/python3
import boto3
from botocore.config import Config
import json
import sys

# AWSセッションとクライアントの設定
custom_config = Config(read_timeout=300, connect_timeout=30)
session = boto3.Session()
bedrock = session.client('bedrock-runtime', 'us-east-1', config=custom_config)

# ファイル指定があればシステムプロンプトを読み込む
system_prompt = ""
if len(sys.argv) > 1:
    try:
        with open(sys.argv[1], 'r', encoding='utf-8') as file:
            system_prompt = file.read()
    except Exception as e:
        print(f"ファイルの読み込み中にエラーが発生しました: {e}", file=sys.stderr)
        sys.exit(1)

# 標準入力からユーザープロンプトを読み込む
user_prompt = sys.stdin.read()

# APIリクエストボディの構築
body = {
    "anthropic_version": "bedrock-2023-05-31",
    "max_tokens": 10000,
    "messages": [{"role": "user", "content": user_prompt}]
}
if system_prompt:
    body["system"] = system_prompt

# モデルと応答形式の設定
model_id = 'anthropic.claude-3-sonnet-20240229-v1:0'
accept = 'application/json'
content_type = 'application/json'

# モデルを呼び出し、応答を取得
response = bedrock.invoke_model(
    body=json.dumps(body),
    modelId=model_id,
    accept=accept,
    contentType=content_type
)
response_body = json.loads(response['body'].read())

# 結果の出力
print(response_body["content"][0]["text"])

# トークン数と想定価格の計算
input_tokens = response_body["usage"]["input_tokens"]
output_tokens = response_body["usage"]["output_tokens"]
input_price_per_token = 0.00300 / 1000
output_price_per_token = 0.01500 / 1000
total_price = (input_tokens * input_price_per_token) + (output_tokens * output_price_per_token)

# 標準エラー出力にトークン数と想定価格を表示
sys.stderr.write(f"\n入力トークン数: {input_tokens}, 出力トークン数: {output_tokens}, 想定価格: ${total_price:.4f}\n")

使い方

以下のように標準入力を受け付け、Claude 3 Sonnetの応答を出力します。

$ echo "こんにちは!最近どうですか?" | ask_sonnet
こんにちは!私は毎日元気に過ごしています。AIとしては特に変わったことはありませんが、ユーザーの皆さんとの会話を楽しんでいます。今日はどのようなお話をされたいですか?ニュースや文化、科学技術など、幅広い話題について楽しく会話できると思います。

入力トークン数: 20, 出力トークン数: 110, 想定価格: $0.0017

あらかじめプロンプトをテキストファイルとして用意しておくことで、実行時に引数として指定することも出来ます。

$ cat 日本語と英語で返すプロンプト.txt
入力データに対する適切な返答を、日本語と英語の両方で行ってください。
出力フォーマットは以下のとおりです。それ以外の挨拶や返答は不要です。

JP: (ここに日本語の返答内容)
EN: (ここに英語の返答内容)

$ echo "こんにちは!最近どうですか?" | ask_sonnet 日本語と英語で返すプロンプト.txt
JP: 最近は仕事が大変でしたが、少し落ち着いてきました。体調も良好で、新しいプロジェクトに取り組める準備ができています。
EN: Things have been quite busy at work recently, but it's calming down a bit now. I'm in good health and ready to take on new projects.

入力トークン数: 113, 出力トークン数: 93, 想定価格: $0.0017

これにより、様々なコマンドと用意したプロンプトを組み合わせて、複雑なタスクを実行することが出来ます。

TIPS

  • コスト意識を持つために、消費したトークン数と想定価格を標準エラー出力に表示しています
  • APIの詳細はAWS公式ドキュメント AnthropicClaude メッセージ API – Amazon Bedrock を参照してください
  • AWS CLIでプロファイルを指定(--profile [profile_name])してログインしている場合、コード内で session = boto3.Session(profile_name='profile_name') のように指定が必要です

活用例

curlとの組み合わせ

curlコマンドで取得したWebページ(HTML)に対して、プロンプトで処理を指示出来ます。

$ cat ページタイトルを日本語で表示.txt
以下のHTMLソースから、titleを取り出し、日本語に翻訳してください。

$ curl -sS https://example.com/ | ask_sonnet ページタイトルを日本語で表示.txt
タイトルは "Example Domain" です。これを日本語に翻訳すると "例ドメイン" になります。

入力トークン数: 472, 出力トークン数: 37, 想定価格: $0.0020
$ cat ページを要約.txt
以下のWebページから本文を読み取り、数行で簡潔に要約して表示してください。

$ curl -sS https://nhn-techorus.com/news/2024_572.html | ask_sonnet ページを要約.txt
NHN テコラスは、AWSサービスパートナーとして、Amazon Bedrockを活用した生成AIによる業務改善サービスの提供を開始した。専門エンジニアが業務の課題に応じて最適な生成AIモデルを選定し、PoCやAI基盤の構築を支援する。また、生成AIの仕組みと活用方法を解説するセミナーも開催する。生成AIを活用することで、業務の効率化やナレッジ検索の改善などが期待される。

入力トークン数: 10342, 出力トークン数: 160, 想定価格: $0.0334

ターミナル上で気軽に機械翻訳や要約が実行できるだけでも、価値を感じていただけるのではないでしょうか!

テキストファイルの処理

for文と組み合わせると、複数のテキストファイルを一括で処理することが出来ます。

以下はパブリックドメイン化された英語の文学作品を読み取り、概要を日本語で表示する例です。トークン量節約のため、先頭300行のみを処理しています。

$ ls pg*.txt
pg11.txt  pg1513.txt  pg2542.txt  pg2701.txt  pg84.txt

$ cat 物語の概要を表示するプロンプト.txt
物語の抜粋を提示しますので、日本語で概要を示してください。
以下、フォーマットです。

作品名: (ここに翻訳したタイトル)
原題: (翻訳前のタイトル)
概要: (ここに物語の概要を簡潔に)
主な登場人物: (登場人物の名前を,区切りで)

以上です。フォーマット以外の説明や挨拶は不要です。余計な改行もしないでください。

$ for file in pg*.txt; do echo "---- $file ----"; head -300 $file | ask_sonnet 物語の概要を表示するプロンプト.txt; done
---- pg11.txt ----
作品名: アリスの不思議な冒険
原題: Alice's Adventures in Wonderland
概要: この物語は、好奇心旺盛な少女アリスが不思議の国へ迷い込み、奇妙な出来事に次々と出くわしながら、様々な経験をする様子を描いたファンタジーです。ウサ ギに追いかけられ、不思議の国に入ったアリスは、体の大きさが変わったり、様々な生き物と出会ったりしながら、この世界を冒険していきます。
主な登場人物: アリス, 白いウサギ, 歌う入れ子, 青キャテルピラー, 狂った帽子屋, マーチヘア, 白クイーン, 白キング

入力トークン数: 3930, 出力トークン数: 237, 想定価格: $0.0153
---- pg1513.txt ----
作品名: ロミオとジュリエット
原題: Romeo and Juliet
概要: ヴェロナの二つの敵対する一族モンタギューとキャピュレットに生まれた若者ロミオとジュリエットが、運命に翻弄されながらも純愛を貫く悲恋物語。両親の長 年の confirmation of errors を止められないまま、二人は自殺を選んでしまう。
主な登場人物: ロミオ,ジュリエット,フライア・ロレンス,マーキュリオ,ティボルト,ベンヴォーリオ,モンタギュー,キャピュレット

入力トークン数: 2257, 出力トークン数: 203, 想定価格: $0.0098
---- pg2542.txt ----
作品名: 人形の家 (A Doll's House)
原題: A Doll's House : a play
概要: この作品は、ヘンリク・イプセンの有名な戯曲です。ノラとトルヴァルド・ヘルメル夫婦を中心に、19世紀後半の北欧中流階級家庭の生活を描いています。一見 幸せそうな家庭ですが、夫婦の関係に大きな亀裂が見え隠れします。ノラは次第に自己実現を求め、最終的には家庭を捨て、自立する決意をします。伝統的な家父長制 社会に対する批判的な作品となっています。
主な登場人物: ノラ, トルヴァルド・ヘルメル, ランク医師, リンデ夫人, クロクスタード

入力トークン数: 2781, 出力トークン数: 262, 想定価格: $0.0123
---- pg2701.txt ----
作品名: 白鯨
原題: Moby Dick; Or, The Whale
概要: この物語は、復讐を誓った船長アハブと、白鯨モービーディックとの対決を描いている。アハブは自らの義足の原因となった白鯨を追って無人島まで航海し、白 鯨との壮絶な戦いに挑む。しかし、その果てにアハブは白鯨に倒され、乗組員たちも難船する。
主な登場人物: アハブ,クウィークェグ,スターバック,スタブ,フラスク

入力トークン数: 2055, 出力トークン数: 183, 想定価格: $0.0089
---- pg84.txt ----
作品名: フランケンシュタイン、あるいは現代のプロメテウス
原題: Frankenstein; Or, The Modern Prometheus
概要: この物語は、極北探検を目指す船長ロバート・ウォルトンの手紙から始まり、彼の航海中に出会った科学者ヴィクター・フランケンシュタインの話が語られます 。フランケンシュタインは人造人間を創り出しますが、その醜悪な姿に恐れをなし、見捨ててしまいます。見捨てられた被造物は復讐を誓い、フランケンシュタインの 家族を次々と殺害していきます。
主な登場人物: ロバート・ウォルトン,ヴィクター・フランケンシュタイン,フランケンシュタインの被造物(モンスター),エリザベス・ラヴェンツァ

入力トークン数: 3852, 出力トークン数: 276, 想定価格: $0.0157

正規化されていないデータを相手に、他の手段で「ファイル名とその中身のリスト」を得るのは難しいのではないでしょうか。

機能を拡張したい場合

応用的な使い方として、本スクリプトの機能を拡張したい場合、その要望自体もClaude 3 Sonnetに任せてみましょう!

例えば、プロンプトをテキストファイルではなく、文字列として受け取って処理したい場合、以下のように実装させることが出来ます。

$ cat コード改修プロンプト.txt
以下のコードについて、引数でテキストファイルを受け取って中身を利用するのではなく、
引数で文字列そのものを受け取って処理するように改修してください。
説明は不要でコードだけを出力してください。

# 結果を ask_sonnet.new に出力
$ cat /usr/bin/ask_sonnet | ask_sonnet コード改修プロンプト.txt > ask_sonnet.new

入力トークン数: 757, 出力トークン数: 603, 想定価格: $0.0113

# 変更点を確認
$ diff -U0 /usr/bin/ask_sonnet ask_sonnet.new
--- /usr/bin/ask_sonnet 2024-03-27 19:58:48.267543400 +0900
+++ ask_sonnet.new      2024-03-27 22:34:41.557543400 +0900
@@ -12,2 +12 @@
-# ファイル指定があればシステムプロンプトを読み込む
-system_prompt = ""
+# システムプロンプト
@@ -15,6 +14,3 @@
-    try:
-        with open(sys.argv[1], 'r', encoding='utf-8') as file:
-            system_prompt = file.read()
-    except Exception as e:
-        print(f"ファイルの読み込み中にエラーが発生しました: {e}", file=sys.stderr)
-        sys.exit(1)
+    system_prompt = sys.argv[1]
+else:
+    system_prompt = ""

$ echo "こんにちは!急に暖かくなりましたね。" | bash ask_sonnet.new "以下の文を新商品のPR文っぽくしてください"
こんにちは!はい、春の陽気を感じられる気候になりましたね。新しいシーズンを迎え、軽やかな気分になれるような新商品をご紹介させていただきます。

「春色浪漫コレクション」は、やわらかな風に誘われる桜の花びらのような淡い色合いと、しなやかな生地でお作りした、春を体現 したアイテムです。優雅な装いでこの上ない陽春の雰囲気を味わえるでしょう。

軽やかな着心地で、旬の新緑を映し出す色鮮やかなデザインは、春のお出かけを格別の体験に変えてくれることでしょう。一年で最 もロマンティックなこの季節にふさわしい、上品で夢心地なコレクションをこの機会にぜひご堪能ください。

入力トークン数: 44, 出力トークン数: 272, 想定価格: $0.0042

さいごに

Amazon Bedrockを使えば、Claude 3 Sonnetのような生成AIモデルを気軽に活用できます。特に、費用請求や権限管理の仕組みがAWSに一本化されるため、すぐに検証を始められるのがメリットです。

また、Amazon Bedrockではいずれのモデルを利用した場合もAWSに閉じた環境で実行され、ユーザの入力データがモデル開発元に提供されたり、学習に利用されることはありません。この点も大きな安心材料ではないでしょうか。
参考: データ保護 – Amazon Bedrock

今回はレガシーにターミナルからの活用例をご紹介しましたが、コマンド化出来るということは、あらゆる場面に組み込めるということです。応用するとCI/CDパイプラインでの自動レビューやChatOpsでのAIアシスタントなど、幅広い用途での活用が期待できます。ぜひお試しください!

テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!

sdat

2015年新卒入社。物理とクラウドの運用現場と、クラウド移行のチームを経て、今はCCoEチームのマネージャーです。初めてのPCはVineLinux、趣味で触るのはJavaScript……でしたが、ChatGPTのお陰で言語不問になりました。物事を手持ちの札で解決できたときが一番楽しい。最強になりたい。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら