如何利用LangChain1.0快速进行天气和数据库查询

该文章已生成可运行项目,

如何利用LangChain1.0快速进行天气和数据库查询

1. 系统概述

本系统是一个基于LangChain框架构建的智能数据库查询工具,利用通义千问大语言模型和SQL数据库工具包实现自然语言数据库查询功能。用户可以通过自然语言提问来查询SQLite数据库中的信息。

2. 系统架构

2.1 主要组件

  1. Agent代理模块 ([dashscope_db_example.py](file:///Users/laraveljun/big_model/langchain-learn/dashscope_db_example.py))

    • 使用ChatTongyi模型作为核心推理引擎
    • 集成SQL数据库工具包
    • 处理自然语言输入并生成相应响应
  2. 数据库工具模块 ([func_tool/db_tools.py](file:///Users/laraveljun/big_model/langchain-learn/func_tool/db_tools.py))

    • 实现了SQL数据库工具包的创建和管理
    • 包含两个主要函数:
      • create_sql_database_toolkit: 创建SQL数据库工具包
      • get_sql_tools: 获取SQL工具列表
  3. 数据库结构

    • 使用SQLite数据库存储学生测验数据
    • 包含学生表([student](file:///Users/laraveljun/big_model/langchain-learn/database/studnet.sql#L1-L6))、题目表([quiz_question](file:///Users/laraveljun/big_model/langchain-learn/database/studnet.sql#L8-L16))和答题记录表([answer_record](file:///Users/laraveljun/big_model/langchain-learn/database/studnet.sql#L18-L25))

2.2 工作流程

  1. 用户提出自然语言查询(如"难度为中等有多少道题?")
  2. Agent解析用户意图并调用适当的SQL工具
  3. 工具执行相应的数据库操作(查看表结构、生成SQL查询等)
  4. 执行查询并获取结果
  5. Agent将结果格式化后返回给用户

3. 核心模块详解

3.1 Agent代理模块 ([main.py](file:///Users/laraveljun/big_model/langchain-learn/dashscope_db_example.py))

from dotenv import load_dotenv
import os
# 加载.env文件中的环境变量
load_dotenv(override=True)

from func_tool.wechat import query_weather
from func_tool.db_tools import get_sql_tools

from langchain.agents import create_agent
from langchain_community.chat_models import ChatTongyi
model = ChatTongyi(model="qwen-turbo", api_key=os.getenv("DASHSCOPE_API_KEY"))

# 创建可以同时使用天气和数据库工具的智能助手
database_uri = "sqlite:///student_quiz.db"  # 示例数据库URI

tools = get_sql_tools(database_uri, model)

# 创建智能助手,可以同时使用天气和数据库工具
agent = create_agent(
    model=model,
    tools=[query_weather]+tools,
system_prompt='''
    1、你是一个专业的 SQL 数据分析师。
        工作流程:
        1. 先使用 sql_db_list_tables 查看所有表
        2. 使用 sql_db_schema 获取相关表的结构
        3. 生成 SQL 查询前,使用 sql_db_query_checker 检查语法
        4. 使用 sql_db_query 执行查询
        5. 用中文总结查询结果
        注意事项:
        - 只使用数据库中实际存在的表和字段
        - 查询结果限制在 10 条以内
        - 如果查询出错,分析错误并重新生成 SQL
        - 有多个问题的时候,需要进行整理后返回
    2、您是一个乐于助人的助手,您可以回答用户的问题,也可以帮助用户解决问题。
    ''',
)

question = "难度为中等有多少道题?"

# Run the agent with database query
response = agent.invoke(
    {"messages": [{"role": "user", "content": question}]}
)
print(response['messages'][-1].content)

3.2 数据库工具模块 ([func_tool/db_tools.py](file:///Users/laraveljun/big_model/langchain-learn/func_tool/db_tools.py))

from typing import List, Dict, Any, Optional
from langchain_core.language_models import BaseLanguageModel
from langchain_community.utilities import SQLDatabase
from langchain_community.agent_toolkits import SQLDatabaseToolkit


def create_sql_database_toolkit(
    database_uri: str, 
    llm: BaseLanguageModel
) -> SQLDatabaseToolkit:
    """
    创建SQL数据库工具包,
    Args:
        database_uri: 数据库连接URI
        llm: 语言模型实例
        
    Returns:
        SQLDatabaseToolkit: 配置好的SQL工具包
    """
    db = SQLDatabase.from_uri(database_uri)
    toolkit = SQLDatabaseToolkit(db=db, llm=llm)
    return toolkit


def get_sql_tools(
    database_uri: str, 
    llm: BaseLanguageModel
) -> List:
    """
    获取SQL数据库工具列表,包含查询和操作数据库的工具
    Args:
        database_uri: 数据库连接URI
        llm: 语言模型实例
        
    Returns:
        List: 工具列表
    """
    toolkit = create_sql_database_toolkit(database_uri, llm)
    return toolkit.get_tools()

4. 关键特性

  • 自然语言处理:支持中文数据库查询
  • 智能查询构建:自动生成合适的SQL查询语句
  • 安全查询机制:查询前语法检查,避免错误查询
  • 模块化设计:各功能模块解耦,易于扩展
  • 环境配置管理:通过.env文件管理API密钥

5. 依赖库

  • langchain:AI代理框架
  • langchain_community:社区模型支持
  • langchain_community.agent_toolkits:SQL工具包
  • langchain_community.utilities:SQL数据库工具
  • python-dotenv:环境变量加载
  • dashscope:DashScope API支持

6. 环境配置

需要在.env文件中设置以下环境变量:

DASHSCOPE_API_KEY=your_dashscope_api_key

7. 使用方法

  1. 安装依赖包:

    pip install -r requirements.txt
    
  2. 配置环境变量:
    创建.env文件并填入相应的API密钥

  3. 运行程序:

    python main.py
    

8. 数据库结构

系统使用SQLite数据库,包含以下表:

8.1 学生表 ([student](file:///Users/laraveljun/big_model/langchain-learn/database/studnet.sql#L1-L6))

  • student_id:学生ID(主键)
  • student_name:学生姓名
  • class:班级
  • create_time:创建时间

8.2 题目表 ([quiz_question](file:///Users/laraveljun/big_model/langchain-learn/database/studnet.sql#L8-L16))

  • question_id:题目ID(主键)
  • question_type:题目类型
  • question_content:题目内容
  • options:选项
  • correct_answer:正确答案
  • difficulty:难度等级
  • score:分值

8.3 答题记录表 ([answer_record](file:///Users/laraveljun/big_model/langchain-learn/database/studnet.sql#L18-L25))

  • record_id:记录ID(主键)
  • student_id:学生ID(外键)
  • question_id:题目ID(外键)
  • student_answer:学生答案
  • is_correct:是否正确
  • submit_time:提交时间

数据库迁移脚本

# 创建 SQLite 数据库
import sqlite3

# 连接到数据库文件(如果不存在会自动创建)
conn = sqlite3.connect("student_quiz.db")
cursor = conn.cursor()

# 创建学生表
cursor.execute("""
CREATE TABLE IF NOT EXISTS student (
    student_id VARCHAR(20) PRIMARY KEY,
    student_name VARCHAR(50) NOT NULL,
    class VARCHAR(20) NOT NULL,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
)
""")

# 创建题目表
cursor.execute("""
CREATE TABLE IF NOT EXISTS quiz_question (
    question_id INTEGER PRIMARY KEY AUTOINCREMENT,
    question_type VARCHAR(20) NOT NULL,
    question_content TEXT NOT NULL,
    options TEXT,
    correct_answer VARCHAR(100) NOT NULL,
    difficulty VARCHAR(10) NOT NULL,
    score INTEGER NOT NULL
)
""")

# 创建答题记录表
cursor.execute("""
CREATE TABLE IF NOT EXISTS answer_record (
    record_id INTEGER PRIMARY KEY AUTOINCREMENT,
    student_id VARCHAR(20) NOT NULL,
    question_id INTEGER NOT NULL,
    student_answer VARCHAR(100) NOT NULL,
    is_correct INTEGER NOT NULL,
    submit_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (student_id) REFERENCES student(student_id),
    FOREIGN KEY (question_id) REFERENCES quiz_question(question_id)
)
""")

# 创建测验汇总表
cursor.execute("""
CREATE TABLE IF NOT EXISTS quiz_summary (
    summary_id INTEGER PRIMARY KEY AUTOINCREMENT,
    quiz_name VARCHAR(100) NOT NULL,
    applicable_grade VARCHAR(20) NOT NULL,
    total_score INTEGER NOT NULL,
    quiz_duration VARCHAR(20) NOT NULL,
    total_students INTEGER NOT NULL,
    error_questions VARCHAR(100),
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
)
""")

# 插入学生数据
students_data = [
    ('80101', '张三', '初二1班', '2025-11-17 08:00:00'),
    ('80102', '李四', '初二1班', '2025-11-17 08:00:00'),
    ('80103', '王五', '初二1班', '2025-11-17 08:00:00'),
    ('80104', '赵六', '初二1班', '2025-11-17 08:00:00'),
    ('80105', '孙七', '初二1班', '2025-11-17 08:00:00'),
    ('80106', '周八', '初二2班', '2025-11-17 08:05:00'),
    ('80107', '吴九', '初二2班', '2025-11-17 08:05:00'),
    ('80108', '郑十', '初二2班', '2025-11-17 08:05:00'),
    ('80109', '钱十一', '初二2班', '2025-11-17 08:05:00'),
    ('80110', '冯十二', '初二2班', '2025-11-17 08:05:00')
]

# 插入题目数据
questions_data = [
    # 选择题
    ('选择', '下列各组词语中,加点字读音完全正确的一项是',
     'A.粗犷(kuàng) 莅临(lì) 棱镜(léng)|B.静谧(mì) 憔悴(qiáo) 确凿(záo)|C.吝啬(lìn) 徘徊(huí) 倜傥(tǎng)|D.怂恿(sǒng) 称职(chèng) 蜷伏(quán)',
     'B', '易', 5),
    ('选择', '下列句子中,没有语病的一项是',
     'A.通过开展"城乡环境综合治理"活动,使我市环境卫生状况有了很大改变。|B.传统文化源远流长,其中不少优秀的文化著作,可作为青少年人格教育的读本。|C.有无扎实的阅读基础,是青少年提高写作能力的前提。|D.为了防止失窃事件不再发生,保安部门采取了切实有效的措施。',
     'B', '中', 5),
    ('选择', '数学中,将二次函数y=2x²-4x+3化为顶点式y=a(x-h)²+k的形式,正确的是',
     'A.y=2(x-1)²+1|B.y=2(x-1)²+5|C.y=2(x+1)²+1|D.y=2(x+1)²+5',
     'A', '中', 5),
    ('选择', '下列关于物理现象的解释,错误的是',
     'A.春天冰雪消融,是熔化现象,需要吸热|B.夏天刚从冰箱拿出的冰棍周围冒"白气",是汽化现象|C.秋天草叶上出现露珠,是液化现象,需要放热|D.冬天窗户玻璃上出现冰花,是凝华现象,需要放热',
     'B', '难', 5),
    ('选择', '历史上,标志着中国近代史开端的事件是',
     'A.鸦片战争|B.太平天国运动|C.甲午中日战争|D.辛亥革命',
     'A', '易', 5),
    # 填空题
    ('填空', '古诗文默写:______,长河落日圆。(王维《使至塞上》)',
     None, '大漠孤烟直', '易', 6),
    ('填空', '化学中,实验室制取二氧化碳的化学方程式为',
     None, 'CaCO₃ + 2HCl = CaCl₂ + H₂O + CO₂↑', '中', 6),
    ('填空', '英语语法:She ______ (finish) her homework before she went out to play yesterday。(用所给词的适当形式填空)',
     None, 'had finished', '中', 6),
    ('填空', '数学应用:一个多边形的内角和是1080°,则这个多边形的边数是',
     None, '8', '难', 6),
    ('填空', '生物知识:生态系统中,______是最大的生态系统,它包括大气圈的底部、水圈的大部和岩石圈的表面',
     None, '生物圈', '易', 6),
    # 判断题
    ('判断', '鲁迅的《朝花夕拾》是一部回忆性散文集,原名《旧事重提》',
     None, '对', '易', 5),
    ('判断', '物理学中,压力的方向总是垂直于接触面指向被压物体',
     None, '对', '中', 5),
    ('判断', '地理上,赤道是南北半球的分界线,本初子午线是东西半球的分界线',
     None, '错', '难', 5),
    ('判断', '语文中,"他经常回忆过去的往事"这句话没有语病',
     None, '错', '易', 5),
    ('判断', '数学中,反比例函数y=k/x(k为常数,k≠0)的图像一定经过点(1,k)',
     None, '对', '中', 5)
]

# 插入答题记录数据
answers_data = [
    ('80101', 1, 'B', 1, '2025-11-17 09:00:00'),
    ('80101', 2, 'A', 0, '2025-11-17 09:01:00'),
    ('80101', 3, 'A', 1, '2025-11-17 09:02:00'),
    ('80101', 4, 'B', 1, '2025-11-17 09:03:00'),
    ('80101', 5, 'C', 0, '2025-11-17 09:04:00'),
    ('80102', 1, 'A', 0, '2025-11-17 09:00:00'),
    ('80102', 2, 'B', 1, '2025-11-17 09:01:00'),
    ('80102', 3, 'B', 0, '2025-11-17 09:02:00'),
    ('80102', 4, 'C', 0, '2025-11-17 09:03:00'),
    ('80102', 5, 'A', 1, '2025-11-17 09:04:00')
]

# 插入测验汇总数据
summary_data = [
    ('学科知识综合测验', '初中二年级', 100, '40分钟', 10, '2,3,4,8,9,13', '2025-11-17 10:00:00')
]

# 执行插入操作
cursor.executemany("INSERT OR REPLACE INTO student VALUES (?, ?, ?, ?)", students_data)
cursor.executemany("INSERT OR REPLACE INTO quiz_question (question_type, question_content, options, correct_answer, difficulty, score) VALUES (?, ?, ?, ?, ?, ?)", questions_data)
cursor.executemany("INSERT OR REPLACE INTO answer_record (student_id, question_id, student_answer, is_correct, submit_time) VALUES (?, ?, ?, ?, ?)", answers_data)
cursor.executemany("INSERT OR REPLACE INTO quiz_summary (quiz_name, applicable_grade, total_score, quiz_duration, total_students, error_questions, create_time) VALUES (?, ?, ?, ?, ?, ?, ?)", summary_data)

# 启用外键约束
cursor.execute("PRAGMA foreign_keys = ON")

# 提交更改并关闭连接
conn.commit()
conn.close()

print("学生测验数据库创建成功!")
print("已创建 4 张表:student, quiz_question, answer_record, quiz_summary")


## 9. 扩展建议

- 可增加更多数据库相关工具(如数据可视化等)
- 支持更多类型的数据库(MySQL、PostgreSQL等)
- 添加复杂查询的缓存机制
- 增加数据库管理功能(增删改查)


本文章已经生成可运行项目
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明知道的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值