Opt Technologies Magazine

オプトテクノロジーズ 公式Webマガジン

ChatGPTを活用した広告テキスト制作アプリケーション「CRAIS for Text」の実装

alt

ノーコードで様々な処理を組み合わせることができるCRAIS for Textの実装について紹介します。

はじめに

こんにちは。AIソリューション開発部の@natsuumeです。最近はChatGPTはじめ生成AIの外部環境変化に振り回される日々を送っています。今回はテキストクリエイティブ制作アプリケーション「CRAIS for Text」の実装について紹介します。

本アプリケーションのエンジニア側の開発体制については、それぞれ

  • 広告効果予測モデルの学習:Melvinさん(AIソリューション開発部)
  • 監視・認証に関するインフラ改修:@abemaさん(チーフアーキテクト室)
  • その他:@natsuume

という形で開発を担当しています。
Melvinさん、阿部さんはOpt Technologies Magazineでも過去記事を公開されていますので気になる方はぜひこちらも合わせてご一読ください。

また、チーフアーキテクト室について気になる方は下記記事をご覧ください。

CRAIS for Textとは

弊社では先日、ChatGPTと自社で開発している効果予測モデルを組み合わせて広告クリエイティブ制作を行う「CRAIS for Text」を発表しました。

アプリケーションの画面例は後ほどフロントエンドに関する項で紹介しますが、処理の流れをグラフ構造で設計・実行するノーコードアプリケーションとなっています。プレスリリース内ではアプリケーションの具体的な内容については割愛しているため、本記事ではこのアプリケーションの内容や実装について解説していきます。

機能と実装

CRAIS for Textはいわゆるサーバレス形式のアーキテクチャを採用しており、AWS上で構築しています。

サーバサイド・アーキテクチャ

具体的なアーキテクチャ図は次のようになります。

アーキテクチャ図

CRAIS for Textは元々社内利用を前提として開発を行っていたアプリケーションですがプレスリリース後の社内外の反応から社外利用も可能なように改修を行った背景があります。そのためサーバサイドなど大部分は社内・社外で共有しつつ、差分が発生するフロントエンドコードを置いているS3およびCloudFrontのみ別々に用意するといった構成を今回は取っています。

アプリケーションで提供している主要機能である効果予測やOpeAI APIを利用したテキスト生成などは、利用しているプロンプトの隠蔽とAPI Keyの漏洩防止などの理由から全てAWS Lambda上で実行しています。

また、API Gatewayから直接Lambdaを呼び出さずにStep Functionsを経由しているのはAPI Gatewayは29秒を超えるとタイムアウトしてしまい、今回のような比較的レスポンスが返ってくるまで時間がかかるLambdaを直接呼び出すことができないためです。

API Gatewayには各LambdaごとにStep FunctionsのStartExecutionを呼ぶエンドポイントと、全てのLambdaで共有するDescribeExecutionのエンドポイントを用意し、フロントエンド側からはStartのAPIをリクエストし、返ってきたexecutionArnを用いて定期的にDescribeのAPIをポーリングするようにしています。

また、IaCとしてはAWS CDKを利用しています。

フロントエンド

フロントエンドでは、React + TypeScript + Recoilという構成で実装しています。この技術選定に関しては実のところさほど重要な理由があるわけではありません。元々1人で開発をするにあたりフロントエンド初心者だったこともあり、例えば状態管理であればReduxなど他のライブラリも含めて経験がほとんど無かったというのが一番大きな理由です。

どの技術を選ぶにせよほぼ1から勉強する必要があったため、それなら新しいもので評判が良さそうなものを使ってみよう、ということでRecoilを採用した経緯があります。フロントエンドフレームワークについては、開発を始めた当時はNext.jsなどは今ほど名前を見かけなかったためReactを採用しています。もし、新しく今すべての知識がまっさらな状態からこの開発を始めたとしたらNext.jsを採用したかもしれません。

さて、実際のアプリケーションUIは下記のようになっています。

画面UIのスクショ

特徴的なのは中央のグラフ構造を作成する部分ですが、こちらはReact Flowというライブラリを利用しています。このようなグラフ構造によるノーコードUIを採用した理由としては、昨今話題となっているChatGPT PluginsやLangChainのAgent機能のように、複数のモデルの入出力や一般的なfilter・map処理を組み合わせることで単体のモデルだけでは実現が困難な出力制御や難しいタスクへの適用、多種多様な用途を単一のUIで実現することができると考えたためです。

(実際には元々ChatGPTを前提としていたわけではありませんが……)

React FlowはグラフUIを簡単に作成できる非常に使い勝手の良いライブラリですが、使う上で難しかった点として状態管理、特にノードとデータをどこまでReact Flowで管理し、どこから自分で(今回はRecoilで)管理すべきかという判断が悩ましいところでした。

