從零構(gòu)建企業(yè)級(jí)RAG與Agent系統(tǒng):LangChain實(shí)戰(zhàn)指南
如果你正在學(xué)習(xí)大模型應(yīng)用開發(fā)可能會(huì)遇到這樣的困境看了很多關(guān)于LangChain、RAG、Agent的教程但依然不知道如何把這些技術(shù)串聯(lián)起來(lái)構(gòu)建一個(gè)真正能解決實(shí)際問(wèn)題的企業(yè)級(jí)應(yīng)用。你可能會(huì)困惑為什么別人的RAG系統(tǒng)能精準(zhǔn)回答業(yè)務(wù)問(wèn)題而自己的卻總是“答非所問(wèn)”為什么Agent聽(tīng)起來(lái)很智能但一上手就卡在工具調(diào)用和流程控制上問(wèn)題的核心在于大多數(shù)教程只教你“點(diǎn)”上的知識(shí)——如何調(diào)用一個(gè)API如何寫一個(gè)Prompt——卻很少告訴你如何將這些“點(diǎn)”連成“線”再編織成一張能支撐復(fù)雜業(yè)務(wù)的“網(wǎng)”。一個(gè)能投入生產(chǎn)環(huán)境的RAG系統(tǒng)遠(yuǎn)不止是“向量檢索大模型”那么簡(jiǎn)單一個(gè)真正有用的Agent也絕非幾個(gè)工具調(diào)用的簡(jiǎn)單堆砌。這篇文章將徹底改變你的學(xué)習(xí)路徑。我們不談空洞的概念直接從企業(yè)級(jí)項(xiàng)目的實(shí)戰(zhàn)需求出發(fā)手把手帶你構(gòu)建兩個(gè)核心項(xiàng)目一個(gè)高可用、可解釋、易維護(hù)的RAG知識(shí)庫(kù)系統(tǒng)以及一個(gè)能自主規(guī)劃、使用工具、完成復(fù)雜任務(wù)的智能體Agent。你將學(xué)到的不只是代碼怎么寫更是如何設(shè)計(jì)架構(gòu)、處理異常、評(píng)估效果以及如何將學(xué)到的技能轉(zhuǎn)化為求職時(shí)的核心競(jìng)爭(zhēng)力。讀完本文你將獲得一套完整的、可復(fù)現(xiàn)的“技術(shù)地圖”從零到一吃透LangChain生態(tài)具備獨(dú)立開發(fā)企業(yè)級(jí)AI應(yīng)用的能力。1. 為什么你需要一套“系統(tǒng)化”的LangChain實(shí)戰(zhàn)教程在開始敲代碼之前我們必須先統(tǒng)一認(rèn)知學(xué)習(xí)LangChain等大模型應(yīng)用框架目標(biāo)不是記住幾個(gè)類名和函數(shù)而是掌握構(gòu)建可靠AI應(yīng)用的工程化能力。市面上很多“入門教程”存在三個(gè)典型誤區(qū)過(guò)于理想化示例代碼運(yùn)行在完美的模擬環(huán)境中忽略了網(wǎng)絡(luò)延遲、模型限流、數(shù)據(jù)臟亂等現(xiàn)實(shí)問(wèn)題。碎片化嚴(yán)重只講解VectorStore或AgentExecutor等孤立組件缺乏項(xiàng)目級(jí)的架構(gòu)設(shè)計(jì)和組件聯(lián)調(diào)。脫離業(yè)務(wù)場(chǎng)景用“總結(jié)美國(guó)總統(tǒng)生平”作為例子但企業(yè)真正需要的是“根據(jù)最新產(chǎn)品手冊(cè)回答客戶技術(shù)問(wèn)題”或“自動(dòng)分析周報(bào)數(shù)據(jù)并生成洞察”。本教程的定位是**“學(xué)完即可就業(yè)”**這意味著我們關(guān)注的重點(diǎn)將是企業(yè)真實(shí)場(chǎng)景下的技術(shù)選型、架構(gòu)設(shè)計(jì)、故障排查和性能優(yōu)化。你會(huì)經(jīng)歷從環(huán)境搭建、原型開發(fā)、迭代優(yōu)化到部署上線的完整閉環(huán)。我們選擇LangChain不僅因?yàn)樗悄壳白盍餍械拇竽P蛻?yīng)用框架更因?yàn)樗峁┝艘粋€(gè)相對(duì)標(biāo)準(zhǔn)化的抽象層讓你能聚焦于業(yè)務(wù)邏輯而非底層API的差異。2. 核心概念厘清RAG、Agent與LangChain到底是什么關(guān)系在深入實(shí)戰(zhàn)前準(zhǔn)確理解這幾個(gè)核心概念及其關(guān)系至關(guān)重要。它們不是并列關(guān)系而是層層遞進(jìn)的構(gòu)建模塊。2.1 RAG讓大模型“學(xué)會(huì)”你的私有知識(shí)通俗解釋想象一下你是一位新員工面對(duì)公司海量的歷史文檔、產(chǎn)品手冊(cè)和會(huì)議紀(jì)要一時(shí)無(wú)從下手。這時(shí)一位資深同事RAG系統(tǒng)出現(xiàn)了。你問(wèn)他任何問(wèn)題他都會(huì)先快速翻閱相關(guān)的文檔檢索然后結(jié)合這些文檔和他的通用知識(shí)增強(qiáng)最后組織成你能理解的答案告訴你生成。技術(shù)定義RAGRetrieval-Augmented Generation檢索增強(qiáng)生成是一種架構(gòu)模式。它通過(guò)外部知識(shí)源如向量數(shù)據(jù)庫(kù)檢索相關(guān)信息并將其作為上下文與大模型的提示詞結(jié)合從而生成更準(zhǔn)確、更相關(guān)且可追溯的答案。關(guān)鍵價(jià)值突破模型記憶限制大模型訓(xùn)練數(shù)據(jù)有截止日期且無(wú)法記憶所有私有知識(shí)。RAG動(dòng)態(tài)注入相關(guān)知識(shí)解決了“模型不知道”的問(wèn)題。答案可溯源生成的答案可以引用來(lái)源文檔提高了可信度和可解釋性這在企業(yè)合規(guī)場(chǎng)景下是剛需。成本與效果平衡相比微調(diào)大模型RAG實(shí)現(xiàn)成本更低迭代更快能快速適配知識(shí)更新。2.2 Agent讓大模型從“答題者”變?yōu)椤皥?zhí)行者”通俗解釋如果RAG是那位博學(xué)的同事那么Agent就是一位擁有多種技能工具的私人助理。你告訴他“幫我查一下明天北京的天氣如果下雨就提醒我?guī)悴㈩A(yù)約一輛明早9點(diǎn)去公司的車”。他會(huì)自主規(guī)劃步驟先調(diào)用天氣查詢工具根據(jù)結(jié)果判斷再調(diào)用日歷工具設(shè)置提醒最后調(diào)用打車軟件API完成預(yù)約。技術(shù)定義Agent智能體是一個(gè)能感知環(huán)境、進(jìn)行決策并執(zhí)行動(dòng)作以實(shí)現(xiàn)目標(biāo)的系統(tǒng)。在大模型語(yǔ)境下它通常指一個(gè)以大模型為“大腦”能夠自主規(guī)劃、調(diào)用工具如搜索、計(jì)算、API、并持續(xù)迭代直至完成復(fù)雜任務(wù)的程序。關(guān)鍵價(jià)值處理復(fù)雜任務(wù)將復(fù)雜目標(biāo)拆解為可執(zhí)行的子任務(wù)序列。連接數(shù)字世界通過(guò)調(diào)用外部工具API、數(shù)據(jù)庫(kù)、函數(shù)讓大模型的能力從文本生成擴(kuò)展到現(xiàn)實(shí)操作。具備自主性根據(jù)執(zhí)行結(jié)果反饋動(dòng)態(tài)調(diào)整計(jì)劃具備更強(qiáng)的魯棒性。2.3 LangChain構(gòu)建RAG和Agent的“腳手架”與“工具箱”通俗解釋LangChain就像樂(lè)高積木的通用連接器和一套豐富的積木套裝。你想搭建RAG城堡或Agent機(jī)器人不需要從零燒制每一塊磚處理各種模型的API差異、設(shè)計(jì)檢索流程、管理對(duì)話狀態(tài)。LangChain提供了標(biāo)準(zhǔn)化、可插拔的組件如文檔加載器、文本分割器、向量存儲(chǔ)、工具、記憶模塊等讓你能像搭積木一樣快速組合出應(yīng)用。技術(shù)定義LangChain是一個(gè)用于開發(fā)由大語(yǔ)言模型驅(qū)動(dòng)的應(yīng)用程序的框架。它通過(guò)提供一套抽象和工具鏈簡(jiǎn)化了鏈Chains、代理Agents、檢索Retrieval等復(fù)雜模式的實(shí)現(xiàn)。核心關(guān)系圖LangChain (框架) ├── 用于構(gòu)建 ── RAG系統(tǒng) (一種特定應(yīng)用架構(gòu)) └── 用于構(gòu)建 ── Agent系統(tǒng) (一種特定應(yīng)用架構(gòu))簡(jiǎn)單說(shuō)LangChain是你用來(lái)高效建造RAG和Agent這兩座“房子”的施工隊(duì)和建材庫(kù)。3. 環(huán)境準(zhǔn)備打造可復(fù)現(xiàn)的本地開發(fā)環(huán)境企業(yè)級(jí)項(xiàng)目的第一步是建立一個(gè)穩(wěn)定、一致的環(huán)境。我們選擇Conda進(jìn)行Python環(huán)境管理并使用Ollama在本地運(yùn)行開源大模型避免對(duì)網(wǎng)絡(luò)和付費(fèi)API的強(qiáng)依賴。3.1 基礎(chǔ)環(huán)境搭建安裝Miniconda (如未安裝): 前往 Miniconda官網(wǎng) 下載并安裝對(duì)應(yīng)你操作系統(tǒng)的版本。創(chuàng)建并激活專屬的Conda環(huán)境# 創(chuàng)建一個(gè)名為langchain-lab的Python 3.10環(huán)境 conda create -n langchain-lab python3.10 -y # 激活環(huán)境 conda activate langchain-lab3.2 核心工具安裝安裝LangChain及相關(guān)核心庫(kù)pip install langchain langchain-community langchain-core # 安裝文本嵌入模型庫(kù)這里以HuggingFace為例 pip install sentence-transformers # 安裝向量數(shù)據(jù)庫(kù)客戶端這里以Chroma為例輕量且易用 pip install chromadb # 安裝用于網(wǎng)頁(yè)內(nèi)容提取的庫(kù) pip install beautifulsoup4 html2text安裝并啟動(dòng)Ollama Ollama允許你在本地輕松運(yùn)行Llama 3、Qwen等開源模型。Mac/Linux: 在終端執(zhí)行curl -fsSL https://ollama.ai/install.sh | shWindows: 從 Ollama官網(wǎng) 下載安裝包。 安裝后拉取一個(gè)中等尺寸的模型如Llama 3 8Bollama pull llama3:8b啟動(dòng)Ollama服務(wù)通常安裝后自動(dòng)運(yùn)行它會(huì)在http://localhost:11434提供API。3.3 驗(yàn)證環(huán)境創(chuàng)建一個(gè)簡(jiǎn)單的Python腳本test_env.py來(lái)驗(yàn)證所有組件是否正常工作# test_env.py import sys print(fPython版本: {sys.version}) try: import langchain print(fLangChain版本: {langchain.__version__}) except ImportError as e: print(fLangChain導(dǎo)入失敗: {e}) try: from sentence_transformers import SentenceTransformer model SentenceTransformer(all-MiniLM-L6-v2) # 一個(gè)輕量級(jí)嵌入模型 embeddings model.encode(Hello, world!) print(f嵌入模型測(cè)試成功向量維度: {embeddings.shape}) except Exception as e: print(f嵌入模型測(cè)試失敗: {e}) # 測(cè)試Ollama連接需要確保ollama服務(wù)正在運(yùn)行 import requests try: response requests.post(http://localhost:11434/api/generate, json{model: llama3:8b, prompt: Hello, stream: False}) if response.status_code 200: print(Ollama連接測(cè)試成功。) else: print(fOllama連接異常狀態(tài)碼: {response.status_code}) except requests.exceptions.ConnectionError: print(無(wú)法連接到Ollama服務(wù)請(qǐng)確保已安裝并運(yùn)行 ollama serve。)運(yùn)行python test_env.py檢查所有輸出是否正常。4. 項(xiàng)目一構(gòu)建企業(yè)級(jí)RAG知識(shí)庫(kù)系統(tǒng)我們將構(gòu)建一個(gè)針對(duì)“產(chǎn)品技術(shù)文檔”的智能問(wèn)答系統(tǒng)。目標(biāo)是用戶可以用自然語(yǔ)言提問(wèn)系統(tǒng)能快速?gòu)拇罅縋DF/Word文檔中找出相關(guān)信息并生成準(zhǔn)確、流暢的答案同時(shí)附上引用來(lái)源。4.1 架構(gòu)設(shè)計(jì)一個(gè)健壯的RAG系統(tǒng)包含以下核心流水線原始文檔 - 加載與解析 - 文本分割 - 向量化嵌入 - 存入向量數(shù)據(jù)庫(kù) 用戶問(wèn)題 - 向量化嵌入 - 向量檢索 - 上下文構(gòu)建 - 大模型生成 - 答案與溯源4.2 分步實(shí)現(xiàn)步驟1文檔加載與處理我們創(chuàng)建一個(gè)document_processor.py文件。# document_processor.py import os from langchain_community.document_loaders import PyPDFLoader, UnstructuredWordDocumentLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.embeddings import HuggingFaceEmbeddings from langchain_community.vectorstores import Chroma class DocumentProcessor: def __init__(self, persist_directory./chroma_db): # 初始化嵌入模型 self.embeddings HuggingFaceEmbeddings( model_nameall-MiniLM-L6-v2, # 輕量且效果不錯(cuò)的句子嵌入模型 model_kwargs{device: cpu}, # 使用CPU有GPU可改為cuda encode_kwargs{normalize_embeddings: True} ) self.persist_directory persist_directory self.text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每個(gè)文本塊的大小 chunk_overlap50, # 塊之間的重疊避免上下文斷裂 separators[\n\n, \n, 。, , , , , , ] # 中文友好分隔符 ) def load_and_split_documents(self, doc_paths): 加載并分割文檔 all_docs [] for path in doc_paths: if path.endswith(.pdf): loader PyPDFLoader(path) elif path.endswith((.doc, .docx)): loader UnstructuredWordDocumentLoader(path) else: print(f暫不支持的文件格式: {path}) continue docs loader.load() print(f已加載文檔: {path}, 頁(yè)數(shù)/段落數(shù): {len(docs)}) all_docs.extend(docs) # 分割文本 split_docs self.text_splitter.split_documents(all_docs) print(f文檔分割完成共得到 {len(split_docs)} 個(gè)文本塊。) return split_docs def create_vector_store(self, documents, collection_nameproduct_docs): 創(chuàng)建并持久化向量存儲(chǔ) vectordb Chroma.from_documents( documentsdocuments, embeddingself.embeddings, persist_directoryself.persist_directory, collection_namecollection_name ) vectordb.persist() # 持久化到磁盤 print(f向量數(shù)據(jù)庫(kù)已創(chuàng)建并保存至: {self.persist_directory}) return vectordb # 使用示例 if __name__ __main__: processor DocumentProcessor() # 假設(shè)你的文檔放在 ./docs 目錄下 doc_paths [./docs/product_manual.pdf, ./docs/api_spec.docx] split_docs processor.load_and_split_documents(doc_paths) vectordb processor.create_vector_store(split_docs)步驟2構(gòu)建檢索與生成鏈創(chuàng)建rag_chain.py文件。# rag_chain.py from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate from langchain_community.llms import Ollama from langchain_community.embeddings import HuggingFaceEmbeddings from langchain_community.vectorstores import Chroma class RAGQASystem: def __init__(self, persist_directory./chroma_db): # 1. 加載嵌入模型需與創(chuàng)建時(shí)一致 self.embeddings HuggingFaceEmbeddings( model_nameall-MiniLM-L6-v2, model_kwargs{device: cpu}, encode_kwargs{normalize_embeddings: True} ) # 2. 加載已持久化的向量數(shù)據(jù)庫(kù) self.vectordb Chroma( persist_directorypersist_directory, embedding_functionself.embeddings ) # 3. 初始化本地大模型通過(guò)Ollama self.llm Ollama(modelllama3:8b, base_urlhttp://localhost:11434) # 4. 構(gòu)建Prompt模板指導(dǎo)模型如何利用上下文 self.qa_prompt PromptTemplate( input_variables[context, question], template請(qǐng)根據(jù)以下上下文信息回答問(wèn)題。如果上下文沒(méi)有提供足夠信息請(qǐng)直接回答“根據(jù)已知信息無(wú)法回答此問(wèn)題”。 上下文 {context} 問(wèn)題{question} 請(qǐng)給出專業(yè)、準(zhǔn)確的答案 ) # 5. 創(chuàng)建檢索問(wèn)答鏈 self.qa_chain RetrievalQA.from_chain_type( llmself.llm, chain_typestuff, # 最簡(jiǎn)單的方式將所有檢索到的文檔合并到一個(gè)Prompt中 retrieverself.vectordb.as_retriever( search_typesimilarity, # 相似度搜索 search_kwargs{k: 4} # 返回最相關(guān)的4個(gè)文檔塊 ), chain_type_kwargs{prompt: self.qa_prompt}, return_source_documentsTrue # 關(guān)鍵返回源文檔用于溯源 ) def ask(self, question): 提問(wèn)并獲取答案 result self.qa_chain.invoke({query: question}) answer result[result] source_docs result[source_documents] # 處理并展示結(jié)果 print(f\n問(wèn)題{question}) print(f答案{answer}) print(\n--- 答案來(lái)源 ---) for i, doc in enumerate(source_docs[:2]): # 展示前2個(gè)主要來(lái)源 print(f[來(lái)源{i1}] {doc.metadata.get(source, 未知)} (頁(yè)碼/段落: {doc.metadata.get(page, N/A)})) print(f 相關(guān)片段{doc.page_content[:200]}...\n) return answer, source_docs # 使用示例 if __name__ __main__: qa_system RAGQASystem() while True: user_question input(\n請(qǐng)輸入您的問(wèn)題輸入quit退出) if user_question.lower() quit: break qa_system.ask(user_question)4.3 運(yùn)行與效果驗(yàn)證準(zhǔn)備文檔在項(xiàng)目根目錄創(chuàng)建docs文件夾放入你的PDF或Word格式的產(chǎn)品文檔。構(gòu)建知識(shí)庫(kù)運(yùn)行python document_processor.py程序會(huì)加載、分割文檔并創(chuàng)建向量數(shù)據(jù)庫(kù)。啟動(dòng)問(wèn)答系統(tǒng)運(yùn)行python rag_chain.py在命令行中輸入問(wèn)題例如“我們產(chǎn)品的主要優(yōu)勢(shì)是什么”或“如何配置XXX功能”。系統(tǒng)會(huì)返回答案并列出引用的文檔片段和來(lái)源。預(yù)期成功現(xiàn)象程序正常啟動(dòng)無(wú)報(bào)錯(cuò)。輸入問(wèn)題后能在幾秒內(nèi)返回連貫的答案。答案內(nèi)容與提供的文檔相關(guān)。能正確顯示答案來(lái)源于哪個(gè)文檔的哪一頁(yè)或哪個(gè)段落。5. 項(xiàng)目二開發(fā)能規(guī)劃與使用工具的智能體Agent現(xiàn)在我們升級(jí)難度構(gòu)建一個(gè)能自主使用工具的智能體。場(chǎng)景一個(gè)“數(shù)據(jù)分析助手”Agent它能根據(jù)用戶的自然語(yǔ)言指令自動(dòng)決定是否需要查詢數(shù)據(jù)庫(kù)、進(jìn)行數(shù)學(xué)計(jì)算并生成最終報(bào)告。5.1 設(shè)計(jì)思路與工具定義我們將為Agent裝備三個(gè)工具查詢產(chǎn)品數(shù)據(jù)庫(kù)模擬一個(gè)根據(jù)產(chǎn)品ID查詢庫(kù)存和價(jià)格的函數(shù)。計(jì)算折扣價(jià)格根據(jù)原價(jià)和折扣率計(jì)算折后價(jià)。獲取當(dāng)前時(shí)間一個(gè)簡(jiǎn)單的工具用于在回答中增加時(shí)間上下文。5.2 分步實(shí)現(xiàn)創(chuàng)建smart_agent.py文件。# smart_agent.py from langchain.agents import Tool, AgentExecutor, create_react_agent from langchain.prompts import PromptTemplate from langchain_community.llms import Ollama from langchain import hub # 用于拉取預(yù)定義的Agent提示詞 import datetime import math # --- 第1步定義工具 --- def query_product_db(product_id: str) - str: 根據(jù)產(chǎn)品ID查詢產(chǎn)品信息。模擬數(shù)據(jù)庫(kù)查詢。 # 這里模擬一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù) product_db { P1001: {name: 無(wú)線藍(lán)牙耳機(jī), price: 299.0, stock: 150}, P1002: {name: 智能手表, price: 899.0, stock: 80}, P1003: {name: Type-C充電線, price: 39.0, stock: 500}, } product product_db.get(product_id.upper()) if product: return f產(chǎn)品信息名稱-{product[name]}, 單價(jià)-{product[price]}元, 庫(kù)存-{product[stock]}件。 else: return f未找到產(chǎn)品ID為 {product_id} 的信息。 def calculate_discount_price(original_price: float, discount_rate: float) - str: 計(jì)算折扣后的價(jià)格。discount_rate是小數(shù)例如0.2代表8折。 if not 0 discount_rate 1: return 折扣率必須在0到1之間。 final_price original_price * (1 - discount_rate) return f折后價(jià)格為{final_price:.2f}元。 def get_current_time(placeholder: str ) - str: 獲取當(dāng)前日期和時(shí)間。參數(shù)placeholder僅為滿足工具調(diào)用格式無(wú)實(shí)際用途。 now datetime.datetime.now() return f當(dāng)前時(shí)間是{now.strftime(%Y年%m月%d日 %H:%M:%S)}。 # 將函數(shù)封裝成LangChain Tool對(duì)象 tools [ Tool( nameProductDatabaseQuery, funcquery_product_db, description根據(jù)產(chǎn)品ID例如P1001查詢產(chǎn)品的名稱、價(jià)格和庫(kù)存。輸入應(yīng)為產(chǎn)品ID字符串。 ), Tool( nameDiscountCalculator, funccalculate_discount_price, description計(jì)算折扣價(jià)格。輸入兩個(gè)數(shù)字用逗號(hào)分隔原價(jià)和折扣率如0.1代表9折。示例輸入299,0.1 ), Tool( nameCurrentTime, funcget_current_time, description獲取當(dāng)前的日期和時(shí)間。當(dāng)回答需要時(shí)間上下文時(shí)使用。輸入可以是任何字符串通常為空。 ) ] # --- 第2步初始化大模型和Agent --- llm Ollama(modelllama3:8b, base_urlhttp://localhost:11434, temperature0) # 使用LangChain Hub上一個(gè)經(jīng)過(guò)優(yōu)化的ReAct提示詞模板 prompt hub.pull(hwchase17/react-chat) # 你也可以自定義提示詞但使用社區(qū)驗(yàn)證過(guò)的模板更穩(wěn)妥。 # 創(chuàng)建ReAct Agent agent create_react_agent(llm, tools, prompt) # 創(chuàng)建執(zhí)行器控制Agent的思考步驟和錯(cuò)誤處理 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 設(shè)置為True可以看到Agent的思考過(guò)程調(diào)試時(shí)非常有用 handle_parsing_errorsTrue, # 處理解析錯(cuò)誤 max_iterations5, # 限制最大迭代次數(shù)防止死循環(huán) early_stopping_methodgenerate # 提前停止方法 ) # --- 第3步運(yùn)行Agent --- def run_agent_loop(): print(數(shù)據(jù)分析助手Agent已啟動(dòng)。你可以詢問(wèn)產(chǎn)品信息、計(jì)算折扣或詢問(wèn)時(shí)間。) print(示例問(wèn)題P1002的庫(kù)存還有多少如果打8.5折最終價(jià)格是多少) print(輸入 quit 退出。\n) while True: try: user_input input(\n你的問(wèn)題) if user_input.lower() quit: print(再見(jiàn)) break # 執(zhí)行Agent result agent_executor.invoke({input: user_input, chat_history: []}) print(f\n助手{result[output]}) except Exception as e: print(f執(zhí)行出錯(cuò){e}) if __name__ __main__: run_agent_loop()5.3 運(yùn)行與效果驗(yàn)證運(yùn)行python smart_agent.py。測(cè)試用例1“查詢一下產(chǎn)品P1001的信息?!鳖A(yù)期Agent應(yīng)識(shí)別出需要使用ProductDatabaseQuery工具調(diào)用并返回產(chǎn)品詳情。觀察控制臺(tái)當(dāng)verboseTrue時(shí)你會(huì)看到類似Thought: 用戶想查詢產(chǎn)品信息我需要使用ProductDatabaseQuery工具。Action: ProductDatabaseQuery, Action Input: P1001的日志這是Agent的思考過(guò)程。測(cè)試用例2“如果P1002打9折價(jià)格是多少順便告訴我現(xiàn)在的時(shí)間?!鳖A(yù)期Agent應(yīng)規(guī)劃兩個(gè)步驟1) 先查詢P1002的價(jià)格2) 用查詢到的價(jià)格調(diào)用折扣計(jì)算器3) 調(diào)用時(shí)間工具。最終整合所有信息回答。關(guān)鍵學(xué)習(xí)點(diǎn)觀察Agent如何將復(fù)雜問(wèn)題拆解為多個(gè)工具調(diào)用并管理中間信息。測(cè)試用例3“幫我計(jì)算一下半徑為5的圓的面積?!鳖A(yù)期由于我們沒(méi)有提供“計(jì)算面積”的工具Agent應(yīng)識(shí)別出無(wú)法處理并給出合理的回應(yīng)如“我目前沒(méi)有計(jì)算幾何面積的功能”。關(guān)鍵學(xué)習(xí)點(diǎn)理解Agent的能力邊界和失敗處理。6. 企業(yè)級(jí)優(yōu)化與最佳實(shí)踐完成基礎(chǔ)構(gòu)建只是第一步。要讓項(xiàng)目達(dá)到“企業(yè)級(jí)”必須考慮以下方面6.1 RAG系統(tǒng)優(yōu)化問(wèn)題優(yōu)化策略實(shí)操建議檢索不準(zhǔn)1.優(yōu)化文本分割嘗試不同chunk_size和chunk_overlap或按章節(jié)/標(biāo)題分割。2.改進(jìn)檢索器使用MMR搜索最大邊際相關(guān)性平衡相關(guān)性與多樣性或使用SelfQueryRetriever讓模型自己構(gòu)建查詢。3.重排序Rerank使用交叉編碼器模型如bge-reranker對(duì)初步檢索結(jié)果重新排序提升Top1精度。在Retriever中設(shè)置search_typemmr并調(diào)整fetch_k參數(shù)。引入langchain.retrievers中的上下文壓縮或重排序包裝器。答案質(zhì)量差1.優(yōu)化Prompt在Prompt中明確指令如“嚴(yán)格基于上下文”、“以要點(diǎn)形式回答”。2.后處理對(duì)模型生成的答案進(jìn)行事實(shí)一致性檢查或格式規(guī)整。3.多路檢索結(jié)合關(guān)鍵詞檢索如BM25和向量檢索取長(zhǎng)補(bǔ)短。使用PromptTemplate精心設(shè)計(jì)提示詞。考慮使用LLMCheckerChain進(jìn)行事實(shí)核查。無(wú)法溯源確保在鏈中設(shè)置return_source_documentsTrue并在前端清晰展示來(lái)源片段和元數(shù)據(jù)如文件名、頁(yè)碼。參考我們RAGQASystem.ask()方法中的實(shí)現(xiàn)。處理長(zhǎng)文檔對(duì)于超長(zhǎng)文檔考慮使用MapReduce或Refine等更復(fù)雜的鏈類型避免上下文窗口溢出。在RetrievalQA.from_chain_type中嘗試chain_typemap_reduce。6.2 Agent系統(tǒng)優(yōu)化問(wèn)題優(yōu)化策略實(shí)操建議工具調(diào)用錯(cuò)誤1.工具描述清晰工具函數(shù)的description必須精確描述其功能和輸入格式。2.輸入驗(yàn)證與解析在工具函數(shù)內(nèi)部進(jìn)行嚴(yán)格的參數(shù)校驗(yàn)和類型轉(zhuǎn)換。3.使用結(jié)構(gòu)化工具為工具定義嚴(yán)格的args_schemaPydantic模型讓模型更準(zhǔn)確地生成輸入。用Tool.from_function并傳入args_schema參數(shù)。在函數(shù)內(nèi)使用try-except捕獲異常。無(wú)效循環(huán)或幻覺(jué)1.設(shè)置迭代上限max_iterations至關(guān)重要。2.提供示例在系統(tǒng)提示詞中加入幾個(gè)工具調(diào)用的成功示例Few-shot。3.使用更強(qiáng)大的模型復(fù)雜任務(wù)需要更強(qiáng)的推理能力考慮升級(jí)模型如llama3:70b或qwen:72b。在AgentExecutor中設(shè)置max_iterations10。從hub.pull的提示詞模板基礎(chǔ)上添加示例。記憶與狀態(tài)管理為多輪對(duì)話的Agent添加記憶功能使其能記住之前的交互。使用ConversationBufferMemory等記憶組件并將其集成到Agent執(zhí)行器中。6.3 工程化與部署建議配置管理將模型地址、API密鑰、數(shù)據(jù)庫(kù)路徑等抽離到配置文件如config.yaml或環(huán)境變量中。日志與監(jiān)控集成日志記錄如logging模塊記錄每次問(wèn)答/工具調(diào)用的耗時(shí)、Token使用量、成功失敗狀態(tài)。異常處理對(duì)所有可能失敗的環(huán)節(jié)網(wǎng)絡(luò)請(qǐng)求、模型調(diào)用、數(shù)據(jù)庫(kù)操作進(jìn)行try-catch并提供友好的用戶反饋和降級(jí)方案。版本化知識(shí)庫(kù)當(dāng)文檔更新時(shí)應(yīng)有策略地更新向量數(shù)據(jù)庫(kù)全量重建或增量更新并考慮版本管理。容器化部署使用Docker將應(yīng)用及其依賴Python環(huán)境、Ollama打包確保生產(chǎn)環(huán)境一致性。7. 常見(jiàn)問(wèn)題與排查指南在實(shí)踐過(guò)程中你幾乎一定會(huì)遇到以下問(wèn)題。這里提供快速的排查思路問(wèn)題現(xiàn)象可能原因排查步驟解決方案運(yùn)行document_processor.py時(shí)提示缺少pdfplumber或unstructured文檔加載器的依賴未安裝完整。檢查錯(cuò)誤信息確認(rèn)缺失的包名。使用pip install pdfplumber python-magic-bin(Windows)或pip install pdfplumber并安裝系統(tǒng)依賴libmagic(Linux/Mac)。Ollama連接失敗1. Ollama服務(wù)未啟動(dòng)。2. 模型未拉取。1. 終端運(yùn)行ollama serve并保持窗口打開。2. 運(yùn)行ollama list查看已拉取模型。1. 確保服務(wù)在localhost:11434運(yùn)行。2. 使用ollama pull model_name拉取所需模型。RAG答案與文檔無(wú)關(guān)胡編亂造1. 檢索到的上下文不相關(guān)。2. Prompt未強(qiáng)制模型基于上下文。3. 模型本身“幻覺(jué)”嚴(yán)重。1. 檢查檢索到的source_documents內(nèi)容是否與問(wèn)題相關(guān)。2. 檢查Prompt模板。3. 嘗試換用其他模型。1. 優(yōu)化檢索器見(jiàn)6.1。2. 強(qiáng)化Prompt指令如“你必須且只能使用以下上下文”。3. 嘗試qwen:7b或llama3:8b-instruct等指令跟隨能力更強(qiáng)的模型。Agent頻繁調(diào)用錯(cuò)誤工具或參數(shù)格式錯(cuò)誤1. 工具描述不夠清晰。2. 模型推理能力不足。1. 打印Agent的思考過(guò)程(verboseTrue)觀察其決策邏輯。2. 簡(jiǎn)化工具描述使用更結(jié)構(gòu)化的輸入示例。1. 重寫工具description明確輸入輸出格式。2. 使用create_structured_chat_agent等更高級(jí)的Agent類型或升級(jí)模型。程序運(yùn)行速度慢1. 嵌入模型在CPU上運(yùn)行。2. 模型推理速度慢。3. 檢索的文檔塊(k)過(guò)多。1. 檢查硬件使用率。2. 對(duì)流程進(jìn)行分段計(jì)時(shí)。1. 如有GPU將嵌入模型設(shè)置為devicecuda。2. 考慮量化模型或使用更小的模型。3. 減少search_kwargs中的k值如從4減到2。langchain庫(kù)版本沖突或找不到模塊LangChain生態(tài)更新快子模塊路徑可能變化。檢查錯(cuò)誤信息中的具體模塊路徑。1. 確保使用較新且一致的版本組合如langchain0.1.x,langchain-community0.0.x。2. 查閱對(duì)應(yīng)版本的官方文檔。8. 從學(xué)習(xí)到就業(yè)如何構(gòu)建你的技術(shù)portfolio學(xué)完本教程你已掌握了企業(yè)級(jí)AI應(yīng)用的核心構(gòu)建能力。但要將其轉(zhuǎn)化為求職優(yōu)勢(shì)你需要一個(gè)能證明你能力的“作品集”。深化項(xiàng)目不要停留在示例代碼。選擇一個(gè)你感興趣的垂直領(lǐng)域如法律、金融、電商用真實(shí)或模擬數(shù)據(jù)構(gòu)建一個(gè)更專業(yè)的RAG或Agent系統(tǒng)。補(bǔ)充關(guān)鍵技能前端展示用Gradio或Streamlit為你的項(xiàng)目做一個(gè)簡(jiǎn)單的Web界面。部署上線學(xué)習(xí)使用Docker和Docker Compose將整個(gè)應(yīng)用Python后端、Ollama服務(wù)、向量數(shù)據(jù)庫(kù)容器化并部署到云服務(wù)器如阿里云ECS或云原生平臺(tái)。性能評(píng)測(cè)設(shè)計(jì)測(cè)試集量化你的RAG系統(tǒng)的準(zhǔn)確率、召回率和響應(yīng)時(shí)間。文檔與總結(jié)為你的項(xiàng)目撰寫清晰的README.md說(shuō)明項(xiàng)目背景、架構(gòu)、如何運(yùn)行、以及你遇到的核心挑戰(zhàn)和解決方案。這正是面試時(shí)最好的談資。關(guān)注前沿持續(xù)關(guān)注LangChain、LlamaIndex等框架的更新以及Agent、RAG領(lǐng)域的新論文如Agentic RAG、Self-RAG并在你的項(xiàng)目中嘗試應(yīng)用。通過(guò)本教程你走完了從零搭建兩個(gè)核心AI應(yīng)用的完整路徑。你學(xué)到的不僅是LangChain的API調(diào)用更是如何以工程化的思維解決真實(shí)問(wèn)題。接下來(lái)請(qǐng)基于這個(gè)堅(jiān)實(shí)的起點(diǎn)選擇你最感興趣的方向深挖下去用代碼構(gòu)建出真正有價(jià)值的應(yīng)用。

