本地大模型編程實戰(26)用langgraph實現基于SQL數據構建的問答系統(5)

本文將將擴展上一篇文章完成的 langgraph 鏈,繼續使用基于 langgraph 鏈 ,對結構化數據庫 SQlite 進行查詢的方法。該系統建立以后,我們不需要掌握專業的 SQL 技能,可以用自然語言詢問有關數據庫中數據的問題并返回答案。主要完善一下兩點內容:

  • 自動記錄消息歷史
  • 增加人工審核環節,防止 LLM(大語言模型) 運行危險的SQL語句

我們先看看完成的 langgraph 鏈的模樣,主要有兩步:創建SQL查詢語句->執行SQL查詢語句,在執行SQL查詢前中斷進行人工審核,上一篇文章的 鏈 沒有人工審核:

本次實現的鏈

使用 qwen2.5llama3.1 做實驗。

請注意:
構建 SQL 數據庫的問答系統需要執行模型生成的 SQL 查詢。這樣做存在風險,請確保您的數據庫連接權限始終盡可能小,這將減輕(但不能消除)構建模型驅動系統的風險。

文章目錄

    • 準備開發環境
    • 定義 `langgraph` 步驟/節點
    • 增加人工審核節點
      • 使用內存存儲
      • 在問答中增加人工審核
      • 定義測試方法
      • 見證效果
    • 總結
    • 代碼
    • 參考

準備開發環境

在正式開始擼代碼之前,需要準備一下編程環境。

  1. 計算機
    本文涉及的所有代碼可以在沒有顯存的環境中執行。 我使用的機器配置為:

    • CPU: Intel i5-8400 2.80GHz
    • 內存: 16GB
  2. Visual Studio Code 和 venv
    這是很受歡迎的開發工具,相關文章的代碼可以在 Visual Studio Code 中開發和調試。 我們用 pythonvenv 創建虛擬環境, 詳見:
    在Visual Studio Code中配置venv。

  3. Ollama
    Ollama 平臺上部署本地大模型非常方便,基于此平臺,我們可以讓 langchain 使用 llama3.1qwen2.5deepseek 等各種本地大模型。詳見:
    在langchian中使用本地部署的llama3.1大模型 。

定義 langgraph 步驟/節點

用langgraph實現基于SQL數據構建的問答系統(4) 中對這部分工作有詳細的闡述,這里僅貼出主要代碼,以使得本文內容比較連貫:

