数据库模型(LangChain入门详解(第五章):SQL Agent——让大模型玩转数据库)

数据库模型(LangChain入门详解(第五章):SQL Agent——让大模型玩转数据库)
LangChain入门详解(第五章):SQL Agent——让大模型玩转数据库

在前四章,我们已经一步步搭建起了LangChain的核心能力:接入大模型(大脑)、添加短期记忆(记住对话)、调用Tool工具(动手做事)、定制专属知识库(记住私有文档)。但还有一个非常实用、新手容易上手,且能直接落地到工作中的能力——用大模型操作数据库,也就是本章的核心:SQL Agent

很多新手看到“数据库”“SQL”就头疼,觉得这是程序员的专属技能,自己不懂SQL、不会写查询语句,就没法用。但LangChain的SQL Agent,恰恰解决了这个痛点:它能让大模型“读懂你的自然语言问题”,自动转换成SQL语句,去查询数据库,再把查询结果整理成通俗易懂的自然语言反馈给你——你不用写一行SQL,就能轻松查数据库里的数据

一、先搞懂:SQL Agent到底是什么?(新手必看)

结合前几章的知识,我们用一句大白话总结,瞬间看懂:

SQL Agent,本质是「LangChain专门针对数据库场景,封装的“智能决策者”」——它整合了「大模型(理解问题、写SQL)+ SQL Tool(执行SQL查询)+ 逻辑判断(验证SQL正确性、处理查询结果)」,核心作用就是让不懂SQL的人,也能通过自然语言,快速查询数据库里的数据。

拆解成3个简单步骤,和我们前四章学的逻辑完全一致:

1. 你输入自然语言问题;

数据库模型(LangChain入门详解(第五章):SQL Agent——让大模型玩转数据库)

2. SQL Agent(决策者):让大模型理解问题,自动转换成正确的SQL语句,同时验证SQL是否合法(避免报错);

3. SQL Agent调用SQL Tool,执行SQL语句,查询数据库,再把查询到的冰冷数据(比如“125800”),整理成自然语言(比如“11月份总销售额为125800元”)反馈给你。

关键区分:SQL Agent 和 普通SQL查询(新手别搞混)

很多新手会把SQL Agent和“手动写SQL查询”搞混,这里用一张通俗对比,快速分清核心差异:

- 手动写SQL:需要你懂SQL语法、知道数据库表结构(比如表名、字段名),写错一个符号就会查询失败;

- SQL Agent:你不用懂SQL、不用记表结构,只要用自然语言提问,Agent会自动搞定“写SQL、查数据、整理结果”,容错率高,适合新手和非技术人员。

补充:SQL Agent还能衔接第四章的定制知识库——如果把数据库表结构、字段说明导入知识库,Agent会更精准地写SQL,避免因不懂表结构而报错。

二、为什么要学SQL Agent?3个核心价值(贴合工作场景)

对于新手来说,SQL Agent不是“锦上添花”,而是“能直接提升工作效率”的实用技能,尤其是职场人,学会后能省大量时间,核心价值有3个:

1. 非技术人员也能“查数据库”,不用求程序员

很多职场人(比如运营、财务、行政),工作中需要查数据库里的数据(比如销量、营收、员工考勤),但自己不懂SQL,每次都要找程序员帮忙写SQL、查数据,耗时又麻烦。学会SQL Agent后,自己用自然语言提问,就能快速拿到结果,不用再求人。

2. 节省时间,不用写SQL、不用调试报错

哪怕是懂一点SQL的人,写复杂查询语句(比如多表关联、条件筛选、统计计算),也要反复调试,避免语法错误。SQL Agent能自动写SQL、验证SQL正确性,不用你调试,几秒就能拿到结果。

3. 衔接前四章,搭建“完整数据查询助手”

结合前四章的内容,SQL Agent能和「大模型+短期记忆+Tool+知识库」完美衔接:比如你连续提问“查11月份总销售额”“再查10月份的,对比一下两者差异”,Agent会记住你的上下文(短期记忆),自动对比两次查询结果,不用你再重复提问。

三、新手入门:SQL Agent的核心组件(不用记复杂原理)

LangChain实现SQL Agent,不用复杂配置,核心靠3个组件,和前四章的组件逻辑一致,新手只要记住它们的作用,后续实操会更轻松:

1. 数据库连接(Database Connection)——“连接你的数据库”

作用:相当于“桥梁”,让LangChain能连接到你的数据库(不管是本地数据库,还是线上数据库)。新手入门,我们用「本地SQLite数据库」(不用安装、不用配置,自带Python,直接能用),避免复杂的数据库搭建。

2. SQL Tool ——“执行SQL语句、查询数据”

作用:和第三章学的Tool本质一样,是SQL Agent的“手脚”,负责执行Agent生成的SQL语句,从数据库里查询数据,再把数据返回给Agent。LangChain已经内置了SQL Tool,不用你自己开发,直接调用即可。

