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. Docker之一简介

    什么是Docker Docker是Google使用go语言进行开发的,对进程进行封装隔离,始于操作系统层面的虚拟化技术. 因为隔离的进程独立于宿主机和其它的隔离进程,因此成为容器 Docker在容器的 ...

  2. AntennaMagus中文培训教程

    AntennaMagus中文培训教程 链接:https://pan.baidu.com/s/1Svc613HvfUtIMB3uOXILkg 提取码:0s2c

  3. Oracle DB 关于CONNECT、RESOURCE 和DBA 角色权限

    授予角色的语法: grant <object/system privilege> to <role name>; 一般情况下,在新建数据库用户后,都会习惯性的给用户授权CONN ...

  4. 大模型提示词(Prompt)模板推荐

    只有提示词写得好,与大模型的互动才能更高效.提示词不仅仅是与AI对话的起点,更是驱动模型产生高质量输出的关键因素.本文将介绍大模型提示词的概念.意义,并分享一些实用的提示词模板,帮助AI玩家更好地利用 ...

  5. FastAPI依赖覆盖与测试环境模拟

    title: FastAPI依赖覆盖与测试环境模拟 date: 2025/04/10 00:58:09 updated: 2025/04/10 00:58:09 author: cmdragon ex ...

  6. CPU 和GPUskinning对比

    CPU: 比如广泛的设备兼容性,比如上面说的精确逻辑处理,比如可以根据距离对Skinning进行LOD(如近距离角色每秒30帧Skinning,远距离角色每秒15帧Skinning),比如多Pass渲 ...

  7. springboot整合log4j

    一.默认名log4j2-spring.xml,就省下了在application.yml中配置 <console name="Console" target="SYS ...

  8. 🎀腾讯云nodejs SDK打包体积过大吐槽事件

    简介 2025年2月1日有位开发同学batchor在GitHub上提出了issue(你们是把***打包了吗?)对腾讯云Node.js的SDK打包体积过大进行吐槽(言语偏贴吧风格略显激进),SDK打包体 ...

  9. .NET 原生驾驭 AI 新基建实战系列(四):Qdrant ── 实时高效的向量搜索利器

    向量数据库作为一种专为现代AI应用设计的新型存储技术,能够高效地管理和检索高维数据,成为智能应用开发中的关键基础设施.本文将深入探讨 Qdrant 这个开源.高性能的向量数据库,重点介绍其如何与 .N ...

  10. stackbd:在一个块设备上堆叠另一个块设备

    stackbd 是一个虚拟的块设备,它作为另一个块设备的前端,如 USB 闪存盘或循环设备.它将I/O请求传递给底层设备,同时它打印请求信息用于调试.它还有可能修改请求. 堆叠块设备(stackbd) ...