【要約】CLIのRAGツールを、コアを分離してあったおかげでWebアプリまで広げられた話 [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
開発者が、自作したCLIツールを非エンジニアにも提供したいと考えた際、インターフェースの制約に直面した。コマンド操作ができるユーザーに限定されるツールを、ブラウザから利用可能な形へ昇華させる必要があった。
直面した課題:
直面した課題:
- ・CLIツールは、コマンド操作ができるユーザーしか利用できない。
- ・RAGの初期化(ベクトルDB構築やLLMの準備)は非常に重い処理である。
- ・リクエストごとに初期化を行うと、レスポンスレイテンシが許容できないレベルになる。
// Approach
開発者は、コアロジックをインターフェースから完全に分離する設計思想に基づき、段階的な拡張を行った。既存のロジックを「入り口」から独立させることで、中身を書き換えずに新しい窓口を追加した。
具体的な手法:
具体的な手法:
- ・コアロジックの関数化:
answer_question関数として、検索と生成の処理を独立させた。 - ・FastAPIによるAPI化:
api.pyを作成し、POST /askエンドポイントを実装した。 - ・lifespanによるリソース管理:
@asynccontextmanagerを使い、サーバー起動時に一度だけ重い初期化を行う。 - ・Pydanticによる型定義:
AskRequestクラスを定義し、不正なリクエストを入り口で遮断する。 - ・シンプルなUI実装: FastAPIからHTMLを返し、JavaScriptの
fetch()でAPIを呼び出す構成とした。
// Result
開発者は、設計の恩恵により、既存のロジックを一行も変更することなくWebアプリ化を実現した。これにより、ツールは「自分専用」から「他人が触れるもの」へと進化した。
得られた成果:
得られた成果:
- ・非エンジニアでもブラウザ経由でツールを利用可能になった。
- ・lifespanの活用により、リクエストごとの初期化コストを排除した。
- ・型定義により、不正なJSONリクエストに対して適切なエラー(422 Unprocessable Entity)を返せるようになった。
Senior Engineer Insight
> 設計の美学は「関心の分離」にある。本件は、ビジネスロジックとI/Oを分離したことで、拡張コストを最小化した好例だ。特に、lifespanを用いたリソースのシングルトン的な管理は、LLMのような重いモデルを扱う際の定石である。ただし、UIをFastAPIに同梱する構成は、フロントエンドが複雑化すると保守性が低下する。小規模なPoCには最適だが、大規模展開時はフロントエンドの分離を検討すべきだ。