blocs/admin: AI機能(Chat / VectorStore)
blocs/admin: AI機能(Chat / VectorStore)
blocs/admin パッケージに同梱される AI 連携クラスです。OpenAI API と Qdrant ベクトル DB を使い、ベクトル検索ベースのチャット機能を実装できます。
前提条件: blocs/admin がインストール済み、openai-php/laravel 等の OpenAI 連携設定、Qdrant サーバーへの接続設定が完了していること。
クラス構成
| クラス | 名前空間 | 役割 |
|---|---|---|
Chat |
Blocs\AI\Chat |
OpenAI Chat API による質問応答・翻訳 |
VectorStore |
Blocs\AI\VectorStore |
Qdrant へのベクトル登録・類似検索 |
VectorStore
ドキュメントをベクトル化して Qdrant コレクションに保存し、類似検索で関連ナレッジを取得します。
主なメソッド
| メソッド | 説明 |
|---|---|
get($collectionName, $docIds) |
ID 指定でドキュメント取得 |
similar($collectionName, $dataForEmbedding, ...) |
ベクトル類似検索(RAG の中核) |
sample($collectionName, $limit, $filter) |
ランダムサンプル取得(類似検索ではない) |
upsert($collectionName, $docId, $payload, $embeddingSource) |
1件の登録・更新。bool を返す |
upsertMany($collectionName, $items) |
複数件のバッチ登録・更新。bool を返す |
count($collectionName) |
コレクション内の件数 |
getAllIds($collectionName, $filter) |
全ドキュメント ID 取得 |
delete($collectionName, $docIds) |
ドキュメント削除 |
登録例
// 成功時 true / 失敗時 false
VectorStore::upsert('my-collection', 'doc-1', ['content' => '本文']);
VectorStore::upsertMany('my-collection', [
['doc_id' => 'doc-1', 'payload' => ['content' => '...']],
// 埋め込み元を payload と別にする場合(任意)
['doc_id' => 'doc-2', 'payload' => ['title' => '...'], 'embedding_source' => '検索用テキスト'],
]);
embedding_source を省略した場合、埋め込みベクトルの生成元は payload 全体が使われます。
バッチ登録の注意
upsertMany() は config('qdrant.embedding_batch_size', 64) 件ずつ処理します。バッチ境界をまたいだ原子性はなく、先行バッチが成功した後に後続バッチが失敗すると、先行分は Qdrant に残ったまま false が返ります。
類似検索例
$results = VectorStore::similar('my-collection', '検索クエリ');
コレクション名を指定してナレッジベースを分離できます。
設定(config/qdrant.php)
アプリ側で config/qdrant.php を用意し、.env から読み込みます。
| キー | 説明 | 既定値 |
|---|---|---|
host |
Qdrant ホスト | http://localhost |
port |
Qdrant ポート | 6333 |
api_key |
Qdrant Cloud 用 API キー | なし |
embedding_model |
埋め込みモデル名 | — |
embedding_base_uri |
埋め込み API のベース URL | — |
embedding_api_key |
埋め込み API キー | — |
embedding_batch_size |
バッチ登録の件数 | 64 |
Chat
OpenAI Chat API で応答を生成します。用途に応じて VectorStore のメソッドを組み合わせます。
use Blocs\AI\Chat;
use Blocs\AI\VectorStore;
$chat = new Chat('my-collection', 'gpt-4o');
// ランダムサンプル1件をコンテキストに含めて応答(類似検索ではない)
$answer = $chat->question([
['role' => 'user', 'content' => 'ユーザーの質問'],
]);
// 類似検索でナレッジを取得してから回答する例
$knowledge = VectorStore::similar('my-collection', 'ユーザーの質問');
$answer = $chat->answer($developerPrompt, [], 'ユーザーの質問', $knowledge);
// 回答の翻訳
$translated = $chat->translate($question, $answer);
主なメソッド
| メソッド | 説明 |
|---|---|
question($messages) |
VectorStore::sample() でランダム1件の payload から content キーを取り出し、resources/prompt/question.md をプロンプトに含めて応答 |
answer($developer, $messages, $question, $knowledge) |
指定ナレッジ(配列)を JSON コンテキストに含めて応答 |
translate($question, $answer, $questionLang) |
回答を質問と同じ言語に翻訳 |
log($isLogging) |
API リクエストを storage/logs/chatOpenAI.log に記録 |
checkLocale() |
Accept-Language ヘッダーからロケールを推定 |
意味検索ベースの RAG が必要な場合は、question() ではなく VectorStore::similar() でナレッジを取得し、answer() に渡してください。
プロンプトテンプレートは resources/prompt/ 配下(question.md, translate.md, detectLanguage.md)に配置します。
利用上の注意
- OpenAI API キーと Qdrant の接続先は
.env等で設定してください Chat::question()を使う場合、登録時の payload にcontentキーを含めてください(ランダム取得した1件の本文として参照されます)- 本機能は管理画面の標準 CRUD とは独立した拡張機能です。利用しないプロジェクトでは無視して構いません