Hono is now AI ready
この記事は英語で書かれた原文をAIが翻訳したものです。
Hono is now AI ready
AI、特にChatGPTアプリケーションを作るために必要なWeb技術はOpenAPIとStreamingです。
OpenAPIはOpenAIではありませんが、OpenAPIを使ってOpenAIアプリケーションを作ることができます。 アプリケーションにやってほしいことをOpenAPIで自然言語として書いておけば、ChatGPTがいい感じに解釈してくれます。
Streamingは、ChatGPTのようにテキストを少しずつ返すアプリケーションに向いています。レスポンスを一度に返すのに30秒かかるとしても、少しずつ返せばユーザーのストレスは減りますし、そのほうがユーザーと「会話している」感じになります。
そして今、Honoはその両方をサポートしています。Zod OpenAPIというHonoの拡張が使えますし、新しい**c.streamText()**でテキストをストリーミングできます。
Zod OpenAPI Hono
ZodOpen API HonoはHonoの拡張で、コードベースの中でOpenAPIを定義し、そのロジックをHonoアプリケーションとして書くことができます。
素晴らしいのは、スキーマをZodで定義できる点です。
超シンプルなブログを作ってみましょう。ユーザーからの入力を次のように想定し、バリデーションします。
const schema = z.object({
title: z.string().min(1),
content: z.string().min(1),
})
このZod OpenAPIでは.openapi()が使えます(この関数はZod to OpenAPIをベースにしています。ありがとうございます!)。
const schema = z.object({
title: z.string().min(1).openapi({ example: 'About today' }),
content: z.string().min(1).openapi({ example: 'Today is a good day...' }),
})
これを使って、パス、コンテンツタイプ、レスポンスの情報をルートとして定義します。
export const routeAddPost = createRoute({
method: 'post',
path: '/posts',
request: {
body: {
content: {
'application/json': {
schema: schema,
},
},
},
},
responses: {
'200': {
description: 'OK',
content: {
'application/json': {
schema: z.object({
ok: z.boolean(),
}),
},
},
},
},
})
「OpenAPIらしい」部分はこれで全部です。あとはいつも通りロジックを実装するだけ。 ここではデータベースにCloudflare D1を使っています。
app.openapi(routeAddPost, async (c) => {
const { title, content } = c.req.valid('json')
const id = crypto.randomUUID()
await c.env.DB.prepare('INSERT INTO posts(id, title, content) values (?, ?, ?)')
.bind(id, title, content)
.run()
return c.jsonT({
ok: true,
})
})
このZod OpenAPIのすごいところは、恐ろしくType-Safeなことです。リクエストのContent-Typeがapplication/jsonなら、c.req.valid()の第一引数としてjsonをサジェストしてくれますし、レスポンススキーマで定義した通りok:booleanを返すことを期待します。
APIスペックはJSONとして生成され、Swagger UIでドキュメントを閲覧できます。

ChatGPT plugin
これをChatGPTのプラグインにしてみましょう。簡単です。マニフェストファイルに「This plugin is for Blogging」と書くだけです。
export const aiPluginJson = {
schema_version: 'v1',
name_for_model: 'Blog',
description_for_model: 'Plug-ins for blogging',
api: {
type: 'openapi',
url: 'http://localhost:8787/openapi.json',
},
//...
}
これで完成です。ヒントを与えると、ChatGPTがブログの内容を考えてデータベースに入れてくれます。しかもこれはCloudflare Workersのようなエッジにデプロイできます。
これがAIにまつわる2つの話のうちの1つ目です。
c.streamText()
Honoの新しい関数c.stream()とc.streamText()を使うと、コンテンツのストリーミングが簡単にできます。
使い方はシンプル。コードを見てください。
app.get('/', (c) => {
return c.streamText(async (stream) => {
stream.writeln('Hello!')
await stream.sleep(1000)
stream.writeln('Hono!')
})
})
ChatGPT Gateway
ChatGPT APIは「stream」をサポートしています。なので、エレガントなコードでChatGPT Gatewayを作れます。
app.post('/api', async (c) => {
const body = await c.req.json<{ message: string }>()
const openai = new OpenAI({ apiKey: c.env.OPENAI_API_KEY })
const chatStream = await openai.chat.completions.create({
messages: PROMPT(body.message),
model: 'gpt-3.5-turbo',
stream: true
})
return c.streamText(async (stream) => {
for await (const message of chatStream) {
await stream.write(message.choices[0]?.delta.content ?? '')
}
})
})
これはただのGatewayですが、適切なプロンプトを与えて、ユーザーごとに履歴を保存すれば、素晴らしいAIの出来上がりです!
AIは楽しい
こうしたAIアプリケーションを作るのはとても楽しいです!
特に、HonoのZod OpenAPI、c.streamText()、そしてCloudflare WorkersはAIと相性抜群です。
ちなみに、この記事は人間が書きました。