3. SQL Agent(智能体)——“核心决策者”

作用:相当于“大脑的延伸”,负责理解你的自然语言问题、生成SQL语句、验证SQL是否正确、处理Tool返回的数据、整理成自然语言回答。LangChain提供了现成的SQL Agent,我们只要把“数据库连接+SQL Tool+大模型”交给它,它就能自动工作。

先贴上今天的完整代码:

import osfrom langchain_community.utilities import SQLDatabasefrom langchain.agents import create_agentfrom langchain_openai import ChatOpenAIfrom langgraph.checkpoint.memory import InMemorySaver  from config import API_KEY, BASE_URL, MODEL_NAME, DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_NAMEfrom langchain_community.agent_toolkits import SQLDatabaseToolkit# 系统提示词模板SYSTEM_PROMPT = """    您是一个专业的MySQL数据库交互专家,专注于处理与数据库操作相关的问题。    **核心能力:**    - 直接执行SQL语句(查询、插入、更新、删除、建表等)    - 自动进行数据验证和结果检查           **重要规则(必须遵守):**    1. 必须完全信任和尊重工具查询结果,即使结果为空或与预期不符    2. 如果sql_db_list_tables工具返回空列表[],说明数据库确实没有表    3. 绝对不要基于训练数据中的常见模式来编造表信息    4. 工具返回什么就回答什么,不要添加、修改或忽略工具结果    当前已知信息:    - 数据库类型: MySQL    - 工具查询结果是最权威的信息源    **工作流程:**    1. **需求分析**:理解用户要执行的操作类型    2. **结构探查**:查看相关表结构和数据    3. **SQL构建**:构建合适的SQL语句    4. **执行验证**:执行SQL并验证结果    要求:    1,表和字段,都应该有中文注释    2,表名和字段名都应该是英文,下划线分割,如果创建表时用户提供的属性是中文,你应该翻译为对应英文创建字段,用户的中文作为字段注释。如果用户给的是英文字段,那么就用这个作为字段名称,对应的翻译作为字段注释。    请用中文回复,操作结果要清晰易懂。"""def setup_database():    """初始化数据库连接"""    db_uri = f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"        try:        db = SQLDatabase.from_uri(db_uri, sample_rows_in_table_info=3)        print("数据库连接成功")        print(f"可用表: {db.get_usable_table_names()}")        return db    except Exception as e:        print(f"数据库连接失败: {e}")        return Nonedef create_sql_agent():    """创建SQL代理"""    # 1. 初始化数据库    db = setup_database()    if not db:        return None    # 2. 初始化模型    llm = ChatOpenAI(        model=MODEL_NAME,        openai_api_key=API_KEY,        openai_api_base=BASE_URL,        temperature=0,        max_tokens=262144    )        # 3. 创建工具集    toolkit = SQLDatabaseToolkit(db=db, llm=llm)    tools = toolkit.get_tools()    # 4. 创建代理    agent = create_agent(        llm,        tools,        checkpointer=InMemorySaver(),          system_prompt=SYSTEM_PROMPT    )        return agentdef main():    """主函数"""    agent = create_sql_agent()    if not agent:        print("代理初始化失败,程序退出")        return    print("SQL代理已就绪,请输入数据库操作需求(输入quit退出)")        while True:        try:            user_input = input("请输入需求:").strip()                        if user_input.lower() in ["quit", "exit"]:                print("程序退出!")                break                            if not user_input:                print("请输入有效需求!")                continue            # 执行查询            inputs = {"messages": [{"role": "user", "content": user_input}]}            response = agent.invoke(inputs,{"configurable": {"thread_id": "1"}})                        # 输出结果            if response and "messages" in response:                content = response["messages"][-1].content                print(f"回复: {content}")                        except KeyboardInterrupt:            print("用户中断,程序退出!")            break        except Exception as e:            print(f"执行出错: {e}")if __name__ == "__main__":    main()
然后咱们把今天的步骤分解一下

1,准备环境,今日的案例使用到的数据库为mysql

2,添加配置文件,在config.py中,我们加入数据库的连接信息,这里我换了一个参数更多的模型,小参数的模型,效果不太好。不过参数多了,调用的时长也变长了

# 1. 数据库配置DB_USER = "root"              # 数据库用户名DB_PASSWORD = "root123" # 数据库密码DB_HOST = "10.10.18.91"       # 数据库IP DB_PORT = "3306"              # 数据库端口DB_NAME = "ai_agent"      # 数据库名MODEL_NAME="moonshotai/Kimi-K2-Instruct-0905"

3,连接数据库,这里咱们只用最简单的配置