相關(guān)新聞

openEuler系統(tǒng)部署ChatGLM2-6B:從環(huán)境搭建到API服務(wù)的完整實(shí)踐指南

openEuler系統(tǒng)部署ChatGLM2-6B:從環(huán)境搭建到API服務(wù)的完整實(shí)踐指南

1. 項(xiàng)目概述:為什么要在openEuler上部署ChatGLM2? 最近接手了一臺(tái)全新的服務(wù)器,任務(wù)很明確:從零開始,在openEuler操作系統(tǒng)上,完整部署一個(gè)能跑起來(lái)的ChatGLM2-6B大模型。這聽(tīng)起來(lái)像是一個(gè)標(biāo)準(zhǔn)的“環(huán)境搭建…

2026/8/4 10:03:01 閱讀更多
曲線軌道砟道床動(dòng)力學(xué)分析與參振質(zhì)量法應(yīng)用

曲線軌道砟道床動(dòng)力學(xué)分析與參振質(zhì)量法應(yīng)用

1. 曲線軌道砟道床動(dòng)力學(xué)分析背景 在鐵路工程領(lǐng)域,曲線軌道段的動(dòng)力學(xué)行為一直是研究重點(diǎn)和難點(diǎn)。與直線軌道相比,曲線軌道由于存在曲率半徑、超高和軌距變化等幾何特征,輪軌相互作用更為復(fù)雜。我曾在某重載鐵路項(xiàng)目中實(shí)測(cè)發(fā)現(xiàn),曲…

