Strands AgentsのTypeScript版がv1.0.0になりました🎉🎉🎉
v1.0.0記念になにかしてみようと思い、以前からお世話になってるAI SDKと連携できるようにアダプターをバイブで作ってみました。
使い方
Next.js App Router Quickstartの手順をベースに解説します。
ちなみに私、最近bun派です。
まず、Next.jsプロジェクトを新規作成します。ウィザードはYes, use recommended defaultsを選択します。
bun create next-app@latest my-ai-app
ディレクトリを移動します
cd my-ai-app
ライブラリーをインストールします。
bun add ai @ai-sdk/react zod
今回、私が作ったstrands-agents-ai-sdk-adapterはnpmに登録してないのでGitHubからします。Strands Agentsも一緒にインストールされます。(いいのかな?)
bun add github:moritalous/strands-agents-ai-sdk-adapter
/chatAPIを作成します。
もろもろをインポートしたうえで、Strands AgentsのAgentを生成します。Strandsのところは、かなり手抜きです。
import { createUIMessageStreamResponse, type UIMessage } from "ai";
import { Agent, BedrockModel } from "@strands-agents/sdk";
import {
toStrandsMessages,
toUIMessageStream,
} from "strands-agents-ai-sdk-adapter";
function createAgent() {
const model = new BedrockModel({
modelId: "global.anthropic.claude-sonnet-4-6",
region: "ap-northeast-1"
});
return new Agent({
model,
printer: false,
systemPrompt: "You are a helpful assistant."
});
}
strands-agents-ai-sdk-adapterの2つの機能を使います。
| 機能 | 内容 |
|---|---|
| toStrandsMessages(messages) | API呼び出し時に受け取るAI SDKの型のメッセージをStrandsの型に変換する |
| toUIMessageStream(stream, callbacks?) | Strands Agentsのストリーム応答をAI SDKの型に変換する |
要するにインプットとアウトプットでひねる ってことですね。
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const strandsMessages = await toStrandsMessages(messages);
const agent = createAgent();
const stream = toUIMessageStream(
agent.stream(strandsMessages, { cancelSignal: req.signal }),
{
onError: (error) => {
console.error("Strands agent stream failed:", error);
},
},
);
return createUIMessageStreamResponse({ stream });
}
ちなみにですが、AI SDK - LangChain Adapterの実装を参考にしてます。
(Codexが)
では、呼び出し画面を作りましょう。これはAI SDKのドキュメント通りです。
'use client';
import { useChat } from '@ai-sdk/react';
import { useState } from 'react';
export default function Chat() {
const [input, setInput] = useState('');
const { messages, sendMessage } = useChat();
return (
<div className="flex flex-col w-full max-w-md py-24 mx-auto stretch">
{messages.map(message => (
<div key={message.id} className="whitespace-pre-wrap">
{message.role === 'user' ? 'User: ' : 'AI: '}
{message.parts.map((part, i) => {
switch (part.type) {
case 'text':
return <div key={`${message.id}-${i}`}>{part.text}</div>;
}
})}
</div>
))}
<form
onSubmit={e => {
e.preventDefault();
sendMessage({ text: input });
setInput('');
}}
>
<input
className="fixed dark:bg-zinc-900 bottom-0 w-full max-w-md p-2 mb-8 border border-zinc-300 dark:border-zinc-800 rounded shadow-xl"
value={input}
placeholder="Say something..."
onChange={e => setInput(e.currentTarget.value)}
/>
</form>
</div>
);
}
これで完成なので、サーバーを起動しましょう。
bun run dev
ストリーミングは伝わりませんが、動きました!
Hono製のサンプルも含めてるので、よかったら見てね。
https://github.com/moritalous/strands-agents-ai-sdk-adapter/tree/main/examples/hono
よろしくお願いします
