9. 使用LangGraph构建基于 SQL 数据的问答系统
在这篇博客中,我们将深入探讨如何使用 LangChain 和 LangGraph 构建一个智能的 SQL 查询助手。这个助手能够将自然语言问题转换为 SQL 查询,执行查询,并提供人性化的答案。更重要的是,它支持人机协同工作流程,让用户可以在关键步骤进行干预。
0.初始化sql数据
我们新建文件命名为 create_and_insert.sql
1 | CREATE TABLE users ( |
然后在本地安装sqlite3后执行:
1 | sqlite3 test.db |
1. 基础设置和依赖导入
1 | from langchain_community.utilities import SQLDatabase |
这段代码导入了必要的依赖并建立了数据库连接。SQLDatabase 是 LangChain 提供的一个实用工具,它能够将数据库操作无缝集成到 LLM 工作流中。
2. 定义应用程序状态
1 | class State(TypedDict): |
使用 TypedDict 定义应用程序状态,这不仅提供了类型提示,还明确了工作流中数据的流动方式。
3. 初始化语言模型
1 | llm = ChatOpenAI(model="gpt-4-mini") |
我们使用 OpenAI 的 GPT-4-mini 模型,并从 LangChain Hub 获取预定义的 SQL 查询提示模板。这个模板经过优化,能够生成高质量的 SQL 查询。
4. 核心功能实现
4.1 SQL 查询生成
1 | class QueryOutput(TypedDict): |
这个函数负责将用户的自然语言问题转换为有效的 SQL 查询。它使用了:
- 结构化输出确保生成语法正确的 SQL
- 数据库模式信息以生成准确的查询
- 预定义的提示模板优化查询生成
4.2 查询执行
1 | def execute_query(state: State): |
这个函数安全地执行生成的 SQL 查询,使用 LangChain 的 QuerySQLDataBaseTool 确保查询执行的安全性和可靠性。
4.3 答案生成
1 | def generate_answer(state: State): |
这个函数将技术性的 SQL 结果转换为用户友好的自然语言答案。
5. 工作流编排与人工干预机制
5.1 基础工作流设置
1 | memory = MemorySaver() |
5.2 人工干预点配置
1 | graph = graph_builder.compile( |
人工干预机制的实现主要依赖于以下几个关键点:
中断点设置:
- 使用
interrupt_before=["execute_query"]
参数指定在执行查询前进行中断 - 这确保了在执行可能影响数据库的操作前,用户有机会审查和确认
- 使用
状态管理:
MemorySaver
用于保存工作流的状态- 这使得工作流可以在中断后继续执行,不会丢失之前的处理结果
流式执行:
1 | config = {"configurable": {"thread_id": "1"}} |
- 用户交互:
1 | try: |
- 条件继续执行:
1 | if user_approval.lower() == "yes": |
5.3 工作流执行过程
完整的执行流程如下:
- 首先执行
write_query
步骤,生成 SQL 查询 - 到达
execute_query
前自动中断 - 显示生成的查询并等待用户确认
- 根据用户的选择:
- 如果确认,继续执行查询和生成答案
- 如果拒绝,终止操作
5.4 示例输出
1 | {'write_query': {'query': 'SELECT COUNT(*) as 用户数量 FROM users;'}} |
这种人工干预机制的优势在于:
- 安全性:防止未经审查的查询直接执行
- 可控性:用户可以在关键节点进行干预
- 透明性:清晰展示每个步骤的执行结果
- 灵活性:可以根据需要在不同节点添加中断点
6.总结
这个项目展示了如何将多个强大的工具(LangChain、LangGraph、GPT-4)组合起来,构建一个智能且安全的 SQL 查询助手。通过分层设计和人机协同,我们既保证了系统的自动化程度,又确保了操作的安全性。
关键特点:
- 自然语言理解和 SQL 生成
- 类型安全和错误处理
- 人机协同的工作流程
- 可扩展的模块化设计
这个方案可以作为构建其他 AI 驱动的数据库工具的参考架构。
7.完整代码
1 | from langchain_community.utilities import SQLDatabase |