2026/8/4 10:03:01 閱讀更多
【單片機(jī)畢業(yè)設(shè)計(jì)推薦】基于 STM32 的多識(shí)別方式智能門禁系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn) 基于 STM32 與安卓 APP 的藍(lán)牙智能門鎖控制系統(tǒng)設(shè)計(jì)(012505)

【單片機(jī)畢業(yè)設(shè)計(jì)推薦】基于 STM32 的多識(shí)別方式智能門禁系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn) 基于 STM32 與安卓 APP 的藍(lán)牙智能門鎖控制系統(tǒng)設(shè)計(jì)(012505)

文章目錄20 個(gè)相關(guān)畢業(yè)設(shè)計(jì)備選題目項(xiàng)目研究背景摘要總體方案核心功能一、核心身份識(shí)別開鎖功能二、安全防護(hù)與狀態(tài)提示功能三、藍(lán)牙通信與 APP 遠(yuǎn)程控制功能技術(shù)路線項(xiàng)目演示關(guān)于我們項(xiàng)目案例源碼獲取溫馨提示:本人主頁(yè)置頂文章(點(diǎn)我)有 CSDN 平臺(tái)官方提供的學(xué)長(zhǎng)聯(lián)…

2026/8/4 11:13:06 閱讀更多
ThreadForge:Java多線程編程的智能解決方案

