作るもの
Amazon Bedrock の API を local から叩きたかったので Chatbot を作ることにしました。
完成物は動画を見ていただくとイメージがつくかと思いました。
AI 系のアプリケーションは Python で実装されることが多いですが、Langchain など周辺ツールが不要で、ただ API を叩くだけであれは言語に制約はありません。 今回は CLI ツールとしての扱いやすさから Go を選択しました。
事前準備
Amazon Bedrockを使用するには、事前に使用したい基盤モデルを有効化する必要があります。詳細な手順は以下のリンクを参照してください。 まだの人は以下のリンクを参照してください。
Amazon Bedrock 基盤モデルへのアクセスの追加または削除 - Amazon Bedrock
【さらっと触りたい方へ】Amazon Bedrock を簡単に触ってみよう
API の実装
sdk のサンプルコードを読むと、薄い client を実装してくれていることがわかります。
SDK for Go V2 を使用した Amazon Bedrock ランタイムの例 - AWS SDK コード例
基本的に payload は自分で組み立てます。
type AnthropicRequest struct {
Prompt string `json:"prompt"`
MaxTokensToSample int `json:"max_tokens_to_sample"`
Temperature float64 `json:"temperature"`
TopP float64 `json:"top_p"`
TopK int `json:"top_k"`
StopSequences []string `json:"stop_sequences"`
}
作った requestBody を引数として与えつつ client.InvokeModel を呼び出します。
output, err := client.InvokeModel(context.TODO(), &bedrockruntime.InvokeModelInput{
Body: jsonPayload,
ModelId: aws.String(modelID), // modelID = "anthropic.claude-instant-v1"
ContentType: aws.String("application/json"),
})
ここで、client と jsonPayload はそれぞれ以下のように実装されています。
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
if err != nil {
fmt.Printf("Error loading AWS configuration: %v\n", err)
return
}
client := bedrockruntime.NewFromConfig(cfg)
request := AnthropicRequest{
Prompt: prompt,
MaxTokensToSample: 4000,
Temperature: 0.7,
TopP: 0.9,
TopK: 50,
StopSequences: []string{"\n\nHuman:"},
}
jsonPayload, err := json.Marshal(request)
prompt の形式
Claude の LLM で chatbot を作る場合、prompt は以下の形式にします。
Human: <your input> Assistant:
<your input> の部分を適当に質問にして、 Amazon Bedrock マネジメントコンソールの Playground に入力すると、AI の回答が生成されます。
このように、素朴に LLM を使って Chatbot を作ると、prompt を工夫して Chatbot のように見せることになります。
余談ですが、OpenAI の Chat API はチャット用に interface が用意されていて、LLM を意識せずに使えるようになっています。 追記:Claude でも Messages API *1 で同様のサポートがされていました。みのるん様補足いただきありがとうございました 🙏 *2
さて、response は prompt の続きの部分を返してくれるので、
type AnthropicResponse struct {
Completion string `json:"completion"`
}
と struct で受け取って、中身を取得してユーザーに表示すれば会話の一往復が完成します
fmt.Printf("AI: %s\n", strings.TrimSpace(answer))
継続的に会話できるようにする
過去の会話を引き継いで継続的に会話できるようにするには、prompt に会話の履歴も含めれば OK です
Human: <your input> Assistant: <response> Human: <your input> Assistant: <response> Assistant:
上記の形式になるように以下のようなループ処理を実装します:
const prefix = "\n\nHuman: "
const postfix = "\n\nAssistant: "
// init
fmt.Print("You: ")
conversation := "" + prefix
// loop to continue chat
for {
input := // get input from console
conversation += input + postfix
answer := callBedrock(conversation)
fmt.Printf("AI: %s\n", strings.TrimSpace(answer))
conversation += strings.TrimSpace(answer)
fmt.Print("You: ")
conversation += prefix
}
このコードでは、ユーザーの入力と AI の応答を交互に会話履歴に追加しています。
これで完成です。
サンプルの結果
前の自身の回答を踏まえて次の回答を生成できているのがわかります
You: list 3 places to visit in japan AI: Here are 3 popular places to visit in Japan: 1. Tokyo - The bustling capital is a modern metropolis with endless attractions. Must-sees include Tokyo Tower, Imperial Palace, Shibuya crossing, Akihabara electronics district, and sensory-overloading Shinjuku. 2. Kyoto - As the former imperial capital, Kyoto has preserved glorious temples, shrines, and gardens that provide a window into traditional Japanese culture. Top spots include Kinkaku-ji (Golden Pavilion), Fushimi Inari Taisha (shrine with thousands of torii gates), and Arashiyama bamboo grove. 3. Hokkaido - Japan's northernmost main island is known for its natural beauty. In Sapporo, see the picturesque Odori Park and try the local specialty of miso ramen. For scenic coastal areas and hiking, head to Furano or Daisetsuzan National Park. Onsen hot springs are also abundant across Hokkaido. You: are these 3 places close? AI: No, those 3 places in Japan are not close to each other and require travel between them: - Tokyo and Kyoto: Tokyo and Kyoto are on different main islands of Japan - Tokyo is on Honshu island while Kyoto is also on Honshu but further west. The cities are over 600 km (370 miles) apart by road/rail. Travel between them requires a 2-3 hour flight or shinkansen bullet train ride of around 2.5 hours each way. - Tokyo and Hokkaido: Tokyo and Hokkaido are even further apart, as Hokkaido is Japan's northernmost main island. The distance between Tokyo and Sapporo, Hokkaido's largest city, is over 1,200 km (745 miles). Flights take around 1.5 hours while the fastest train/ferry route is over 9 hours each way. - Kyoto and Hokkaido: Kyoto and Hokkaido are on separate islands with Kyoto being all the way at the south of Honshu while Hokkaido is north of Honshu. The distance between Kyoto and Sapporo is over 1,800 km (1,118 miles). Travel between the two requires changing flights or trains/ferries and takes all day. So in summary, while all three places are top tourist destinations in Japan, they require significant travel time between each other due to the geographical spread across multiple islands. Planning visits requires factoring in transportation time. You:
注意点と改善の余地
短い会話ならこれで十分ですが、会話履歴が長くなると、APIのトークン制限に達してしまうので production 向きではありません。ちょっと聞きたい時、くらいに使えるツールになります。
おわりに
会話の入力体験や token のことを考えると、チャットボットを自前実装するのは面倒になりそうです。
全体のコードは Github を参照ください。