前回に続き、ChatGPTのAPIを使って、ちょっとしたツールを作成してみましょう。ChatGPTは語学がとても堪能なので、今回は、いろいろな言語への翻訳ツールを作成してみましょう。
多言語翻訳ツールを作ってみよう
昔から、マレーシアなど他民族国家を旅行すると、案内板やレストランのメニュー表などが、いろいろな言語で書かれているのを目にすることができます。最近では、日本でも観光客が増えてきたので、海外の観光客が立ち寄るお店では、案内がいろいろな言語で書かれることも増えてきました。
そこで、今回は、いろいろな言語の案内を一気に作ることができる多言語翻訳ツールを作ってみましょう。翻訳機能自体は、ChatGPTのAPIを利用して実現してみましょう。
ChatGPTは語学が得意 - どんな言語が話せるの?
会話型AIのChatGPTは、いろいろな言語で話すことができるだけでなく翻訳も得意です。「英語に翻訳して」と頼むことで、翻訳ツールとして使うこともできます。
試しに、ChatGPT 4に「ChatGPTは何カ国語を話すことができますか?ChatGPTが話せる言語の一覧を列挙し、その言語ごとに、どのくらいの能力があるのかを数値化し、グラフに描画してください。」と尋ねてみると、次の画面のようなグラフを描画してくれました。
実際、このグラフでも英語が最も高い数値を出しているだけあって、日英翻訳はかなり自然です。また、その他の言語も、それなりに良い感じで訳してくれます。
翻訳ツールの概要
それで、ここで作る翻訳ツールですが、下記のような構成のものを考えました。図で見るとちょっと複雑に見えるかもしれません。しかし、基本的には、ユーザー、Node.jsで作ったWebサーバー、ChatGPT APIと3者が登場し、相互に通信するという形になります。
そして、単に、Node.jsを使ったWebサーバーから、ChatGPT APIを呼び出しているだけです。ただし、操作性をよくするために、JavaScript(以後JSと略します)のFetch APIを使って、HTMLから非同期通信でWebサーバーにアクセスするようにしています。
通信やアクションを箇条書きにすると、次のような流れになります。
- (1) ユーザーがブラウザでNode.jsで作ったWebサーバーにアクセスする
- (2) WebサーバーはHTML「index.html」ファイルをユーザーに返す
- (3) ユーザーが翻訳したい文章をテキストエリアに入力して「翻訳」ボタンを押す
- (4) クライアントJSのFetch APIでWebサーバー(URIが「/translate」)に文章を送信
- (5) Webサーバーは、文章を受け取って、翻訳プロンプトと文章を組み合わせて、ChatGPT APIを呼び出す
- (6) ChatGPT APIが翻訳結果を返信、Webサーバーがそれを受け取って、(4)のクライアントJSに返す
- (7) クライアントJSがテキストエリアに翻訳結果を表示する
プロジェクトの準備
今回も、前回に引き続き、Node.jsを使ってブラウザ上で動くツールを作ってみましょう。最初に、JavaScriptの実行エンジンのNode.jsをインストールしておいてください。
続いて、プロジェクトを作成するディレクトリを作って、必要となるライブラリをインストールしましょう。ターミナル(WindowsならPowerShell、macOSならターミナル.app)を開いて、以下のコマンドを実行しましょう。
# プロジェクトのフォルダを作成
mkdir multi_translator
# プロジェクトのフォルダに移動
cd multi_translator
# パッケージを初期化
npm -f init
npm install openai --save
npm install express --save
ChatGPTのAPIを使うため、APIキーを作成しよう
今回のプログラムを実行するためには、OpenAIにユーザー登録し、APIキーを取得する必要があります。APIキーを取得する方法は、本連載の24回目を参考にしてください。APIキーを取得したら、忘れないようにメモっておきましょう。
Webサーバー側のプログラム「server.js」
この翻訳ツールのプログラムは、Node.jsで動かすWebサーバー(server.js)と、HTMLファイル「index.html」の二つのファイルで構成されます。二つのファイルを同じディレクトリに配置しましょう。
まずは、Node.js用のプログラム「server.js」から見てみましょう。以下のプログラムは、こちらにもアップロードしています。
// ライブラリを読み込む --- (*1)
const express = require('express');
const OpenAI = require('openai')
const path = require('path')
// APIキーを設定する(以下は書き換えが必要です★★★) --- (*2)
const API_KEY = 'xxx'
// const API_KEY = process.env['OPENAI_API_KEY']
// APIキーを設定したオブジェクトを生成
const openai = new OpenAI({ apiKey: API_KEY });
// ChatGPTに入力するプロンプトのテンプレート --- (*3)
const PROMPT_TEMPLATE = `
### 指示:
次の入力を英語、中国語、韓国語、スペイン語に翻訳してください。
### 入力:
"""__input__"""
### 出力例:
- 英語: ***
- 中国語: ***
- 韓国語: ***
- スペイン語: ***
`
// ChatGPT APIを呼び出す非同期の関数を定義 --- (*4)
async function callChatgpt(msg) {
const params = {
messages: [{ role: 'user', content: msg }],
model: 'gpt-3.5-turbo',
};
const chatCompletion = await openai.chat.completions.create(params);
return chatCompletion.choices[0].message.content;
}
// Webサーバーを起動 --- (*5)
const app = express();
const port = 3001;
const server = app.listen(port, () => {
console.log('[URL] http://localhost:' + port);
});
// サーバーの応答を設定 --- (*6)
app.get('/', (_req, res) => { //index.htmlを返す
res.sendFile(path.join(__dirname, 'index.html'));
});
// 翻訳の応答を設定 --- (*7)
app.get('/translate', async (req, res) => {
let q = '' + req.query.q;
q = q.replace(/"/g, '')
// テンプレートを置換してChatGPTに問い合わせる --- (*8)
const prompt = PROMPT_TEMPLATE.replace('__input__', q);
const result = await callChatgpt(prompt);
const toHtml = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
// 結果を戻す --- (*9)
res.send(toHtml(result));
});
プログラムを確認してみましょう。(*1)では必要なライブラリを読み込みます。(*2)の部分は、APIキーを設定する部分です。書き換えて使ってください。
(*3)では、ChatGPTに送信するプロンプト(指示書)のテンプレートを記述します。このプロンプトを書き換えることにより、ほかの用途に利用することもできることでしょう。実際に翻訳したい文章は、__input__の部分に差し込まれます。(*8)の部分で置換して使います。
(*4)ではChatGPTのAPIを呼び出す関数を定義します。
(*5)ではWebサーバーを起動して、ユーザーからの接続を待ち受けるようにします。ここでは、サーバーのポート番号を3001に指定しています。
(*6)ではルートへアクセスした時の応答を指定します。HTMLファイルの「index.html」を返します。
(*7)では翻訳を行う「/translate」にアクセスがあった時の応答を設定します。(*8)では、クエリの「q」の内容を(*3)で定義したChatGPTのプロンプトに差し込んで、ChatGPTに問い合わせを行います。そして、(*9)では結果をHTMLに変換して返します。
クライアント側のプログラム「index.html」
そして、以下がクライアント側のHTMLファイル「index.html」です。上記の「server.js」から参照されます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"><title>翻訳ツール</title>
<style>
textarea { width: 99%; background-color: bisque;}
</style>
</head>
<body>
<h1>翻訳ツール</h1>
<div>
翻訳したい内容を下記に入力:<br>
<textarea id="q" rows="4"></textarea><br>
<button onclick="getResult()">翻訳</button>
</form>
</div>
<div>
<h3>翻訳結果:</h3>
<div>
<textarea id="result" rows="8"></textarea>
</div>
</div>
<script type="text/javascript">
// 翻訳ボタンが押された時の処理 --- (*1)
function getResult() {
// 入力されたテキストを取得 --- (*2)
const text = document.getElementById('q').value;
const result = document.getElementById('result');
result.value = '翻訳しています。少々お待ちください...';
// サーバーに翻訳をリクエスト --- (*3)
const query = `q=${encodeURIComponent(text)}`;
fetch(`/translate?${query}`)
.then(response => response.text())
.then(resultText => result.value = resultText);
}
</script>
</body>
</html>
上記のHTMLはとてもシンプルな構成で、「翻訳」ボタンを押したら、(*1)で定義しているJavaScriptのgetResult関数を呼び出すだけのものです。(*2)ではテキストエリア(id=q)に入力されたテキストを取得して、(*3)でサーバーに送信します。翻訳が終わったらその結果をテキストエリア(id=result)に設定します。
プログラムを実行してみよう
それでは、プログラムを実行してみましょう。ターミナル(WindowsならPowerShell、macOSならターミナル.app)を起動します。そして、以下のコマンドを実行します。
$ node server.js
そして、Webブラウザで「http://localhost:3001」にアクセスします。すると、翻訳ツールの画面が表示されます。そこで、翻訳したい内容を上のテキストボックスに入力して「翻訳」ボタンを押します。すると、しばらくすると、翻訳結果が画面下のテキストボックスに表示されます。