ThreadForge:Java多線程編程的智能解決方案

1. 為什么我們需要ThreadForge這樣的多線程工具? 在Java開發(fā)中,多線程編程一直是讓開發(fā)者又愛(ài)又恨的話題。我至今還記得第一次處理線程安全問(wèn)題時(shí),那個(gè)詭異的ConcurrentModificationException異常讓我調(diào)試了整整兩天。傳統(tǒng)的Java多線程API雖然…

2026/8/4 11:13:06 閱讀更多
BitComet比特彗星多協(xié)議下載工具核心功能與優(yōu)化指南

BitComet比特彗星多協(xié)議下載工具核心功能與優(yōu)化指南

1. BitComet 比特彗星的核心價(jià)值解析BitComet作為一款老牌BT下載工具,從2003年發(fā)布至今已經(jīng)迭代了20年。v2.20.1.19多協(xié)議版之所以能保持生命力,關(guān)鍵在于其三大核心能力:首先是多協(xié)議支持能力,這個(gè)版本不僅支持傳統(tǒng)的BitTorrent協(xié)…

2026/8/4 11:13:06 閱讀更多
ChatGPT充值后Codex并發(fā)請(qǐng)求總出錯(cuò)?用冪等設(shè)計(jì)避免重復(fù)執(zhí)行

