PAL(Program-Aided Language models) 思想成为大模型 Agent 领域的重要范式。核心思路是 LLM 只负责语言任务,复杂的逻辑/计算交由程序执行

通过合理设计 prompt,模型生成代码/SQL/逻辑描述,外部程序再执行,得到结果后反馈给 LLM,LLM 再生成最终答案。

本文将通过一个 LangChain + MySQL + Postgres Checkpoint 实例,完整演示 PAL 的设计流程,帮助大家理解和复现。

项目结构

.
├── llm_env.py # 初始化 LLM
└── main.py # PAL 交互主流程

llm_env.py:初始化 LLM

from langchain.chat_models import init_chat_model

llm = init_chat_model("gpt-4o-mini", model_provider="openai")

简单封装一个 LLM 对象,这里用 gpt-4o-mini,通过 llm_env.llm 调用。

main.py:PAL 主流程

导入库 & 初始化
import os
import sys sys.path.append(os.getcwd()) from langchain_community.utilities import SQLDatabase
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.tools.sql_database.tool import QuerySQLDatabaseTool
from langgraph.graph import START, StateGraph
from langgraph.checkpoint.postgres import PostgresSaver
import time
from typing import TypedDict, Annotated
from llm_set import llm_env llm = llm_env.llm

亮点:

  • 用 StateGraph 组织整个流程

  • 用 PostgresSaver 持久化 checkpoint,方便中断恢复

初始化 MySQL 数据库
db = SQLDatabase.from_uri(
"mysql+pymysql://root:123456@localhost:3306/javademo",
engine_args={"pool_size": 5, "max_overflow": 10},
)

数据库连接,示例用 javademo 库,用户可根据实际修改。

State 定义
class State(TypedDict):
"""State for the demo.""" question: str
query: str
result: str
answer: str
approved: bool

定义流程中的共享变量,典型 PAL 模式的中间态。

Prompt 设计
system_message = """
Given an input question, create a syntactically correct {dialect} query to
run to help find the answer. Unless the user specifies in his question a
specific number of examples they wish to obtain, always limit your query to
at most {top_k} 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 a the
few relevant columns given the question. Pay attention to use only the column names that you can see in the schema
description. Be careful to not query for columns that do not exist. Also,
pay attention to which column is in which table. Only use the following tables:
{table_info}
""" user_prompt = "Question:{input}" query_prompt_template = ChatPromptTemplate(
[("system", system_message), ("human", user_prompt)],
)

亮点:

  • 系统提示明确要求 安全、规范 的 SQL

  • 限定 top_k 结果

  • 避免 SELECT *

LLM 生成 SQL
class QueryOutput(TypedDict):
"""Generated the SQL query."""
query: Annotated[str, "Syntactically valid SQL query."] def write_query(state: State):
"""Generate SQL query to fetch information."""
prompt = query_prompt_template.invoke(
{
"dialect": db.dialect,
"top_k": 5,
"table_info": db.get_table_info(),
"input": state["question"],
}
) structured_llm = llm.with_structured_output(QueryOutput) result = structured_llm.invoke(prompt) return {"query": result["query"]}

PAL 核心步骤 1
LLM 不直接回答问题,而是生成 SQL 查询。

用户确认
def wait_for_user_approve(state: State):
"""Pause here and wait for user approval before executing query."""
try:
user_approval = input("Do you want to go to execute query? (yes/no): ")
except Exception:
user_approval = "no" if user_approval.lower() == "yes":
return {
"query": state["query"],
"approved": True,
}
else:
return {
"query": state["query"],
"approved": False,
}

用户确认 SQL 是否执行,保证安全性 —— 很关键。

执行 SQL
def excute_query(state: State):
"""Execute the SQL query and return the result."""
if state["approved"]:
execute_query_tool = QuerySQLDatabaseTool(db=db)
return {"result": execute_query_tool.invoke(state["query"])}
else:
return {"result": "excute denied."}

PAL 核心步骤 2
SQL 执行交给程序完成,LLM 不直接操作数据库。

