LoginSignup
0
1

AmazonBedrock(Claude3 Vision)をLangChain+Streamlitで使う

Last updated at Posted at 2024-04-11

AWSサンプルのAmazon Bedrock QuickStartのサンプルがClaude3になっていなかったので作ってみました。

「claude_3_examples/image_api_st.py」が追加されていましたが、Stable DiffusionかAmazon Titanで制定した画像のタイトルをClaude3に問い合わせるものであり、思ったものと違いました。

以下がAmazon Bedrock(Claude3 sonnet)をLangChain+Streamlitで動かすPythonコードです。
テキストだけでなく、画像の入力にも対応しています。

chat_bedrock_st.py
import time

import boto3
import base64
import streamlit as st

from langchain_community.chat_models import BedrockChat
from langchain_core.messages import HumanMessage
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

st.title("ChatBedrock")

# Setup bedrock
bedrock_runtime = boto3.client(
    service_name="bedrock-runtime",
    region_name="us-east-1",
)

@st.cache_resource
def load_chat():
    chat = BedrockChat(
        client=bedrock_runtime,
        model_id="anthropic.claude-3-sonnet-20240229-v1:0",
        streaming=True,
        callbacks=[StreamingStdOutCallbackHandler()],
        model_kwargs = {"temperature": 0.0}
    )

    return chat

chat = load_chat()

uploaded_file = st.file_uploader("Image", type="jpg")

if "messages" not in st.session_state:
    st.session_state.messages = []

for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

if prompt := st.chat_input("What is up?"):
    st.session_state.messages.append({"role": "user", "content": prompt})
    with st.chat_message("user"):
        st.markdown(prompt)

    with st.chat_message("assistant"):
        message_placeholder = st.empty()
        full_response = ""
        
        content = []
        
        if uploaded_file:
            image_data = base64.b64encode(uploaded_file.read()).decode('utf-8')
            content.append(
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/jpeg",
                        "data": image_data
                    }
                }
            )
    
        content.append(
            {
                "type": "text",
                "text": prompt
            }
        )

        messages = [
            HumanMessage(
                content=content
            )
        ]

        # prompt = prompt_fixer(prompt)
        result = chat.invoke(messages)

        # Simulate stream of response with milliseconds delay
        for chunk in result.content.split(' '): # fix for https://github.com/streamlit/streamlit/issues/868
            full_response += chunk + ' '
            if chunk.endswith('\n'):
                full_response += ' '
            time.sleep(0.05)
            # Add a blinking cursor to simulate typing
            message_placeholder.markdown(full_response + "")

        message_placeholder.markdown(full_response)

    st.session_state.messages.append({"role": "assistant", "content": full_response})

以下のサイトを参考にしました。

以下のような感じで動作します。よく見ると、ClaudeがOpenAIになっています。

image.png

入力した画像は以下の通りです。

test.jpg

0
1
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
0
1