ChatGPT充值后Codex并發(fā)請(qǐng)求總出錯(cuò)?用冪等設(shè)計(jì)避免重復(fù)執(zhí)行

ChatGPT充值后,很多開發(fā)者會(huì)使用 Codex 編寫接口、生成業(yè)務(wù)邏輯和補(bǔ)充自動(dòng)化測(cè)試。在單用戶、單次請(qǐng)求的情況下,生成的代碼往往可以正常運(yùn)行。但進(jìn)入真實(shí)項(xiàng)目后,一旦出現(xiàn)重復(fù)點(diǎn)擊、網(wǎng)絡(luò)重試或多個(gè)請(qǐng)求同時(shí)執(zhí)行,就可能暴露新的問(wèn)題…

2026/8/4 11:13:06 閱讀更多
Linux網(wǎng)絡(luò)數(shù)據(jù)接收機(jī)制與性能調(diào)優(yōu)實(shí)戰(zhàn)

Linux網(wǎng)絡(luò)數(shù)據(jù)接收機(jī)制與性能調(diào)優(yōu)實(shí)戰(zhàn)

1. 網(wǎng)絡(luò)數(shù)據(jù)接收核心機(jī)制解析當(dāng)我們需要從網(wǎng)絡(luò)接口獲取數(shù)據(jù)時(shí),系統(tǒng)底層究竟發(fā)生了什么?這個(gè)看似簡(jiǎn)單的操作背后,隱藏著一套精密的網(wǎng)絡(luò)協(xié)議棧協(xié)作機(jī)制。今天我們就來(lái)深入剖析網(wǎng)絡(luò)數(shù)據(jù)接收(net_recv)的全過(guò)程&#xff0c…