回答用户
def generate_answer(state: State):
"""Answer question using retrieved information as context."""
if state["approved"]:
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)
return {"answer": response.content} else:
prompt = f'{"同意" if state["approved"] else "拒绝"} 用户拒绝当前执行'
response = llm.invoke(prompt)
return {"answer": response.content}

PAL 核心步骤 3
LLM 根据 SQL 结果生成最终自然语言答案。

流程图
graph_builder = StateGraph(State).add_sequence(
[write_query, wait_for_user_approve, excute_query, generate_answer]
) graph_builder.add_edge(START, "write_query")

用 LangGraph 编排整个 PAL 流程。

持久化 checkpoint + 启动循环
DB_URI = "postgresql://postgres:123456@localhost:5432/langchaindemo?sslmode=disable"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
checkpointer.setup() input_thread_id = input("输入thread_id:")
time_str = time.strftime("%Y%m%d", time.localtime())
config = {"configurable": {"thread_id": f"{time_str}-{input_thread_id}-agent-demo"}} graph = graph_builder.compile(checkpointer=checkpointer) print("输入问题,输入 exit 退出。")
while True:
query = input("你: ")
if query.strip().lower() == "exit":
break
response = graph.invoke(
{"question": query},
config,
) print(response)
  • Checkpoint 存入 Postgres

  • 用户可断点续跑

  • CLI 交互友好

总结:PAL 模式的好处

1.LLM 不做逻辑执行,只负责「写程序」
2.复杂逻辑交给程序完成,结果回传给 LLM
3.SQL 查询避免安全风险
4.有明确「用户确认」步骤
5.checkpoint 持久化,支持中断恢复

运行效果示例

AI大模型应用开发-用LangChain构建PAL应用:SQL的生成与执行的更多相关文章

  1. AI大模型学习了解

    # 百度文心 上线时间:2019年3月 官方介绍:https://wenxin.baidu.com/ 发布地点: 参考资料: 2600亿!全球最大中文单体模型鹏城-百度·文心发布 # 华为盘古 上线时 ...

  2. 华为高级研究员谢凌曦:下一代AI将走向何方?盘古大模型探路之旅

    摘要:为了更深入理解千亿参数的盘古大模型,华为云社区采访到了华为云EI盘古团队高级研究员谢凌曦.谢博士以非常通俗的方式为我们娓娓道来了盘古大模型研发的"前世今生",以及它背后的艰难 ...

  3. 保姆级教程:用GPU云主机搭建AI大语言模型并用Flask封装成API,实现用户与模型对话

    导读 在当今的人工智能时代,大型AI模型已成为获得人工智能应用程序的关键.但是,这些巨大的模型需要庞大的计算资源和存储空间,因此搭建这些模型并对它们进行交互需要强大的计算能力,这通常需要使用云计算服务 ...

  4. 无插件的大模型浏览器Autodesk Viewer开发培训-武汉-2014年8月28日 9:00 – 12:00

    武汉附近的同学们有福了,这是全球第一次关于Autodesk viewer的教室培训. :) 你可能已经在各种场合听过或看过Autodesk最新推出的大模型浏览器,这是无需插件的浏览器模型,支持几十种数 ...

  5. zz独家专访AI大神贾扬清:我为什么选择加入阿里巴巴?

    独家专访AI大神贾扬清:我为什么选择加入阿里巴巴? Natalie.Cai 拥有的都是侥幸,失去的都是人生 ​关注她 5 人赞同了该文章 本文由 「AI前线」原创,原文链接:独家专访AI大神贾扬清:我 ...

  6. DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍

    DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍 1. 概述 近日来,ChatGPT及类似模型引发了人工智能(AI)领域的一场风潮. 这场风潮对数字世 ...

  7. [web建站] 极客WEB大前端专家级开发工程师培训视频教程

    极客WEB大前端专家级开发工程师培训视频教程  教程下载地址: http://www.fu83.cn/thread-355-1-1.html 课程目录:1.走进前端工程师的世界HTML51.HTML5 ...

  8. HBase实践案例:知乎 AI 用户模型服务性能优化实践

    用户模型简介 知乎 AI 用户模型服务于知乎两亿多用户,主要为首页.推荐.广告.知识服务.想法.关注页等业务场景提供数据和服务, 例如首页个性化 Feed 的召回和排序.相关回答等用到的用户长期兴趣特 ...

  9. 搭乘“AI大数据”快车,肌肤管家,助力美业数字化发展

    经过疫情的发酵,加速推动各行各业进入数据时代的步伐.美业,一个通过自身技术.产品让用户变美的行业,在AI大数据的加持下表现尤为突出. 对于美妆护肤企业来说,一边是进入存量市场,一边是疫后的复苏期,一边 ...

  10. 千亿参数开源大模型 BLOOM 背后的技术

    假设你现在有了数据,也搞到了预算,一切就绪,准备开始训练一个大模型,一显身手了,"一朝看尽长安花"似乎近在眼前 -- 且慢!训练可不仅仅像这两个字的发音那么简单,看看 BLOOM ...

