ClareCourseWare / Notiondb.py
claudqunwang's picture
Add Clare product UI: run_web.sh, README, exclude hf_space from push
c8c6034
import os
from pathlib import Path
from dotenv import load_dotenv
# LlamaIndex 核心组件
from llama_index.core import (
VectorStoreIndex,
SimpleDirectoryReader,
StorageContext,
load_index_from_storage,
Settings,
)
from llama_index.embeddings.openai import OpenAIEmbedding
# ============================
# 环境变量 & 路径配置
# ============================
# 加载 .env(和 Clare 项目保持一致,直接复用 OPENAI_API_KEY)
load_dotenv()
PROJECT_ROOT = Path(__file__).resolve().parent
# 1. GENAI 课程目录(你要向量化的本地课程代码 / 笔记)
# 这里用绝对路径更稳,不怕你从哪里运行脚本
EXPORT_DIR = PROJECT_ROOT / "GENAI COURSES"
# 2. 向量数据库持久化路径
PERSIST_DIR = PROJECT_ROOT / "genai_courses_index"
# 3. 显式指定 Embedding 模型(和 Clare 一致:text-embedding-3-small)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
def get_index(force_rebuild=False):
"""
获取索引:优先读取本地缓存,如果不存在或强制刷新,则重新构建
"""
# 情况 A: 数据库已存在,直接加载 (极快,不花钱)
if PERSIST_DIR.exists() and not force_rebuild:
print(f"📂 发现本地数据库 ({PERSIST_DIR}),正在加载...")
try:
storage_context = StorageContext.from_defaults(persist_dir=str(PERSIST_DIR))
index = load_index_from_storage(storage_context)
print("✅ 加载成功!")
return index
except Exception as e:
print(f"⚠️ 本地数据库加载失败: {e},准备重新构建...")
# 情况 B: 数据库不存在,或者要求强制更新 -> 读取本地文件构建
print(f"🚀 开始扫描本地文件并构建向量数据库:{EXPORT_DIR}")
if not EXPORT_DIR.exists():
raise FileNotFoundError(f"GENAI COURSES 目录不存在:{EXPORT_DIR}")
# 1. 读取文件
# recursive=True 会读取子文件夹,确保附件和嵌套页面都被读取
# required_exts 可以指定只读 .md,如果不加这行则会读取所有支持的文件(pdf, txt, etc.)
reader = SimpleDirectoryReader(
input_dir=str(EXPORT_DIR),
recursive=True,
# 可以根据需要调整:这里把常见的课程文件类型都包含进来
required_exts=[".md", ".pdf", ".txt", ".py", ".ipynb"],
)
documents = reader.load_data()
print(f"📄 成功读取了 {len(documents)} 个文件片段")
# 2. 构建索引 (这一步会调用 OpenAI API 进行 Embedding)
print("🧠 正在生成向量索引 (Embedding)...")
index = VectorStoreIndex.from_documents(documents)
# 3. 保存到硬盘
print(f"💾 正在保存数据库到 {PERSIST_DIR} ...")
index.storage_context.persist(persist_dir=PERSIST_DIR)
return index
if __name__ == "__main__":
# --- 主程序 ---
# 首次运行或通过参数控制 force_rebuild=True 来更新
index = get_index(force_rebuild=False)
# 创建查询引擎
query_engine = index.as_query_engine()
print("\n💬 本地知识库助手已就绪 (输入 'exit' 退出, 'update' 重建):")
while True:
question = input("\n请输入问题: ")
if question.lower() == 'exit':
break
elif question.lower() == 'update':
index = get_index(force_rebuild=True)
query_engine = index.as_query_engine()
print("✅ 数据库已更新!")
continue
response = query_engine.query(question)
print(f"\n🤖 回答:\n{response}")