2026/8/4 11:13:06 閱讀更多
清華大學(xué)重磅EST:植物自導(dǎo)電閃蒸焦耳熱600°C/2600°C兩步法!稀土超積累植物秒級(jí)轉(zhuǎn)化為CeO?-石墨烯電催化劑!

清華大學(xué)重磅EST:植物自導(dǎo)電閃蒸焦耳熱600°C/2600°C兩步法!稀土超積累植物秒級(jí)轉(zhuǎn)化為CeO?-石墨烯電催化劑!

通訊作者:鄧兵、劉建國(guó)通訊單位:清華大學(xué)DOI:https://doi.org/10.1021/acs.est.6c00603研究背景稀土元素(REEs)是清潔能源技術(shù)與電子器件不可或缺的核心原料,然而傳統(tǒng)提取方式依賴能耗高、排放大的采礦與強(qiáng)…

2026/8/4 0:01:30 閱讀更多
貴州師范大學(xué)JCIS:混合焓調(diào)控設(shè)計(jì)PtCoNiCuCr高熵合金!ORR半波電位0.89 V/質(zhì)量活性2.4倍Pt/C!

貴州師范大學(xué)JCIS:混合焓調(diào)控設(shè)計(jì)PtCoNiCuCr高熵合金!ORR半波電位0.89 V/質(zhì)量活性2.4倍Pt/C!