随机推荐

  1. Linux下启动Oracle命令

    1.进入LInux,切换到Oracle用户权限,输入数据库密码.su - oracle    1在这里插入图片描述2.输入sqlplus "/as sysdba"    1在这里插 ...

  2. Delphi 判断字符是否是汉字

    function IsHZ(ch: WideChar): boolean; var i: Integer; begin i := Ord(ch); if (i < 19968) or (i &g ...

  3. LLM应用落地实施手册

    背景 自ChatGPT诞生以来,各个企业都开始尝试引入LLM落地实施"智能"应用,而目前并没有太多文章系统地介绍应该怎么落地实施一个基于LLM的应用,到底应该做哪些步骤.本人从20 ...

  4. MySQL 事务隔离级别:社交恐惧症的四个阶段

    MySQL 事务隔离级别:社交恐惧症的四个阶段 在数据库的世界里,数据们也有社交问题!事务隔离级别就是控制它们互相看到对方的程度... 什么是事务隔离? 想象一下,数据库是一个繁忙的餐厅,每个事务都是 ...

  5. 【Linux】3.9 网络配置

    网络配置 1 Linux网络配置原理 虚拟机NAT网络配置原理 2 查看网络IP和网关 2.1 虚拟机网络编辑器 2.2 修改IP地址 2.3 查看网关 2.4 查看windows中的虚拟网卡的ip地 ...

  6. 离线版nRF Connect for Desktop安装方法

    首先确保两台电脑都安装了nRF Connect for Desktop 先在一台能连网的电脑上安装自己想要的App 然后把APP拷贝到没有网的电脑上 从%USERPROFILE%\.nrfconnec ...

  7. 剑气纵横千行码:AI写就的设计模式侠客行助您仗剑走天涯

    烟火里的江湖旧忆 暮色里,代码侠的电动车在巷口急刹,外卖箱里的热汤晃出细响,恍惚间竟像当年工厂堡锻造炉的轰鸣.难得休息之余,他抹了把额头的汗,扶了扶常开网约车的腰,摸了摸自己晒黑的脸,偶感那颠炒粉的手 ...

  8. 多年后再做Web开发,AI帮大忙

    最近在AI辅助下做一个简单的网站开发,真是感叹AI的强大呀! 虽然多年前我做过Web前端和后端开发,但是那时候的开发没有现在这么容易入门.上手. 之前SSH(Structs2+Spring+Hiber ...

  9. FreeSWITCH Jitter Buffer 技术解析与应用指南

    一.概述 freeswitch是一款简单好用的VOIP开源软交换平台. Jitter Buffer(抖动缓冲器)是实时语音通信中解决网络抖动和延迟问题的核心技术.FreeSWITCH通过STFU(So ...

  10. CUDA原子操作

    这节主要涉及到一个多线程情况下存在的数据竞争问题 -- 多个线程同时访问共享数据时,由于没有正确的同步机制,导致数据出现不一致的情况. C/C++ 多线程中,可以通过互斥锁(mutex).原子操作(a ...