|
|
""" |
|
|
ベクトルストア構築ユーティリティ |
|
|
""" |
|
|
|
|
|
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 |
|
|
|