| """ |
| ベクトルストア構築ユーティリティ |
| """ |
|
|
| import logging |
| import os |
| from typing import List, Optional |
|
|
| from dotenv import load_dotenv |
| from langchain_chroma import Chroma |
| from langchain_core.documents import Document |
| from langchain_openai import OpenAIEmbeddings |
|
|
| from .embedding_storage import save_embeddings |
| from .loader import load_chunks_from_json, display_document_info |
|
|
| logger = logging.getLogger(__name__) |
|
|
| |
| load_dotenv(dotenv_path=".env") |
|
|
|
|
| def build_vector_store( |
| docs_path: str = 'data/processed/chunks.json', |
| persist_dir: str = 'data/vector_store', |
| model_name: str = 'text-embedding-3-small', |
| save_embeddings_to_file: bool = True, |
| embeddings_dir: str = 'data/embeddings' |
| ) -> None: |
| """ |
| ドキュメントチャンクからベクトルストアを構築し、必要に応じて埋め込みも保存する |
| |
| Args: |
| docs_path: ドキュメントチャンクが格納されたJSONファイルのパス |
| persist_dir: ベクトルストアを保存するディレクトリ |
| model_name: 使用するOpenAI埋め込みモデル名 |
| save_embeddings_to_file: 埋め込みを別ファイルに保存するかどうか |
| embeddings_dir: 埋め込みを保存するディレクトリ |
| """ |
| logger.debug("OPENAI_API_KEY set: %s", bool(os.getenv("OPENAI_API_KEY"))) |
| logger.info("全てのインポートが成功しました") |
| |
| |
| docs_list = load_chunks_from_json(docs_path) |
| |
| |
| display_document_info(docs_list) |
| |
| |
| embeddings = OpenAIEmbeddings(model=model_name) |
| logger.info(f"埋め込みモデル初期化済み: {model_name}") |
| |
| |
| if docs_list: |
| |
| texts = [doc.page_content for doc in docs_list] |
| logger.info(f"{len(texts)}件のドキュメントに対して埋め込みを生成中...") |
| vectors = embeddings.embed_documents(texts) |
| |
| |
| if save_embeddings_to_file: |
| embeddings_file = save_embeddings( |
| documents=docs_list, |
| vectors=vectors, |
| model_name=model_name, |
| embeddings_dir=embeddings_dir |
| ) |
| logger.info(f"埋め込みを保存しました: {embeddings_file}") |
| |
| |
| |
| db = Chroma.from_documents(docs_list, embeddings, persist_directory=persist_dir) |
| logger.info(f"ベクトルストアを作成し保存しました: {persist_dir}") |
| logger.info(f"{len(docs_list)}件のドキュメントチャンクをインデックス化しました") |
| else: |
| logger.error("インデックス化するドキュメントがありません。chunks.jsonファイルを確認してください。") |
| raise ValueError("入力ファイルにドキュメントが見つかりません") |
|
|
|
|
| def search_vector_store( |
| query: str, |
| persist_dir: str = 'data/vector_store', |
| k: int = 5, |
| model_name: str = 'text-embedding-3-small' |
| ) -> List[Document]: |
| """ |
| ベクトルストアから関連ドキュメントを検索する |
| |
| Args: |
| query: 検索クエリ |
| persist_dir: ベクトルストアが保存されているディレクトリ |
| k: 取得するドキュメント数 |
| model_name: 使用するOpenAI埋め込みモデル名 |
| |
| Returns: |
| 関連ドキュメントのリスト |
| """ |
| |
| embeddings = OpenAIEmbeddings(model=model_name) |
| |
| |
| db = Chroma(persist_directory=persist_dir, embedding_function=embeddings) |
| |
| |
| retriever = db.as_retriever( |
| search_type='similarity', |
| search_kwargs={'k': k} |
| ) |
| |
| |
| docs = retriever.invoke(query) |
| |
| return docs |
|
|