Bedrock Converse API でPDFを読み込む
はじめに
Bedrock Converse APIとは、Bedrockとのメッセージの送受信を実装できるAPIです。
プログラムを介してBedrockを利用する場合、Converse APIを通して実装を行うことになります。
今回はConverse APIのPDF対応機能を用いて、Claude Sonnet 4にPDFを読み込ませていきます。
本記事は、社内作成ツールで利用した技術について書いています。
実装
ローカルのPDFファイルを読み込み、Bedrock経由で要約させる実装を行います。
const client = new BedrockRuntimeClient({
// あらかじめ.envに環境変数を設定しておく
region: process.env.BEDROCK_AWS_REGION,
credentials: {
accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!,
},
});
const pdfPath = path.join(__dirname, "sample.pdf");
const pdfData = readFileSync(pdfPath);
const command = new ConverseCommand({
modelId: "us.anthropic.claude-sonnet-4-20250514-v1:0",
messages: [
{
role: "user",
content: [
{
text: "PDFの内容を箇条書き3つに要約してください。",
},
// 以降、PDF読み込み設定
{
document: {
source: {
bytes: pdfData,
},
name: "sample-pdf",
format: "pdf",
citations: {
enabled: true,
},
},
},
],
},
],
});
const response = await client.send(command);
const contentArray = response.output?.message?.content || [];
const fullText = contentArray
.map(content => ('text' in content ? content.text : ''))
.filter(Boolean)
.join('');
console.log(fullText);
実行
今回読み込ませるsample.pdfは、2000文字程度の架空の業務報告書です。

実際に箇条書き3行に要約させてみた結果がこちらです。
PDFの内容を以下の3つの要点で要約いたします:
• **DXによる経営基盤の強化**:。し、することで業務プロセスの自動化を実現した。
• **人材育成とワークスタイル変革**:。。また、。
• **財務成果と顧客価値の向上**:。顧客面ではし、という成果を上げた。
箇条書きが不自然な日本語になっていますが、PDFに含まれるテキストについては読み取れているようです。
補足
上記のコードで利用しているConverseCommandの指定ルールについて解説します。
このオブジェクトでは、Bedrockに送信したいコンテンツをcontentへと指定します。
const command = new ConverseCommand({
modelId: "us.anthropic.claude-sonnet-4-20250514-v1:0",
messages: [
{
role: "user",
content: [
// こちらに配列で指定
]
},
],
});
配列で指定するとき、各オブジェクト直下のパラメータは単一とする必要があります。
例えば、以下のように指定すると型エラーとなります。
content: [
{
text: "PDFの内容を箇条書き3つに要約してください。",
document: {
source: {
bytes: pdfData,
},
name: "PDF",
format: "pdf",
},
},
]
contentの型はContentBlock[]となっています。(参考)
例えばTextMemberにおいては、text以外のパラメータはneverとして指定できないように定義されています。
このため、複数のデータ種別を送りたい場合は、1つずつ配列に含めることが必要です。
export declare namespace ContentBlock {
/**
* <p>Text to include in the message.</p>
* @public
*/
interface TextMember {
text: string;
image?: never;
document?: never;
video?: never;
toolUse?: never;
toolResult?: never;
guardContent?: never;
cachePoint?: never;
reasoningContent?: never;
citationsContent?: never;
$unknown?: never;
}
/**
* <p>Image to include in the message. </p> <note> <p>This field is only supported by Anthropic Claude 3 models.</p> </note>
* @public
*/
interface ImageMember {
text?: never;
image: ImageBlock;
document?: never;
video?: never;
toolUse?: never;
toolResult?: never;
guardContent?: never;
cachePoint?: never;
reasoningContent?: never;
citationsContent?: never;
$unknown?: never;
}
// 以降省略
NCDC株式会社( ncdc.co.jp/ )のテックブログです。 主にエンジニアチームのメンバーが投稿します。 募集中のエンジニアのポジションや、採用している技術スタックの紹介などはこちら( github.com/ncdcdev/recruitment )をご覧ください!
Discussion