React Flowが標準的に提供しているクラスの場合、Nodeがdataフィールドを持つ構成になっています。これは例えばアーキテクチャ図のようにノードとその関係性を静的に表現する用途としては十分です。しかし、今回のようにデータをパイプライン処理のように加工していくことを表現する有向グラフの場合、dataが肥大化してしまい少しの変更で頻繁に再レンダリングが発生してしまったり処理前後のデータとそれらの受け渡しなどの設計が難しく、未だにしっくり来る状態管理設計ができていないのが現状です。

ChatGPTの活用

記事タイトルにもあるChatGPTは、本アプリケーションでは現在広告テキストの生成に利用しています。前述の画面UIのスクリーンショットにも少し写っていますがテキスト生成ノードとしてユーザにいくつかの項目を入力してもらいます。現在の項目は下記の通りですが、これらの種類やフォーマット等については今後実際のユースケースを見ながら適宜変更していく予定です。

  • テキストの種別(タイトル or 説明文)
  • 生成するテキストの数
  • 業種・業界
  • 企業・ブランド名
  • ターゲット
  • キーワード
  • 訴求
  • 禁止ワード・禁止表現

このようなデータをAPIにリクエストとして投げてLambda内でプロンプトを組み立て、それをOpenAI APIに渡すようにしています。ChatGPTは手軽に非常に質の高いテキストを生成できるものですが各種パラメータとプロンプトさえ分かれば誰でも再現が可能であり、フロントエンドでリクエストを投げてしまうとAPI KEYの漏洩の可能性のほか、実際に利用しているプロンプトが見えてしまうという問題があります。

社内向けであれば別にプロンプトがユーザから見えていても問題なかったのですが、この点も社外向けリリースにあたり改修した点の1つです。

プロンプトの工夫点

プロンプトの工夫点として簡単な内容をいくつか紹介します。1つは英語のプロンプトを利用することです。既に広く知られている通り、ChatGPTは英語のほうが性能が高いと言われています。実際、プロンプトを英語にすることで日本語のケースと比べてGPT-3.5-turboでもGPT-4を日本語で利用した場合に比較的近い出力が得られるケースが多いです。英語のプロンプトを利用する際で、今回のような最終出力として日本語を要求する場合、取りうる選択肢として

  • 英語で生成した内容に対してもう1段翻訳ステップを噛ませる
  • 「出力は日本語で出力する」という(英語の)指示を与える

という2通りの手段が考えられます。多段的に処理した場合の実行時間や、実際に複数のユーザが利用するようになった際にRate Limitに与える影響が読みきれなかったため、本アプリケーションのプロンプトでは後者の手段を採用しています。実際、後者のプロンプトでも、日本語でのプロンプトと比べ出力の質や安定性は大きく向上しました。

また、それ以外のプロンプトの工夫としてフォーマットの制御があります。本アプリケーションのプロンプトでは愚直に「JavaScriptのJSON.parse()に与えるので直接与えられるJSON形式で出力してください。JSONスキーマは……」というような文言を記載することで制御しています。一見こういった単純な指示ではうまく行かないように思いますが(実際、日本語のプロンプトではGPT-3.5-turboだとフォーマットが崩れる事が多い)GPT-4を利用したり、GPT-3.5-turboであっても英語で前述の指示を記載するだけで比較的フォーマットの制御は容易に行うことができます。

(もっとも、これは現在であればFunction Callingの機能がリリースされたため、新しくプロンプトを設計する際に利用する工夫ではないと思いますが……)

そのほか、いわゆる主要なプロンプトエンジニアリング手法などを適宜取り入れつつ、内容の改善を図っています。プロンプトエンジニアリング手法に興味のある方でプロンプトエンジニアリングガイドをまだ読んだことがない方は、ぜひ一度目を通すことをおすすめします。

現在の課題・今後の展望

今回、3月のOpenAI APIのリリースにはじまり6月の社外向けリリース開始というスケジュールだったこともありまだまだ機能面・UI/UX面でも改善が必要な箇所は残っています。また、すでに一部のコードが負債化しつつあるため、これらの解消も課題です。7月以降はそういったリファクタリングなどと現在のアプリケーションの改修、新機能の開発などをいかに並行して行っていけるかが重要になりそうです。

これはあくまで私個人が構想している段階ですが、アプリケーションのエンジン部分(コアとなるグラフ関連機能)についても以下のような機能追加を行っていきたいと思っています。

  • 循環グラフを可能にする(繰り返し処理を表現できるようにする)
  • より発展的・多様なグラフ設計への対応
  • 作成したグラフ構造の保存、読み込み
  • 同じ組織内のユーザ間で作成したグラフ構造の共有

まとめ

今回はCRAIS for Textの実装についての解説や今後の展望についても簡単に紹介しました。ChatGPTはじめ昨今外部環境の変化が激しいですが、今後もなんとか追従しつつ独自の強みとなるプロダクトを開発していきたいところです。

Opt Technologies ではエンジニアを募集中です。カジュアル面談も可能ですので、下記リンク先よりお気軽にご応募ください。