使用 LlamaIndex + 阿里云百炼实现知识库 作者:马育民 • 2025-08-17 23:28 • 阅读:10011 # 阿里云百炼准备工作 ### 获取 API 密钥 阿里云百炼 API 密钥:从 [阿里云控制台](https://dashscope.aliyun.com/) 获取。 ### 模型 [](https://www.malaoshi.top/upload/0/0/1GW1hU9RYIy5.png) 使用 [链接](https://bailian.console.aliyun.com/?spm=5176.29619931.J__Z58Z6CX7MY__Ll8p1ZOR.1.7f78521csb1HHk&tab=model#/model-market?capabilities=%5B%22TR%22%5D&z_type_=%7B%22capabilities%22%3A%22array%22%7D "链接") 中的向量模型 目前,最新的模型: - 处理文本推荐 `通用文本向量-v4` - 处理文本+图片,推荐 `通用多模态向量` # LlamaIndex 安装依赖 ```bash pip install llama-index pip install llama-index-llms-dashscope # 阿里云百炼适配 pip install llama-index-embeddings-dashscope pip install pypdf python-docx # 处理PDF文档、word文档 ``` # 下载 NLTK stopwords 停用词 默认使用 NLTK 分词,首次执行代码时,会自动从 github.com 下载 **停用词**,如果不能访问 github.com,执行代码会报错下载失败 ### 手动下载语料库 访问 `stopwords` 语料库的 GitHub 下载链接: https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/corpora/stopwords.zip ### 解压到指定目录 - 找到 `nltk_data` 的默认存储路径: Windows 系统通常为 `C:\Users\你的用户名\AppData\Roaming\nltk_data`(`AppData` 是隐藏文件夹,需开启“显示隐藏文件”)。 - 在该路径下创建 `corpora` 文件夹(若不存在),将下载的 `stopwords.zip` 解压到 `corpora` 中,最终目录结构为: `C:\Users\你的用户名\AppData\Roaming\nltk_data\corpora\stopwords\`(解压后内部应有 `english`、`chinese` 等子文件夹)。 ### 验证是否生效 运行以下代码,若不报错则配置成功: ```python import nltk from nltk.corpus import stopwords # 查看英文停用词(测试是否能加载) print(stopwords.words('english')[:5]) # 输出前5个英文停用词 ``` # 下载 NLTK punkt_tab 文本拆分 `punkt_tab` 是 LlamaIndex 文本拆分(尤其是句子级拆分)的核心依赖 首次执行代码时,会自动从 github.com 下载 `punkt_tab.zip`(用于文本分词的核心语料库),如果不能访问 github.com,执行代码会报错下载失败 ### 手动下载 `punkt_tab` 语料库 直接访问 `punkt_tab` 的 GitHub 下载链接: https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/tokenizers/punkt_tab.zip ### 解压到 `nltk_data` 指定目录 - **找到 `nltk_data` 路径**: Windows 系统默认路径为 `C:\Users\你的用户名\AppData\Roaming\nltk_data`(`AppData` 是隐藏文件夹,需开启“显示隐藏文件”)。 - **创建目录结构**: 在 `nltk_data` 下新建 `tokenizers` 文件夹(若不存在),将下载的 `punkt_tab.zip` 解压到 `tokenizers` 中,最终目录为: `C:\Users\你的用户名\AppData\Roaming\nltk_data\tokenizers\punkt_tab\` (解压后内部应有 `english.pickle`、`chinese.pickle` 等分词模型文件)。 ### 验证是否生效 运行以下代码,无报错则配置成功: ```python import nltk from nltk.tokenize import sent_tokenize # 依赖 punkt_tab 进行句子分割 # 测试句子分词 text = "这是第一个句子。这是第二个句子。" print(sent_tokenize(text)) # 正常输出:['这是第一个句子。', '这是第二个句子。'] ``` # 代码 ``` import os from llama_index.core import VectorStoreIndex,SimpleDirectoryReader,ServiceContext,PromptTemplate,Settings,StorageContext,load_index_from_storage from llama_index.llms.dashscope import DashScope # 阿里云百炼LLM适配 from llama_index.embeddings.dashscope import DashScopeEmbedding # 阿里云百炼Embedding适配 from llama_index.core.node_parser import SentenceSplitter import nltk # 创建一个新的路径列表,将新路径添加到列表中 print("nltk.data.path:",nltk.data.path) new_path = ['./nltk_data'] nltk.data.path += new_path print("nltk.data.path:",nltk.data.path) # -------------------------- # 配置阿里云百炼API密钥 # -------------------------- os.environ["DASHSCOPE_API_KEY"] = "sk-xxxx" # 替换为实际API密钥 # -------------------------- # 初始化模型(LLM和Embedding) # -------------------------- # 配置大语言模型(通义千问) llm = DashScope( model_name="qwen-plus", # 可选模型:qwen-plus/qwen-max/qwen-turbo等 temperature=0.1, # 控制回答随机性(0-1,越低越确定) api_key=os.getenv("DASHSCOPE_API_KEY"), # 使用环境变量中的 API Key ) # 配置Embedding模型(用于文本向量化) embed_model = DashScopeEmbedding( model_name="text-embedding-v4", # 使用阿里百炼 通用文本向量-v4 dimension=1536, # 模型输出维度(固定为1536) embed_batch_size=10 # 关键:设置批量处理大小为10(模型最大限制),否则请模型发请求会报400错误 ) # -------------------------- # 配置 SentenceSplitter,拆分token,防止文本多长,超过模型token限制 # -------------------------- node_parser = SentenceSplitter( chunk_size=1024, # 单个节点1024 token chunk_overlap=50, # 重叠50 token ) # -------------------------- # 配置全局参数 # -------------------------- Settings.llm = llm Settings.embed_model = embed_model Settings.num_output = 512 Settings.context_window = 3900 Settings.node_parser = node_parser # 应用SentenceSplitter # -------------------------- # 加载与处理文档,加载当前目录下 docs 文件夹下的文档 # -------------------------- def load_documents(doc_dir="docs"): """加载指定文件夹中的所有文档(支持PDF、TXT、DOCX等)""" # 自动识别并加载文件夹中的所有文档 loader = SimpleDirectoryReader( input_dir=doc_dir, recursive=True # 递归加载子文件夹文档 ) return loader.load_data() # -------------------------- # 构建或加载索引 # persist_dir:向量索引的保存路径 # -------------------------- def get_index(documents, persist_dir="./text_index"): """构建新索引或加载已保存的索引""" if not os.path.exists(persist_dir): # 首次运行:构建索引并保存到本地 index = VectorStoreIndex.from_documents( documents ) # 持久化索引(避免重复构建) index.storage_context.persist(persist_dir=persist_dir) print(f"索引构建完成,已保存至 {persist_dir}") else: # 后续运行:加载已有索引 storage_context = StorageContext.from_defaults(persist_dir=persist_dir) index = load_index_from_storage( storage_context ) print(f"已加载现有索引:{persist_dir}") return index # -------------------------- # 构建问答引擎并交互 # -------------------------- if __name__ == "__main__": # 加载文档(确保"docs"文件夹中存在你的知识库文档) documents = load_documents(doc_dir="文档") print(f"成功加载 {len(documents)} 个文档") # 获取索引 index = get_index(documents) # 创建查询引擎(配置检索参数) query_engine = index.as_query_engine( similarity_top_k=3 # 检索最相关的3个文档片段 ) # 交互式问答 print("\n===== 知识库问答系统 =====") while True: question = input("\n请输入问题(输入'q'退出):") if question.lower() == "q": break # 调用查询引擎获取回答 response = query_engine.query(question) print("\n回答:") print(response) # 可选:打印参考的文档来源 print("\n参考文档片段:") for i, node in enumerate(response.source_nodes, 1): print(f"\n片段{i}(相关性:{node.score:.2f}):") print(node.text[:200] + "...") # 显示前200字符 ``` ### 创建文档 在当前工程目录下创建 `文档` 目录,该目录下存放要学习的文档 ### 运行程序 执行程序后,生成 `text_index` 目录,该目录是存放向量的数据 原文出处:http://malaoshi.top/show_1GW1h7WWLOLx.html