こんにちは。PR TIMES 開発本部フロントエンドエンジニアのいわもと (@yoiwamoto) です。
ChatGPT を業務で利用するために、OSS の chatbot-ui を社内でセルフホストして公開しました。
以下は2023年4月5日時点の情報で、今後組織向けにプランなどが改善される可能性は大いにあります。
ChatGPT を会社で利用するハードル
ChatGPT は OpenAI が公開した大規模言語モデルおよびチャットアプリケーションで、うまく活用すれば業務効率を大きく向上させる余地があります。
ただし、会社などでの業務利用となると、少なくとも現時点で以下のようなハードルがあります。
データ活用のオプトアウトは個人で申請する必要がある
OpenAI の利用規約では、ChatGPT 公式のブラウザ UI からのユーザー入力は、サービスの開発や改善に活用され、API 経由の入力はそうではない、ということが明記されています。
“サービスの開発や改善” は当然言語モデルの学習用途も考えられます。
このあたりの線引きは会社によるかと思いますが、ほとんどの場合、業務利用時には入力が学習に利用されることを避けたいと考えられます。
API 以外での利用についても、この規約ページにある Google フォームから申請すれば、入力データが活用されることをオプトアウトすることができますが、会社規模で利用する場合、社員一人一人にこの申請を行なってもらうことになり、運用上かなり難易度が高く、確実性も低いと思います。
支払いは個人で行う必要がある

これは ChatGPT Plus のことですが、支払いは定額サブスクリプション形式で、個人ごとに行う必要があります。
会社でこの費用を負担しようとする場合、通常だと経費申請が必要になってしまうんじゃないでしょうか。
そのうち組織で利用するために organization のような機能ができるとは思いますが、今はやはり運用に若干の負担がかかる状態だと思っています。
(Twitter で見かけた、社員にバーチャルクレジットカードを発行する方法はすごくいいなと思いました)
対応言語が英語のみ
ChatGPT では現時点で英語の UI しか利用できません。
今の所、シンプルなアプリケーションなのでそれほど問題になることはありませんが、やはり会社で利用するにあたっては少し敷居が高いところがあると言えます。
chatbot-ui について
ChatGPT API を使うことを前提にした OSS の ChatGPT ブラウザアプリケーションクローンです。
以下のような特徴があります。
- Next.js、Tailwind CSS と一般的な技術での実装
- 現時点でコントリビュータ数が 66、イシューが 109 件立っているなど開発が活発
- 本家の完全なクローンかと思いきや、会話の検索、JSON インポート・エクスポート、変数を含むテンプレートの管理など便利系の機能が積極的に追加されてもいる
- 多言語対応(日本語も)
- MIT ライセンス
やったこと
今回はこちらの chatbot-ui を fork して少し調整の上、社内でセルフホストしました。
Next.js の Middleware で IP 制限処理を実装
API は従量課金で支払いは会社が行うので、社外の人が利用できてしまうことがないよう何かしら制限を設ける必要があります。
アプリケーション層に認証の仕組みを実装するのも一つの手ですが、多少手がかかると思い、今回は Middleware で IP 制限処理を実装しています。
とりあえずの実装という感じですが参考程度に貼っておきます。
import type { NextRequest, NextResponse } from 'next/server';
export const config = {
matcher: ['/'],
};
export default async function middleware(req: NextRequest) {
// IP ホワイトリスト検証
const ipWhitelist = process.env.IP_WHITELIST?.split(',');
const reqIps = req.headers.get('x-forwarded-for')?.split(', ');
if (ipWhitelist !== undefined && reqIps !== undefined) {
// IP ホワイトリストに含まれていればアクセス許可
if (reqIps.some((ip) => ipWhitelist.includes(ip))) {
return NextResponse.next();
}
}
// ステータスは 200 なのであれだが middleware ではそれが手軽にできないので一旦許容
return NextResponse.json({ message: 'unauthorized' });
}
unauthorized の部分をちゃんとする場合、専用の API Routes を立ててそちらに .rewrite()
する方法が一般的なようです。
環境変数には IP_WHITELIST
を以下のように IP のコンマ区切りで設定します。
IP_WHITELIST='aaa.bbb.ccc.ddd,eee.fff.ggg.hhh'
OPENAI_API_KEY='...'
ちなみに同じことは getServerSideProps でやってもいいはずですが、/
には既に gssp の実装があり、コンフリクトしないようにこれを編集したくない、今回はセルフホストなので関係ないが一般的にはこのような依存のないシンプルな処理はエッジで対応するのがベスプラっぽい、などの理由で Middleware を使っています。
Cloud Run へデプロイ
chatbot-ui のリポジトリはそのまま Vercel にデプロイして動作するようになっているようですが、弊社では他の用途で Vercel を使用しておらず、チームで管理するには困る部分も多かったので、今回は Cloud Run へのデプロイを選択しています。
Artifact Registry にリポジトリを作成、main に変更を push で GitHub Actions からイメージをビルドして push、gcloud CLI から Cloud Run の新しいリビジョンをデプロイ、という構成にしています。
(デプロイ部分を手元で実行しているのは、権限周りがうまく調整できず一旦そうしているだけで、特に意図はありません)
利用方針について
会社での利用方針については、API 利用の場合は利用規約上は学習に活用されないと示されていることもあり、今のところ以下のように許可しない入力を定め、それ以外の入力を許可しています。
許可しない入力
- 一切の顧客情報
- 個人情報
- API キーやパスワードその他の秘匿情報
まとめ
冒頭に挙げたいくつかのハードルは、いずれも ChatGPT 公式で改善される可能性が十分にあるので、今回は時間をかけすぎず、構成にこだわらずにとりあえず動く状態にすることを優先して、1日以内で社内に公開できました。
すぐに使わなくなる可能性もありますし、逆にアップデートしていく可能性もあるかと思っています。
同じようなことをしようとしている方がいれば、少しでも参考になれば幸いです👍