def setup_database():    """初始化数据库连接"""    db_uri = f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"        try:        db = SQLDatabase.from_uri(db_uri, sample_rows_in_table_info=3)        print("数据库连接成功")        print(f"可用表: {db.get_usable_table_names()}")        return db    except Exception as e:        print(f"数据库连接失败: {e}")        return None
sample_rows_in_table_info=3  这个参数配置的是提供给ai大模型的示列数据行数在这个初始化连接的方法中,还有一个比较重要的参数engine_args    @classmethod    def from_uri(        cls,        database_uri: Union[str, URL],        engine_args: Optional[dict] = None,        **kwargs: Any,    ) -> SQLDatabase:        """Construct a SQLAlchemy engine from URI."""        _engine_args = engine_args or {}        return cls(create_engine(database_uri, **_engine_args), **kwargs)这个参数可以配置连接池相关信息,在这里咱们先不用

4,初始化模型,这里咱们设置大模型

llm = ChatOpenAI(        model=MODEL_NAME,        openai_api_key=API_KEY,        openai_api_base=BASE_URL,        temperature=0,        max_tokens=262144      )
temperature=0,          # 温度参数(0-2),控制输出的随机性                                            # 0 = 确定性输出,2 = 最大随机性这里因为使用数据库,为防止幻觉限制为0

5,使用langchain提供的sql工具

    # 3. 创建工具集    toolkit = SQLDatabaseToolkit(db=db, llm=llm)    tools = toolkit.get_tools()

如果想看看都有哪些tool,可以在这下面打印出来

    for tool in tools:        print(f"{tool.name}: {tool.description}\n")


tools中的工具

6,创建agent

跟到这里的同学能够发现我的提示词变了,而且比之前的要复杂很多。这里就涉及到提示词工程了,感兴趣的小伙伴可以继续使用原来提示词对比一下效果

# 系统提示词模板SYSTEM_PROMPT = """    您是一个专业的MySQL数据库交互专家,专注于处理与数据库操作相关的问题。    **核心能力:**    - 直接执行SQL语句(查询、插入、更新、删除、建表等)    - 自动进行数据验证和结果检查           **重要规则(必须遵守):**    1. 必须完全信任和尊重工具查询结果,即使结果为空或与预期不符    2. 如果sql_db_list_tables工具返回空列表[],说明数据库确实没有表    3. 绝对不要基于训练数据中的常见模式来编造表信息    4. 工具返回什么就回答什么,不要添加、修改或忽略工具结果    当前已知信息:    - 数据库类型: MySQL    - 工具查询结果是最权威的信息源    **工作流程:**    1. **需求分析**:理解用户要执行的操作类型    2. **结构探查**:查看相关表结构和数据    3. **SQL构建**:构建合适的SQL语句    4. **执行验证**:执行SQL并验证结果    要求:    1,表和字段,都应该有中文注释    2,表名和字段名都应该是英文,下划线分割,如果创建表时用户提供的属性是中文,你应该翻译为对应英文创建字段,用户的中文作为字段注释。如果用户给的是英文字段,那么就用这个作为字段名称,对应的翻译作为字段注释。    请用中文回复,操作结果要清晰易懂。"""  agent = create_agent(        llm,        tools,        checkpointer=InMemorySaver(),          system_prompt=SYSTEM_PROMPT    )

普通AI(简短提示词)

# 就像普通助手 - 灵活但有创意SYSTEM_PROMPT = "你是一个有用的助手"
  • 工作方式:基于训练数据生成回答
  • 风险:可能"编造"信息,但影响不大
  • 例子:问"法国的首都是什么?" - 即使记错了也问题不大

数据库AI(严格提示词)

# 就像银行柜员 - 必须严格按系统操作SYSTEM_PROMPT = """严格的操作规则..."""
  • 工作方式:必须100%基于真实数据
  • 风险:如果"编造"会导致严重后果
  • 例子:问"我的账户余额多少?" - 绝对不能猜!

接下来就是要测试了

我这边先创建两个有关联关系的表,创建表这部分还要对关系型数据库有一些了解。

创建公司表:

帮我创建一个公司表,属性有Id,公司名称,公司位置,法人名称,注册资本

创建公司表

创建员工表:

创建一个员工表,和公司表关联,属性有Id,姓名,手机号,薪水,职位,公司Id

创建员工表与公司表关联

插入测试数据:

给公司表插入两条测试数据,给员工表插入10条测试数据

插入测试数据

开始查询:

我输入了需求:这里我还打错字了[捂脸]

统计一下,这些公司的月薪数量,从小打到排序,

查询结果

这里能看到,我打了错字,但是他还是从语义中理解了我的意图,并且还做了一部分我要求的额外的工作,比如平均月薪、员工数量、两家公司对比,如果是自己玩的话,我觉得还是挺好的,但是在工作中遇到这样的问题,可能还有点麻烦。想要去除他这种发挥,还需要做工作。

第二个问题:

为啥的月薪更高呢?


文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有