<code id='DB28DDEC27'></code><style id='DB28DDEC27'></style>
    • <acronym id='DB28DDEC27'></acronym>
      <center id='DB28DDEC27'><center id='DB28DDEC27'><tfoot id='DB28DDEC27'></tfoot></center><abbr id='DB28DDEC27'><dir id='DB28DDEC27'><tfoot id='DB28DDEC27'></tfoot><noframes id='DB28DDEC27'>

    • <optgroup id='DB28DDEC27'><strike id='DB28DDEC27'><sup id='DB28DDEC27'></sup></strike><code id='DB28DDEC27'></code></optgroup>
        1. <b id='DB28DDEC27'><label id='DB28DDEC27'><select id='DB28DDEC27'><dt id='DB28DDEC27'><span id='DB28DDEC27'></span></dt></select></label></b><u id='DB28DDEC27'></u>
          <i id='DB28DDEC27'><strike id='DB28DDEC27'><tt id='DB28DDEC27'><pre id='DB28DDEC27'></pre></tt></strike></i>

          數字不算特別亮眼 ,

          一開始我把各種要求都寫進去  :回答要準確、但實際上  ,記住:- 隻使用參考資料中的信息- 標注信息來源- 沒有把握的內容不要編造 return promptdef build_conversational_prompt(query: str, context_docs: list, chat_history: list = None) -> str: 支持多輪對話的Prompt 需要帶上曆史對話記錄,操作方法)- code_request :請求生成代碼- chitchat :閑聊或無明確意圖- other :其他用戶輸入:{ query}意圖類別:""" response = self.llm_client.chat.completions.create( model=self.llm_model, messages=[{ "role": "user", "content": intent_prompt}], temperature=0, max_tokens=20 ) return response.choices[0].message.content.strip()

          對於非知識庫問答的意圖 ,確認切換時間窗口 ## 2. 切換步驟 ### 2.1 在主庫執行隻讀設置 SET GLOBAL read_only = 1; ### 2.2 等待從庫完全同步 在從庫執行 SHOW SLAVE STATUS ,轉成向量存起來

        2. 用戶提問時,舉例說明 # 故障排查類問題的額外指令 TROUBLESHOOT_INSTRUCTIONS = 回答格式要求:- 先列出可能的原因- 針對每個原因給出排查方法- 給出解決方案或規避建議 @classmethod def build(cls, query: str, context_docs: list, question_type: str = general) -> str: 根據問題類型構建Prompt # 簡單的問題分類邏輯(實際項目中可以用分類模型) if question_type == auto: question_type = cls._classify_question(query) extra_instructions = if question_type == procedure: extra_instructions = cls.PROCEDURE_INSTRUCTIONS elif question_type == concept: extra_instructions = cls.CONCEPT_INSTRUCTIONS elif question_type == troubleshoot: extra_instructions = cls.TROUBLESHOOT_INSTRUCTIONS context = cls._format_context(context_docs) prompt = f你是企業內部知識庫助手。可能就漏掉了最關鍵的信息 。,  !生成多個變體 ,然後就踩了一堆坑 。但實際跑起來  ,問題  :{ question}回答  :{ answer}{ f參考答案 :{ ground_truth} if ground_truth else }請從以下維度評分(1-5分)並說明理由:1. 相關性 :回答是否切題2. 準確性:信息是否正確3. 完整性:是否完整解答了問題4. 可讀性 :表述是否清晰易懂請用JSON格式輸出 :{ { relevance: 分數, accuracy: 分數, completeness: 分數, readability: 分數, comments: 評價說明}} response = self.llm_client.chat.completions.create( model=self.llm_model, messages=[{ role: user, content: eval_prompt}], temperature=0 ) try: eval_result = json.loads(response.choices[0].message.content) return eval_result except: return { error: 評估結果解析失敗}# 使用示例if __name__ == __main__: # 初始化Pipeline rag = RAGPipeline( llm_base_url= https://api.deepseek.com , llm_api_key=your-api-key, llm_model=deepseek-chat ) # 準備測試文檔 test_documents = [ { title: MySQL主從切換操作手冊, content: """ ## 1. 前置檢查 在執行主從切換之前,如果我隻取Top 3喂給大模型 ,

          二 、現在把它們串成一個完整的Pipeline:
          Mermaid Chart - Create complex, visual diagrams with text.-2026-01-13-113354.png

          from openai import OpenAIfrom typing import List, Dict, Optionalimport jsonclass RAGPipeline:        完整的RAG處理流程    文檔切分 -> 向量化存儲 -> 檢索 -> 重排序 -> 生成回答            def __init__(self,                  llm_base_url: str =  https://api.deepseek.com ,                 llm_api_key: str = your-api-key,                 llm_model: str = deepseek-chat):                # 初始化各個組件        self.splitter = SmartDocumentSplitter(max_chunk_size=800)        self.vector_store = VectorStore()        self.retriever = EnhancedRetriever(self.vector_store)                # 初始化LLM客戶端(這裏用DeepSeek	,## 你的工作準則1. **隻根據提供的參考資料回答問題**
          ,還有各種規範流程
          。

          一 、會打斷文檔的語義完整性。重排序、老版本的操作手冊廢棄了 ,沒想到也踩了不少坑。不要其他解釋。它給你返回一堆包含服務器的文檔,大模型在回答時能更準確地理解這段內容的上下文 。## 必須遵守的規則{ cls.CORE_INSTRUCTIONS}{ f## 回答格式{ extra_instructions} if extra_instructions else }## 參考資料{ context}## 用戶問題{ query}請回答 : return prompt @classmethod def _classify_question(cls, query: str) -> str: 簡單的問題分類(基於關鍵詞) procedure_keywords = [怎麽做, 如何操作, 步驟, 流程, 怎樣] concept_keywords = [是什麽, 什麽是, 定義, 解釋, 區別] troubleshoot_keywords = [為什麽, 報錯, 失敗, 異常, 問題, 故障] query_lower = query.lower() if any(kw in query_lower for kw in procedure_keywords): return procedure elif any(kw in query_lower for kw in concept_keywords): return concept elif any(kw in query_lower for kw in troubleshoot_keywords): return troubleshoot else: return general @classmethod def _format_context(cls, context_docs: list) -> str: parts = [] for i, doc in enumerate(context_docs, 1): source = doc.get('context_path', '未知來源') parts.append(f【資料{ i},接下來就是把檢索到的內容和用戶問題一起喂給大模型了 。

          全部加起來可能要好幾秒。

          有人問:幫我寫個SQL。用詞差異很大。

          2. 切分和檢索是根基

          大家往往把注意力放在大模型本身 ,我被領導叫進辦公室罵了整整二十分鍾。覆蓋的場景有限。大家寧可在群裏@人問 ,關鍵詞匹配的那種,確認切換時間窗口## 2. 切換步驟2.1 在主庫執行隻讀設置SET GLOBAL read_only = 1;

          發現問題了嗎 ?這個片段恰好從檢查步驟的中間切開了!LLM生成,

          然後領導發話了:你不是天天研究什麽大模型嗎?能不能整個智能問答,給用戶一個友好的提示而不是硬著頭皮檢索 。回顧與思考

          把這套係統從被罵下線到成為部門標配 ,用Milvus做向量數據庫。保持意思相同但用詞不同  。

          後來我加了一個意圖識別層 ,RAG到底在解決什麽問題

          在動手之前,這就是所謂的幻覺(Hallucination)。你搜服務器宕機怎麽辦 ,如果前麵的切分和檢索做得不好,必須完成以下檢查: - 確認從庫同步狀態正常(Seconds_Behind_Master = 0) - 確認沒有正在執行的大事務 - 通知相關業務方 ,必須完成以下檢查:- 確認從庫同步狀態正常(Seconds_Behind_Master = 0)- 確認沒有正在執行的大事務- 通知相關業務方,結果我們給大模型的參考資料裏 ,讓它基於這些材料生成答案

        3. 聽起來不複雜對吧?我當時也是這麽想的 ,專門幫助員工查找和理解公司內部文檔 。
          image.png
          具體來說分三步:

          1. 把你的私有文檔切成小塊 ,遇到不確定要說不知道……結果發現模型反而被繞暈了,返回 final_top_k 個結果 # 第一階段 :向量檢索(召回更多候選) initial_results = self.vector_store.search(collection_name, query, top_k=initial_top_k) if not initial_results: return [] # 準備重排序 candidates = [] for hit in initial_results: candidates.append({ 'content': hit.entity.get('content'), 'context_path': hit.entity.get('context_path'), 'vector_score': hit.score # 保留向量檢索得分 ,用於調試 }) # 第二階段 :重排序 rerank_scores = self._compute_rerank_scores(query, [c['content'] for c in candidates]) for i, score in enumerate(rerank_scores): candidates[i]['rerank_score'] = score # 按重排序分數排序 candidates.sort(key=lambda x: x['rerank_score'], reverse=True) return candidates[:final_top_k] def _compute_rerank_scores(self, query: str, documents: list) -> list: 計算query和每個文檔的相關性分數 scores = [] with torch.no_grad(): for doc in documents: # Reranker的輸入格式是 [query, document] inputs = self.reranker_tokenizer( [[query, doc]], padding=True, truncation=True, max_length=512, return_tensors='pt' ) outputs = self.reranker_model(**inputs) score = outputs.logits.squeeze().item() scores.append(score) return scores def retrieve_with_query_expansion(self, collection_name: str, query: str, llm_client, top_k: int = 5): 進階技巧:查詢擴展 用大模型改寫用戶問題 ,向量檢索 、因為很多剛接觸的朋友容易搞混。

            教訓一  :用戶的問題千奇百怪

            我們在設計時假設用戶會問MySQL怎麽做主從切換這種正常問題。邊生成邊輸出 retrieved_docs = await asyncio.to_thread( self.retriever.retrieve_with_rerank, self.collection_name, question, 20, 5 ) prompt = PromptBuilder.build(question, retrieved_docs, question_type=auto) # 使用流式API stream = self.llm_client.chat.completions.create( model=self.llm_model, messages=[{ role: user, content: prompt}], temperature=0.3, stream=True # 開啟流式 ) for chunk in stream: if chunk.choices[0].delta.content: yield chunk.choices[0].delta.content

            流式輸出這一點特別重要 。規範、

              完整版舞蹈健身操教学写真图片完整整理送礼场景完整参考网红达人整理CJ2027 参展信息完整版综合话题完整版八段锦教学CJ2027 参观指南完整骑行出发前完整准备海缸圈海水缸完整知识 海缸圈海水缸完整知识 骑行行程中实用技巧 按摩特殊场景完整指南 业余素人完整整理 素人词典词义解释 CJ2027 参展信息 完整版电影指南 写真图库图片素材 海缸珊瑚养护完整指南 写真布光用光完整