feat: 🔗 Tidy

This commit is contained in:
2026-01-28 12:36:47 +00:00
parent d5f8d72e46
commit 8ca23187e3
4 changed files with 41 additions and 15 deletions
+3 -1
View File
@@ -5,8 +5,9 @@ api:
# --- Model Settings --- # --- Model Settings ---
models: models:
inference: "lm_studio/qwen/qwen3-8b" enrich: "lm_studio/qwen/qwen3-8b"
embedding: "text-embedding-qwen3-embedding-8b" embedding: "text-embedding-qwen3-embedding-8b"
retrieval: "lm_studio/qwen/qwen3-next-80b"
# --- Ingestion Settings --- # --- Ingestion Settings ---
ingestion: ingestion:
@@ -15,6 +16,7 @@ ingestion:
max_workers: 8 max_workers: 8
chunk_size: 800 chunk_size: 800
chunk_overlap: 100 chunk_overlap: 100
embedding_batch_size: 32
# --- Retrieval Settings --- # --- Retrieval Settings ---
retrieval: retrieval:
+13 -3
View File
@@ -3,6 +3,16 @@ from langchain_community.vectorstores import FAISS
from embedding import LocalLMEmbeddings from embedding import LocalLMEmbeddings
from pathlib import Path from pathlib import Path
from config_loader import load_config
CFG = load_config()
DATABASE_PATH = CFG["ingestion"]["db_path"]
EMBEDDING_MODEL = CFG["models"]["embedding"]
API_BASE = CFG["api"]["base_url"]
# --- DSPy Signature --- # --- DSPy Signature ---
class DnDContextQA(dspy.Signature): class DnDContextQA(dspy.Signature):
"""Answer DnD campaign questions using provided snippets and full file context. """Answer DnD campaign questions using provided snippets and full file context.
@@ -13,12 +23,12 @@ class DnDContextQA(dspy.Signature):
# --- DSPy Module --- # --- DSPy Module ---
class DnDRAG(dspy.Module): class DnDRAG(dspy.Module):
def __init__(self, db_path="./local_faiss_db", k=3): def __init__(self, db_path=DATABASE_PATH, k=3):
super().__init__() super().__init__()
# 1. Setup Embeddings & Load FAISS # 1. Setup Embeddings & Load FAISS
self.embeddings = LocalLMEmbeddings( self.embeddings = LocalLMEmbeddings(
model="text-embedding-qwen3-embedding-8b", model=EMBEDDING_MODEL,
base_url="http://192.168.0.49:1234" base_url=API_BASE
) )
self.vectorstore = FAISS.load_local( self.vectorstore = FAISS.load_local(
db_path, self.embeddings, allow_dangerous_deserialization=True db_path, self.embeddings, allow_dangerous_deserialization=True
+16 -10
View File
@@ -15,6 +15,15 @@ from config_loader import load_config
CFG = load_config() CFG = load_config()
DATA_DIR = CFG["ingestion"]["data_dir"] DATA_DIR = CFG["ingestion"]["data_dir"]
DATABASE_PATH = CFG["ingestion"]["db_path"]
MODEL_BASE = CFG["models"]["enrich"]
EMBEDDING_MODEL = CFG["models"]["embedding"]
API_BASE = CFG["api"]["base_url"]
API_VERSION = CFG["api"]["api_version"]
MAX_WORKERS=CFG["ingestion"]["max_workers"]
CHUNK_SIZE=CFG["ingestion"]["chunk_size"],
CHUNK_OVERLAP=CFG["ingestion"]["chunk_overlap"]
EMBEDDING_BATCH_SIZE=CFG["ingestion"]["embedding_batch_size"]
def load_documents(): def load_documents():
docs = [] docs = []
@@ -44,16 +53,13 @@ def load_documents():
def chunk_documents(docs): def chunk_documents(docs):
# LangChain preserves metadata during splitting automatically # LangChain preserves metadata during splitting automatically
text_splitter = RecursiveCharacterTextSplitter( text_splitter = RecursiveCharacterTextSplitter(
chunk_size=CFG["ingestion"]["chunk_size"], chunk_size=CHUNK_SIZE,
chunk_overlap=CFG["ingestion"]["chunk_overlap"], chunk_overlap=CHUNK_OVERLAP,
separators=["\n\n", "\n", ". ", " ", ""] separators=["\n\n", "\n", ". ", " ", ""]
) )
return text_splitter.split_documents(docs) return text_splitter.split_documents(docs)
def enrich_chunks(chunks: list) -> list: def enrich_chunks(chunks: list) -> list:
MODEL_BASE = CFG["models"]["inference"]
API_BASE = CFG["api"]["base_url"]
API_VERSION = CFG["api"]["api_version"]
def process_single_chunk(indexed_chunk): def process_single_chunk(indexed_chunk):
idx, chunk = indexed_chunk idx, chunk = indexed_chunk
@@ -75,7 +81,7 @@ def enrich_chunks(chunks: list) -> list:
enriched_results = [] enriched_results = []
with ThreadPoolExecutor(max_workers=CFG["ingestion"]["max_workers"]) as executor: with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
# Wrap chunks in enumerate to keep track of order # Wrap chunks in enumerate to keep track of order
futures = [executor.submit(process_single_chunk, (i, c)) for i, c in enumerate(chunks)] futures = [executor.submit(process_single_chunk, (i, c)) for i, c in enumerate(chunks)]
@@ -86,11 +92,11 @@ def enrich_chunks(chunks: list) -> list:
enriched_results.sort(key=lambda x: x[0]) enriched_results.sort(key=lambda x: x[0])
return [item[1] for item in enriched_results] return [item[1] for item in enriched_results]
def store_chunks_locally(chunks, db_path="./local_faiss_db"): def store_chunks_locally(chunks, db_path=DATABASE_PATH):
embeddings_model = LocalLMEmbeddings( embeddings_model = LocalLMEmbeddings(
model="text-embedding-qwen3-embedding-8b", model=EMBEDDING_MODEL,
base_url="http://192.168.0.49:1234", base_url=API_BASE,
batch_size=32, batch_size=EMBEDDING_BATCH_SIZE,
) )
print(f"Index creation started for {len(chunks)} chunks...") print(f"Index creation started for {len(chunks)} chunks...")
+9 -1
View File
@@ -1,11 +1,19 @@
import sys import sys
import dspy import dspy
from experts.dnd_agent import DnDRAG from experts.dnd_agent import DnDRAG
from config_loader import load_config
CFG = load_config()
RETRIEVE_MODEL = CFG["models"]["retrieval"]
API_BASE = CFG["api"]["base_url"]
API_VERSION = CFG["api"]["api_version"]
def main(): def main():
# 1. Setup the LLM # 1. Setup the LLM
print("🚀 Initializing Qwen-8B via LM Studio...") print("🚀 Initializing Qwen-8B via LM Studio...")
lm = dspy.LM("lm_studio/qwen/qwen3-8b", api_base="http://192.168.0.49:1234/v1/") lm = dspy.LM(RETRIEVE_MODEL, api_base=API_BASE+API_VERSION)
dspy.configure(lm=lm) dspy.configure(lm=lm)
# 2. Load the RAG System (only happens once!) # 2. Load the RAG System (only happens once!)