LoginSignup
2
0
生成AIに関する記事を書こう!
Qiita Engineer Festa20242024年7月17日まで開催中!

AWSのbedrockにclaude3.5が出たのでPythonで呼び出してみた

Last updated at Posted at 2024-06-21

事前準備

  • aws configureでiamをcliに登録しておく
  • bedrockでClaude3.5 sonnetを有効かしておく

モデルIDを取得する

下のコードでmodel_idにclaude-3-5が入っているidを取得できる。

def search_model(query):
    response = client.list_foundation_models()

    for model in response['modelSummaries']:
        if query in model['modelId']:
            print(model['modelId'])

search_model("claude-3-5")

サンプルコード

取得したIDをしたのように埋め込む

from pydantic import BaseModel, Field, ValidationError
import boto3
import json

class ChatWithClaudeParams(BaseModel):
    prompt: str = Field(..., min_length=1)
    max_tokens: int = Field(1000, ge=800, le=4096)
    temperature: float = Field(0.7, ge=0.0, le=1.0)
    llm_model_id: str = Field("anthropic.claude-3-5-sonnet-20240620-v1:0")

def chat_with_claude(params):
    if not isinstance(params, ChatWithClaudeParams):
        raise TypeError("params must be an instance of ChatWithClaudeParams")

    bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')
    
    body = json.dumps({
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": params.max_tokens,
        "messages": [{"role": "user", "content": params.prompt}],
        "temperature": params.temperature
    })

    response = bedrock.invoke_model(
        body=body,
        modelId=params.llm_model_id,
        contentType="application/json",
        accept="application/json"
    )

    response_body = json.loads(response['body'].read())
    return response_body['content'][0]['text']


try:
    params = ChatWithClaudeParams(prompt="Hello, Claude!")
    result = chat_with_claude(params)
    print(result)
except ValidationError as e:
    print(e.json())
except TypeError as e:
    print(str(e))

画像の内容について質問してみる

from pydantic import BaseModel, Field, ValidationError
import boto3
import json
import base64

class ChatWithClaudeParams(BaseModel):
    prompt: str = Field(..., min_length=1)
    max_tokens: int = Field(1000, ge=800, le=4096)
    temperature: float = Field(0.7, ge=0.0, le=1.0)
    llm_model_id: str = Field("anthropic.claude-3-5-sonnet-20240620-v1:0")
    image_path: str = Field(None)  # 画像ファイルのパスを追加

def chat_with_claude(params):
    if not isinstance(params, ChatWithClaudeParams):
        raise TypeError("params must be an instance of ChatWithClaudeParams")

    bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')
    
    messages = [{"role": "user", "content": params.prompt}]

    # 画像が指定されている場合、Base64エンコードしてメッセージに追加
    if params.image_path:
        with open(params.image_path, "rb") as image_file:
            image_data = base64.b64encode(image_file.read()).decode('utf-8')
        messages[0]["content"] = [
            {"type": "text", "text": params.prompt},
            {"type": "image", "source": {"type": "base64", "media_type": "image/jpeg", "data": image_data}}
        ]

    body = json.dumps({
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": params.max_tokens,
        "messages": messages,
        "temperature": params.temperature
    })

    response = bedrock.invoke_model(
        body=body,
        modelId=params.llm_model_id,
        contentType="application/json",
        accept="application/json"
    )

    response_body = json.loads(response['body'].read())
    return response_body['content'][0]['text']

params = ChatWithClaudeParams(
    prompt="この画像について説明してください。",
    image_path="cute_dog.jpeg"
)
response = chat_with_claude(params)
print(response)

使った画像

cute_dog.jpeg

出力結果

この画像は、公園のような屋外の風景の中で、かわいい子犬が描かれています。

犬は茶色と白の毛色で、大きな目と笑顔を見せています。舌を出して幸せそうな表情をしており、とても愛らしい雰囲気です。

背景には青い空と白い雲、緑の芝生や木々が描かれています。遠くには街並みが見え、公園のベンチやゴミ箱も配置されています。

全体的に明るく温かみのある色使いで、cartoon風のイラストスタイルで描かれています。犬の表情や姿勢、背景の細かい描写など、細部まで丁寧に描かれた可愛らしいイラストです。

この絵は、のどかな公園での楽しいひとときや、ペットとの触れ合いの喜びを感じさせるような、温かい雰囲気を醸し出しています。

LangChainでやってみる

pip install -U langchain langchain-community langchain-aws

LangChainで出力制御もする

from langchain_aws import ChatBedrock
from langchain.schema import HumanMessage
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from typing import List

# Pydanticモデルの定義(変更なし)
class WeatherResponse(BaseModel):
    temperature: float = Field(description="気温(摂氏)")
    conditions: str = Field(description="天気の状態")
    precipitation_chance: float = Field(description="降水確率(%)")
    recommendations: List[str] = Field(description="おすすめの活動リスト")

# 出力パーサーの作成(変更なし)
parser = PydanticOutputParser(pydantic_object=WeatherResponse)

# Bedrockの設定
bedrock_chat = ChatBedrock(
    model_id="anthropic.claude-v2",
    client=None,  # AWS SDKのクライアントを設定
    region_name="us-east-1",  # 適切なリージョンを指定
)

# プロンプトテンプレートの作成(変更なし)
template = ChatPromptTemplate.from_messages([
    ("human", "今日の{location}の天気を教えてください。{format_instructions}"),
])

# チャット関数
def get_weather(location: str):
    messages = template.format_messages(
        location=location,
        format_instructions=parser.get_format_instructions()
    )
    response = bedrock_chat.invoke(messages)
    return parser.parse(response.content)

# 使用例
try:
    weather = get_weather("東京")
    print(f"気温: {weather.temperature}°C")
    print(f"天気: {weather.conditions}")
    print(f"降水確率: {weather.precipitation_chance}%")
    print("おすすめの活動:")
    for rec in weather.recommendations:
        print(f"- {rec}")
except Exception as e:
    print(f"エラーが発生しました: {e}")
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0