研究背景質(zhì)子交換膜燃料電池(PEMFCs)因其高能量轉(zhuǎn)換效率和清潔零排放特性備受關(guān)注,然而陰極氧還原反應(yīng)(ORR)動(dòng)力學(xué)遲緩、鉑催化劑成本高昂且耐久性不足的問(wèn)題嚴(yán)重制約了其商業(yè)化進(jìn)程。將 Pt 與 3d 過(guò)渡金屬合金化可調(diào)控…

2026/8/4 0:01:30 閱讀更多
福州大學(xué)/清華大學(xué)AFM:脈沖焦耳熱900°C/1s合成Co?Cu催化劑,寬電位NH?法拉第效率~100%,MEA穩(wěn)定300h

福州大學(xué)/清華大學(xué)AFM:脈沖焦耳熱900°C/1s合成Co?Cu催化劑,寬電位NH?法拉第效率~100%,MEA穩(wěn)定300h

通訊作者:萬(wàn)宇馳、張久俊、呂瑞濤通訊單位:福州大學(xué) 、清華大學(xué)DOI:https://doi.org/10.1002/adfm.76112核心導(dǎo)讀:本文提出"分步升級(jí)"廢硝酸鹽處理新路線——利用廢水中的金屬離子經(jīng)快速焦耳熱(40V&#xff…

