3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Bedrock上のClaudeをcURLとかfetch APIで呼び出す

Last updated at Posted at 2025-08-13

やったこと

LINEとAzure OpenAIで超簡単なbotを以前作ってみたのですが、ちょっとBedrockもさわってみたかったのとバックエンドをClaudeに変えてみたかったこともあって切り替えました。
困ったことと変えた後のコードを残しておきます!

困ったこと

あまりにAWS Bedrock素人すぎて以下の点がわかってなかったです。

Bedrockでテキスト生成する場合はInvokeとConverseの2種類のAPIがある

InvokeAPIはTitanとかClaudeとかそれぞれのモデルの公式なメッセージ定義通りに書き下す必要があるもの。
それに対してConverseはモデルごとの切り替えを容易にするためにBedrock上でユーザープロンプトやシステムプロンプトの定義の仕方を標準化してくれている(モデルごとの差異を吸収してくれている)ようです! なんて便利な!

ということで今回はConverseAPIを使うことにしました。

参考になったclassmethodさんブログ記事

推論パラメータ

基盤モデルをそのまま使うのはClaude4とか新しいやつだとサポート外で、推論パラメータなるインターフェースを使って呼び出すのがいいみたいです。
使うときはBedrockコンソールのモデルカタログにあるモデルごとのモデルIDではなく、推論パラメータのID(Inference profile ID)を使うだけ。
簡単・・・だけど最初基盤モデルを必死に呼び出そうとして30分くらい困ってしまいました。。

Claude4だったら

↓これ”じゃなくて”
image.png

↓これ!
image.png

システムプロンプトの入れ方

  • ConverseAPIで
  • HTTP(cURL)アクセス時の
  • ユーザーではなくシステムプロンプトの

という3つの条件がそろった記述やドキュメントが意外と見つからずに苦戦しました。
公式ドキュメントにも記載がなく・・・

いろいろ調べた結果、HTTP POSTリクエストする際のBodyに入れるMessage属性の中にはuserassistant属性しか入れられないということに1時間くらいして気が付きました。
リクエストボディのMessageと同レベルでSystemの定義をすることが正解だったみたいです。

ということで完成したコード

こちらです。わかりやすいようにAzure OpenAIを使っていた時のコードをコメントで残してみています。
今回は業務報告書のレビューをLINEでしてほしかったので”業務”で始まるLINEメッセージの場合に中身を読みとってコメントしてくれるbotをLambda上で書きました。
PostmanやcURLを使って動作確認した後に、node-fetchライブラリを使ってLambda上では実装しました。

import fetch from "node-fetch/src/index.js"

const API_KEY = "Bearer ******"; //bedrock api key(IAMユーザー上で発行)
// const API_KEY = "*****"; //azure-openai api key
const LINE_TOKEN = "*****";

export const handler = async(event) => {
  const reqBody = JSON.parse(event.body);

  let message = {};

  if (reqBody.events[0].message.type == "text" && reqBody.events[0].message.text.startsWith("業務")) {
    const URL =
      "https://bedrock-runtime.ap-northeast-1.amazonaws.com/model/apac.anthropic.claude-sonnet-4-20250514-v1:0/converse";
      // "https://*****.openai.azure.com/openai/deployments/*****/chat/completions?api-version=2023-03-15-preview";
    const data = {
      "system": [
        {"text" : "あなたは優秀なモチベーターです。業務報告書を受け取った場合は、「特にポジティブフィードバックができそうな点」「特に今後成長するために取り組めそうな点」をそれぞれ見つけて200字以内でコンパクトにコメントしてください。"}
      ],
      messages: [
        // {
        //   role: "system",
        //   content:"あなたは優秀なモチベーターです。業務報告書を受け取った場合は、「特にポジティブフィードバックができそうな点」「特に今後成長するために取り組めそうな点」をそれぞれ見つけて200字以内でコンパクトにコメントしてください。",
        // },
        {
          "role": "user",
          "content":[
            {
              "text" : reqBody.events[0].message.text
            }
          ]
          // content: reqBody.events[0].message.text,
        },
      ],
    };
    const response = await fetch(URL, {
      method: "POST",
      body: JSON.stringify(data),
      headers: {
        "Content-Type": "application/json",
        // "api-key": API_KEY,
        "Authorization": API_KEY,
      },
    });

    const resjson = await response.json();

    message = {
      type: "text",
      // text: resjson.choices[0].message.content
      text: resjson.output.message.content[0].text
    };

    await fetch("https://api.line.me/v2/bot/message/push", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${LINE_TOKEN}`,
      },
      body: JSON.stringify({
        to: reqBody.events[0].source.groupId || reqBody.events[0].source.userId,
        messages: [
          message
        ],
      }),
    });

  }
  return 200;
};

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?