OSSを使った社内LLMツールの爆速開発と運用
みなさんこんにちは!
ワンキャリアでテックリードをしている高根沢(X:@p0x0q_jp)です!
今回は、ワンキャリア社内で使っている社内LLMツールについて、ご紹介できればなと思います。なお、わかりやすく説明するために、合同勉強会をイタンジさんと実施したときのスライドを用います。
はじめに
皆さん、生成AIを実業務に使いこなせていますでしょうか?
ミドル世代にヒアリングした調査によると、IT系ではまだ29%しか使えていないというデータもあります。
ワンキャリアでも、1年前時点で生成AIを使いこなす人はほぼいませんでした。その理由は、以下の2点です。
どのように業務に生成AIを活用すればいいかわからない(イメージが湧かない)
会社的に使って良いのかわからない(社内ルールがない)
そこで、ワンキャリアでは以下の対応を行っています。今回は、開発側がメインなので2についてお話しします。
生成AIルールをCTO/コーポレートIT側で定義し全社展開
社内ルールの元で使える社内LLMツールの開発
とくに、2の要件としては「LLMとチャットができる」「ワンキャリアの社員のみが利用できるように制限できる」「LLMとのやり取りを記録できる」の3つを満たすことが求められました。
社内LLMツール
機能概要
社内LLMツールは、以下の機能を持っています。
ChatGPTの主要モデルとチャット形式でやり取りができる
PC/スマホ対応
社員のみが利用できる
チャットのやり取りをDB上に記録できる
構成
構成としては以下の3つに分かれています。
フロントエンド
役割: 社内LLMツールのUIを提供
バックエンド(LLMプロキシサーバー)
Djangoを採用
役割: OpenAIのエンドポイントをプロキシし、リクエストとレスポンスをDBに保存
クラウドインフラ
GKEを採用
技術選定編
フロントエンドの技術選定
まず、フロントエンドについてです。フロントエンドは、OSSのNextChatを採用しました。NextChatは、クロスプラットフォームをサポートしているリポジトリでStar数が多い(10k以上)だけでなく、OpenAIのエンドポイントをカスタマイズできる要件を満たしていました。
ただし、チャット履歴などはDBではなく、LocalStorage管理(Zustand)となっています。そのため、チャット履歴の管理を行う機構は別途実装する必要があります。
バックエンドの技術選定
次に、バックエンドについてです。バックエンドは、Djangoを採用しました。Djangoは、Pythonで書かれたWebアプリケーションフレームワークで、AI系依存関係を多言語よりも早く導入できるというメリットがあります。
Pythonを採用した理由は、2点ほどあります。
OpenAIパッケージなど、LLM系依存関係を他言語よりも早く、簡単に導入できる
RAG対応を考えた時に、最もサンプルコードが充実しているのはPythonだったため
インフラの技術選定
最後に、インフラについてです。インフラは、Google Cloud / GKEを採用しました。理由は、既存インフラでコストを抑えつつ、既に使い慣れている方法により爆速でインフラを構築するためです。
社内ツールなので、スケールアウトの必要がないため、既存プロダクトの開発環境系をデプロイしているGKEクラスターに、追加でデプロイしています。
このようにすることで、既存インフラに相乗りし、爆速・格安で社内LLMツールを開発することができました。
※格安な理由:GKE上のノードに空きリソースがあったので、追加のリソースなしでデプロイできた。
開発編
フロントエンドの開発
フロントエンドは既にOSSベースとなっているので、認証系の追加改修だけで済みました。具体的には、NextAuth.jsを追加し、社員のみが利用できるようにCognitoによる認証を追加しました。
Cognitoの設定では、Googleアカウントでのみ認証を許可するように設定し、メールアドレスのドメイン情報を検証することで、ワンキャリアの社員のみが利用できるようにしました。
バックエンドは、シンプルなDjangoプロジェクトとして作成したため、OpenAIのエンドポイントをプロキシするAPIを1本追加するだけで済みました。
内容としては、フロントエンドのNextChatからカスタムエンドポイントでリクエストを受け取り、OpenAIのエンドポイントにリクエストを送信し、レスポンスをDBに保存した後に、フロントエンドに返却するというものです。
なお、プロキシサーバーなので、APIの仕様はOpenAIのCompletion APIに準拠しています。
バックエンドの開発で詰まったところ
バックエンドの開発で詰まったところは、ストリームレスポンスを返す機構を標準のSteamingHttpResponseではなく、カスタムメソッドを利用しなければならなかったことです。
理由としては、ストリームレスポンスを標準メソッドで返すと値が空になってしまい、DBに保持できない問題が発生したためです。
この問題を解決するために、カスタムメソッドを利用してストリームレスポンスを返す機構を実装しました。
カスタムメソッドのCachedSteamingHttpResponseに関するコードはスライド中に全て載っているので、興味がある方はご覧ください。
インフラの構築
インフラの構築は、既存に相乗りするだけなのでシンプルです。追加で設定したのはCognitoの設定のみになります。
Cognitoの設定は、認証方法をGoogleアカウントのみ許容するようにしています。
このようにすることで、フロントエンド側でログイン後に取得できるメールアドレスのドメイン情報を検証することで、社員かどうかを判定するようにしています。
完成!
フロントエンドの改修、バックエンドの新規API追加、インフラの設定を行い、社内LLMツールを完成させました。
画面遷移としては、以下の3ステップになります。
ログインしていなければログイン画面が出現する
Cognito経由でGoogleアカウントの画面に遷移する
ログイン後に社員ドメインであれば、チャット画面が表示されて利用できる状態になる。
さいごに
今回は、ワンキャリア社内で使っている社内LLMツールについてご紹介しました。
工夫した点としては、OSSに相乗りすることで、開発コストを抑えつつ、爆速で社内LLMツールを実運用に載せました。
また、インフラも既存のKubernets Clusterに相乗りすることで、インフラコストについても抑えることができました。
各社で社内LLMツールを導入するときの参考にしていただければ幸いです。
▼ワンキャリアのエンジニア組織のことを知りたい方はまずこちら
▼カジュアル面談を希望の方はこちら
▼エンジニア求人票
この記事が参加している募集
この記事が気に入ったらサポートをしてみませんか?