LangChain.jsでCloudflare Workers AIの翻訳モデルを利用する
LangChain.jsを使用すると、Cloudflare Workers AIを簡単に活用できます。Text GenerationやText Embeddingsのモデルは問題なく利用できますが、Translationモデルなど一部のモデルは対応していない。LangChain.jsでは新たな実装が必要な場合、自身で処理を実装しChainに組み込むことができます。RunnableLambdaを使用すれば、テキスト生成以外のモデルもLangChain.jsで活用可能。Cloudflare Workers AIを効果的に使用していくためには、適切な実装が必要です。
目次
LangChain.jsでCloudflare Workers AIを利用すると、簡単にチャットモデルやテキスト生成モデルを利用できます。複雑なプロンプトなどでなければ、model
部分だけ後からOpenAIやClaude・Amazon Bedrockなどに差し替えることができるのもLangChain.jsのいいところだと思っています。
import { ChatCloudflareWorkersAI } from "@langchain/cloudflare";
const model = new ChatCloudflareWorkersAI({
model: "@cf/meta/llama-2-7b-chat-int8", // Default value
cloudflareAccountId: process.env.CLOUDFLARE_ACCOUNT_ID,
cloudflareApiToken: process.env.CLOUDFLARE_API_TOKEN,
// Pass a custom base URL to use Cloudflare AI Gateway
// baseUrl: `https://gateway.ai.cloudflare.com/v1/{YOUR_ACCOUNT_ID}/{GATEWAY_NAME}/workers-ai/`,
});
const response = await model.invoke([
["system", "You are a helpful assistant that translates English to German."],
["human", `Translate "I love programming".`],
]);
console.log(response);
翻訳など、テキスト生成 / Embedding以外のモデルが動かない(2024/3時点)
ただ少し気になっているのが、Workers AIが公開している利用可能モデル全てがLangChain.jsで利用できない様子なことです。llama-2
系mistral-7b
系などの[Text Generation]モデルやText Embeddingsのbge-base-en
系などは問題なく利用できます。ただしTranslationモデルについては、ChatCloudflareWorkersAI
などのmodel
プロパティに指定しても意図した動作になりませんでした。
これは推測ですが、APIに対して入力するパラメーターがモデルの種類によって異なることが原因かなと思っています。Text Generationモデル系では、このような形でAPIリクエストを送信します。
const messages = [
{ role: "system", content: "You are a friendly assistant" },
{
role: "user",
content: "What is the origin of the phrase Hello, World",
},
];
const stream = await ai.run(
"@cf/meta/llama-2-7b-chat-fp16", // "@cf/mistral/mistral-7b-instruct-v0.1"なども同様
{
messages,
stream: true,
}
);
これが翻訳のモデル(meta/m2m100-1.2b
)とかですと、全く異なる内容を送信します。
const response = await ai.run(
"@cf/meta/m2m100-1.2b",
{
text: "I'll have an order of the moule frites",
source_lang: "english", // defaults to english
target_lang: "french",
}
);
LangChain.js側で、モデルの用途ごとにリクエスト内容を書き換えるとなると、モデル名ベースのif分岐が必要になりそうですので、ChatCloudflareWorkersAI
やCloudflareWorkersAI
クラスがテキスト生成系以外をサポートするのは難しそうに見えます。LangChain.js側でサポートしてもらうとすれば、CloudflareWorkesTranslationAI
のような用途別のクラスを作るくらいでしょうか・・
RunnableLambdaを使って、Workers AI SDKを直接実行する
2024/03時点でテキスト生成系以外のモデルをLangChain.jsで利用したい場合、RunnableLambda
を利用するのが現実的かなと思います。RunnableLambdaを利用することで、動的な処理をChainにすることができますので、「テキストを生成するChain」と組み合わせて「テキスト生成 -> 翻訳」のようなフローが作れます。
実装方法としては、RunnableLambdaの中でWorkers AI SDKのモデル呼び出しを実行するだけです。
const ai = new Ai(c.env.AI);
const japaneseTranslationChain = RunnableSequence.from([
new RunnableLambda({
func: async (input) => {
const { translated_text: translatedQuestion } = await ai.run('@cf/meta/m2m100-1.2b', {
text: input.text,
source_lang: "english", // defaults to english
target_lang: "japanese"
}
);
return translatedQuestion
}
}),
new StringOutputParser()
])
const result = await japaneseTranslationChain.invoke({ text: "こんにちは" })
console.log(result)
まとめ
Cloudflare Workers AIは、テキスト生成とEmbedding以外にもさまざまな種類・用途のモデルを提供しています。その一方でAPIリクエストの内容(body
)が変わる関係上、LangChain.jsからストレートに利用できるモデルがすこし限定されています(2024/03時点)。
一方でLangChain.js側には、動的な処理を自前で実装してChainにする仕組みも用意されています。そのため、今回のようなLangChain.jsが提供する機能やAPIだけで達成できない実装については、ある程度自前の実装をChain化して持ち込むことも検討する必要がありそうです。
RunnableLambdaをうまく使って、Cloudflare Workers AIを使いこなしていきましょう。