2026/8/4 0:01:30 閱讀更多
MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案

MoneyPrinterPlus實(shí)戰(zhàn)指南:AI視頻批量生成與自動(dòng)化發(fā)布完整解決方案 【免費(fèi)下載鏈接】MoneyPrinterPlus AI一鍵批量生成各類短視頻,自動(dòng)批量混剪短視頻,自動(dòng)把視頻發(fā)布到抖音,快手,小紅書,視頻號(hào)上,賺錢從來(lái)沒(méi)有這么容易過(guò)! 支持本地語(yǔ)音模型chatTTS,fasterwhisper,…

2026/8/3 7:44:46 閱讀更多
3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南

3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南

3分鐘搞定!QQ空間歷史說(shuō)說(shuō)完整備份終極指南 【免費(fèi)下載鏈接】GetQzonehistory 獲取QQ空間發(fā)布的歷史說(shuō)說(shuō) 項(xiàng)目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾想過(guò),那些年發(fā)過(guò)的QQ空間說(shuō)說(shuō),那些記錄青春的文字…

2026/8/3 12:53:38 閱讀更多
AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O 分配 PCB

AMAT 0100-02186 I/O分配PCB板是應(yīng)用材料(Applied Materials)公司生產(chǎn)的一款用于半導(dǎo)體設(shè)備的I/O信號(hào)分配電路板。該型號(hào)(0100-02186)的核心特點(diǎn)如下:專用于Endura等半導(dǎo)體工藝腔室。集成信號(hào)路由與分配功能。連接控制…

2026/8/3 19:34:52 閱讀更多
Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)

Nissei Corp FFMN-32L-10-T0 40AX 三相異步電動(dòng)機(jī)是日本日清(Nissei)品牌的一款工業(yè)用三相異步電機(jī),適用于自動(dòng)化設(shè)備及通用機(jī)械驅(qū)動(dòng)。該型號(hào)(FFMN-32L-10-T0 40AX)的核心特點(diǎn)如下:三相交流異步電動(dòng)機(jī)。額定…

2026/8/3 19:34:54 閱讀更多