"""
1. 創建SQLite對象
"""from langchain_community.utilities import SQLDatabasedb = SQLDatabase.from_uri(f"sqlite:///{db_file_path}")"""
2. 狀態
"""from typing_extensions import TypedDictclass State(TypedDict):question: strquery: strresult: stranswer: strfrom langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3.1",temperature=0, verbose=True)def set_llm(llm_model_name):"""設置大模型,用于測試不同大模型"""global llm llm = ChatOllama(model=llm_model_name,temperature=0, verbose=True)"""
3. 定義langgraph節點
"""from typing_extensions import Annotatedclass QueryOutput(TypedDict):"""生成的SQL查詢語句"""query: Annotated[str, ..., "Syntactically valid SQL query."]# 提示詞system = """You are an agent designed to interact with a SQL database.
Given an input question, create a syntactically correct {dialect} query to run, then look at the results of the query and return the answer.
Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most 5 results.
You can order the results by a relevant column to return the most interesting examples in the database.
Never query for all the columns from a specific table, only ask for the relevant columns given the question.
You have access to tools for interacting with the database.
Only use the given tools. Only use the information returned by the tools to construct your final answer.
You MUST double check your query before executing it. If you get an error while executing a query, rewrite the query and try again.DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.You have access to the following tables: {table_names}
""".format(table_names=db.get_usable_table_names(),dialect=db.dialect
)from langchain_core.prompts import ChatPromptTemplate
query_prompt_template = ChatPromptTemplate.from_messages([("system", system),("user", "Question:{input}")
])def write_query(state: State):"""根據問題生成SQL查詢語句"""prompt = query_prompt_template.invoke({"input": state["question"],})structured_llm = llm.with_structured_output(QueryOutput)result = structured_llm.invoke(prompt)print(f'Query is:\n{result["query"]}')return {"query": result["query"]}from langchain_community.tools.sql_database.tool import QuerySQLDatabaseTooldef execute_query(state: State):"""執行SQL查詢"""execute_query_tool = QuerySQLDatabaseTool(db=db)result = execute_query_tool.invoke(state["query"])print(f'Result is:\n{result}')return {"result": result}def generate_answer(state: State):"""使用檢索到的信息作為上下文來回答問題。"""prompt = ("Given the following user question, corresponding SQL query, ""and SQL result, answer the user question.\n\n"f'Question: {state["question"]}\n'f'SQL Query: {state["query"]}\n'f'SQL Result: {state["result"]}')response = llm.invoke(prompt)print(f'answer is:\n{response.content}')return {"answer": response.content}

增加人工審核節點

LangGraph 可以在敏感步驟(例如執行 SQL 查詢)之前中斷應用程序以供人工審核。這是由 LangGraph 的持久層啟用的,它將運行進度保存到存儲中。

使用內存存儲

from langgraph.graph import START, StateGraphgraph_builder = StateGraph(State).add_sequence([write_query, execute_query, generate_answer]
)
graph_builder.add_edge(START, "write_query")
# graph = graph_builder.compile()from langgraph.checkpoint.memory import MemorySavermemory = MemorySaver()
graph_with_human = graph_builder.compile(checkpointer=memory, interrupt_before=["execute_query"])

上述代碼在 execute_query 執行前中斷了流程,以使得人可以進行人工審核。
MemorySaver 將鏈的執行過程存儲在內存中,它實際上也記錄了聊天歷史,使得鏈具有記憶功能,擁有聊天的上下文信息,可以與用戶進行多輪連續對話。

在問答中增加人工審核

下面我們定義問答方法:

def ask_with_human(question,thread_id):"""問答:增加了人工審核"""config = {"configurable": {"thread_id": thread_id}}for step in graph_with_human.stream({"question": question},config,stream_mode="updates",):print(step)try:user_approval = input("您確定要執行查詢么?(yes/no): ")except Exception:user_approval = "no"if user_approval.lower() == "yes":# 如果獲得批準,再繼續執行for step in graph_with_human.stream(None, config, stream_mode="updates"):print(step)else:print("操作已被取消。")

上面的代碼中增加了人工審核邏輯。

定義測試方法

為方便對多款大模型進行對比測試,我們定義一個簡單的測試方法,其中定義了兩個問題:

def test_model(llm_model_name):"""測試大模型"""print(f'============{llm_model_name}==========')set_llm(llm_model_name)thread_id = "liu23"questions = ["How many Employees are there?","Which country's customers spent the most?",]for question in questions:ask_with_human( question,thread_id)

見證效果

qwen2.5llama3.1 處理這些邏輯都沒有問題,我們用 qwen2.5 執行第1個問題,了解一下執行過程:

  • 同意/yes
{'write_query': {'query': 'SELECT COUNT(*) AS EmployeeCount FROM Employee'}}
{'__interrupt__': ()}
您確定要執行查詢么?(yes/no): yes
{'execute_query': {'result': '[(8,)]'}}
{'generate_answer': {'answer': 'Based on the SQL result provided, there are 8 employees in total. The result `(8,)` indicates that the count of employees is 8.'}}
  • 不同意/no
{'write_query': {'query': 'SELECT COUNT(*) AS EmployeeCount FROM Employee'}}
{'__interrupt__': ()}
您確定要執行查詢么?(yes/no): no
操作已被取消。

總結

langgraph 可以在不修改步驟/節點邏輯的情況下增加人工審批環節,nice。


代碼

本文涉及的所有代碼以及相關資源都已經共享,參見:

  • github
  • gitee

為便于找到代碼,程序文件名稱最前面的編號與本系列文章的文檔編號相同。

參考

  • Build a Question/Answering system over SQL data

🪐感謝您觀看,祝好運🪐

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72127.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72127.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72127.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Kubernetes】污點和容忍

一、概述 在 Kubernetes(k8s)中,污點(Taints) 是定義在節點上的一種機制,用于拒絕某些 Pod 調度到該節點,除非這些 Pod 具有對應的容忍度(Tolerations)。污點可以用來控…

【大模型?知識圖譜】大模型結合醫療知識圖譜:解鎖智能輔助診療系統新范式

【大模型?知識圖譜】大模型結合醫療知識圖譜:解鎖智能輔助診療系統新范式 大模型結合醫療知識圖譜:解鎖智能輔助診療系統新范式引言一、系統架構1.1 系統架構圖1.2 架構模塊說明1.2.1 用戶輸入1.2.2 大模型(語義理解與意圖識別)1.2.3 Agent(問題解析與任務分配)1.2.4 問…

FASIONAD:自適應反饋的類人自動駕駛中快速和慢速思維融合系統

24年11月來自清華、早稻田大學、明尼蘇達大學、多倫多大學、廈門大學馬來西亞分校、電子科大(成都)、智平方科技和河南潤泰數字科技的論文“FASIONAD : FAst and Slow FusION Thinking Systems for Human-Like Autonomous Driving with Adaptive Feedbac…

【免費】YOLO[笑容]目標檢測全過程(yolo環境配置+labelimg數據集標注+目標檢測訓練測試)

一、yolo環境配置 這篇帖子是我試過的,非常全,很詳細【cudaanacondapytorchyolo(ultralytics)】 yolo環境配置 二、labelimg數據集標注 可以參考下面的帖子,不過可能會出現閃退的問題,安裝我的流程來吧 2.1 labelimg安裝 label…

Linux系統軟件管理

systemctl 控制軟件啟動和關閉 Linux系統很多軟件支持使用systemctl命令控制:啟動,停止,開啟自啟。 能被systemctl管理的軟件,一般被稱為:服務。 語法:systemctl start|stop|status|enable|disable 服務名…

CAN總線通信協議學習1——物理層

首先來看看CAN是怎么產生的:簡單理解,CAN就是一種“擁有特別連接方式”的數據傳輸的總線,其有特定的一些規則。 (注:資料及圖片來源于知乎博主TOMOCAT。) CAN總線的結構 查閱參考文獻,OSI標準…

偏移量是什么

在將二維網格映射到一維數組時,偏移量是指在一維數組中 某一行的第一個元素相對于數組起始位置的位置差。對于一個 3 行 4 列的網格,我們使用公式 cur_pos x * n y 來計算二維位置 (x, y) 在一維數組中的索引。 當 x 0 (第一行&#xff…

【Mac電腦本地部署Deepseek-r1:詳細教程與Openwebui配置指南】

文章目錄 前言電腦配置:安裝的Deepseek版本:使用的UI框架:體驗效果展示:本地部署體驗總結 部署過程Ollama部署拉取模型運行模型Openwebui部署運行Ollama服務在Openwebui中配置ollama的服務 后話 前言 deepseek最近火的一塌糊涂&a…

給小白的oracle優化工具,了解一下

有時懶得分析或語句太長,可以嘗試用oracle的dbms_sqldiag包進行sql優化, --How To Use DBMS_SQLDIAG To Diagnose Query Performance Issues (Doc ID 1386802.1) --診斷SQL 性能 SET ECHO ON SET LINESIZE 132 SET PAGESIZE 999 SET LONG 999999 SET SER…

YOLO11改進加入ResNet網絡

文章目錄 1.改進目的2.demo引入2.1代碼2.2 結果展示2.3 BottleNeck詳解 1.改進目的 原始YOLO11模型訓練好以后,檢測結果mAP結果很低,視頻檢測結果很差,于是想到改進網絡,這里介紹改進主干網絡。 2.demo引入 2.1代碼 # File: 2…

Spring MVC流程

SpringMVC啟動流程 啟動流程父子容器請求處理MultipartFile 解析參數傳遞返回值處理HandlerInterceptor 啟動流程 啟動Tomcat解析web.xml創建DispatcherServlet調用DIspatcherServlet的init方法 4.1 創建Spring容器 4.2 發布ContextRefresheEvent 4.3 在OnRefreshed方法中觸發…

【大數據】ClickHouse常見的錯誤及解決方式

ClickHouse 是一款高性能的列式數據庫,但在使用過程中難免會遇到一些錯誤。本文將介紹一些 ClickHouse 常見的錯誤及其解決方式,幫助您更好地使用 ClickHouse。 1、錯誤:DB::Exception 錯誤信息 DB::Exception:Table engine Distributed d…

物理競賽中的線性代數

線性代數 1 行列式 1.1 n n n 階行列式 定義 1.1.1:稱以下的式子為一個 n n n 階行列式: ∣ A ∣ ∣ a 11 a 12 ? a 1 n a 21 a 22 ? a 2 n ? ? ? ? a n 1 a n 2 ? a n n ∣ \begin{vmatrix}\mathbf A\end{vmatrix} \begin{vmatrix} a_{11…

IP-----動態路由OSPF

這只是IP的其中一塊內容,IP還有更多內容可以查看IP專欄,前一章內容為GRE和MGRE ,可通過以下路徑查看IP-------GRE和MGRE-CSDN博客,歡迎指正 注意!!!本部分內容較多所以分成了兩部分在下一章 5.動態路由OS…

數字內容體驗未來趨勢:交互升級與用戶深耕

智能技術重塑內容交互 隨著數字內容體驗進入深度智能化階段,AI驅動的內容生成與智能推薦算法正在重構用戶與信息的交互范式。基于自然語言處理技術的內容創作工具,已實現從文本自動生成到多模態內容適配的跨越,企業能夠以分鐘級速度產出符合…

2025年2月21日優雅草內測分發站全新升級-測試運營-優雅草內測分發站新用戶提供免費100下載點-2月28日正式運營并且提供私有化部署版本

2025年2月21日優雅草內測分發站全新升級-測試運營-優雅草內測分發站新用戶提供免費100下載點-2月28日正式運營并且提供私有化部署版本 說明 優雅草內測分發站新用戶提供免費100下載點,優雅草分運營站和demo測試站 運營站:www.youyacao.cn 提供免費100…

動態內存池設計與環形緩沖區實現詳解

一、動態內存池設計 在嵌入式系統中,頻繁使用 malloc 和 free 會導致內存碎片和性能問題。動態內存池通過預分配固定大小的內存塊,并統一管理分配與釋放,顯著提高內存使用效率和實時性。 1. 核心設計思路 預分配內存:將內存劃分…

015--基于STM32F103ZET6的智能風扇設計

1.實物視頻演示 智能風扇演示視頻 2.程序代碼講解 STM32F103ZET6智能風扇_嗶哩嗶哩_bilibili 3源代碼獲取 https://download.csdn.net/download/weixin_41011452/90440545

【洛谷貪心算法】P1106刪數問題

這道題可以使用貪心算法來解決,核心思路是盡量讓高位的數字盡可能小。當我們逐步刪除數字時,會優先刪除高位中相對較大的數字。具體做法是從左到右遍歷數字序列,當發現當前數字比它后面的數字大時,就刪除當前數字,直到…

開源PDF解析工具olmOCR

olmOCR 是由 Allen Institute for Artificial Intelligence (AI2) 的 AllenNLP 團隊開發的一款開源工具,旨在將PDF文件和其他文檔高效地轉換為純文本,同時保留自然的閱讀順序。它支持表格、公式、手寫內容等。 olmOCR 經過學術論文、技術文檔和其他文檔…