这篇适合谁
适合想让大模型算日期、算数这类题目更可靠的读者。读完你能配好 LangChain 和 OpenAI 的调用方式,用程序辅助提示让模型写 Python 代码,再由解释器算出答案。
PAL 是什么
PAL(程序辅助语言模型,Program-Aided Language models)由 Gao 等人在 2022 年提出[1]。它让大模型读取自然语言问题,并把推理的中间步骤写成程序。思维链提示靠自由文本推导答案,PAL 则把解题步骤交给 Python 解释器这类编程运行时去执行[1]。
这篇的例子用 LangChain 和 OpenAI GPT-3 搭一个小应用:读入问题,让模型生成代码,再用解释器给出答案。例子针对的是需要日期推算的问题,提示里的示例取自 reasoning-machines/pal 项目在 GitHub 上的日期理解提示文件[1]。
准备
代码导入了 openai、dateutil、LangChain 的 OpenAI 封装和 dotenv,所以环境里要能装上这些包[1]:
import openai
from datetime import datetime
from dateutil.relativedelta import relativedelta
import os
from langchain.llms import OpenAI
from dotenv import load_dotenvAPI 密钥从环境变量 OPENAI_API_KEY 读取,示例把它同时设给 openai 客户端和 LangChain[1]。
这个例子的关键在于提示里的示例。示例把问题写成注释、把解题过程写成代码,模型会照着这个格式续写,所以示例的写法直接决定它输出的代码能不能用[1]。读者如果换成自己的问题,最好也准备几组同样格式的示例,而不是只给一句问题。
上手步骤
第一步,配置环境。先调用 load_dotenv(),然后按示例设置密钥[1]:
load_dotenv()# API configuration
openai.api_key = os.getenv("OPENAI_API_KEY")# for LangChain
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")第二步,创建模型实例。示例把 temperature 设为 0,让输出尽量稳定[1]:
llm = OpenAI(model_name='text-davinci-003', temperature=0)第三步,准备提示和问题。问题是「今天是 2023 年 2 月 27 日,我正好在 25 年前出生,我的出生日期是多少(MM/DD/YYYY)?」,赋给 question 变量[1]:
question = "Today is 27 February 2023. I was born exactly 25 years ago. What is the date I was born in MM/DD/YYYY?"提示里放了好几组示例。每组先用注释写出问题,再用 Python 代码算出答案。第一组示例是这样的[1]:
# Q: 2015 is coming in 36 hours. What is the date one week from today in MM/DD/YYYY?
# If 2015 is coming in 36 hours, then today is 36 hours before.
today = datetime(2015, 1, 1) - relativedelta(hours=36)
# One week from today,
one_week_from_today = today + relativedelta(weeks=1)
# The answer formatted with %m/%d/%Y is
one_week_from_today.strftime('%m/%d/%Y')第四步,调用模型并打印输出[1]:
llm_out = llm(DATE_UNDERSTANDING_PROMPT.format(question=question))
print(llm_out)模型会输出什么
对这个问题,模型返回的是一段 Python 代码。示例中的输出如下[1]:
# If today is 27 February 2023 and I was born exactly 25 years ago, then I was born 25 years before.
today = datetime(2023, 2, 27)
# I was born 25 years before,
born = today - relativedelta(years=25)
# The answer formatted with %m/%d/%Y is
born.strftime('%m/%d/%Y')第五步,用 exec 执行这段代码[1]:
exec(llm_out)
print(born)运行后输出 02/27/1998[1]。
为什么这样做
普通的思维链让模型用文字一步步算,算术一旦出错就很难察觉。PAL 把计算放进解释器:模型只负责把问题翻译成代码,日期加减由 relativedelta 完成[1]。
PAL 的流程可以拆成三步:模型把问题写成程序,解释器运行程序得到结果,最后把结果交给使用者。上面的例子正好对应这三步:提示让模型生成代码,exec 执行代码,print 输出日期[1]。计算由解释器完成,而不是由模型的文字推理完成。
注意事项
exec会运行模型返回的任意代码。示例适合本地练习,不要直接放到线上环境里跑。- 示例用的是
text-davinci-003和 LangChain 的 OpenAI 封装。换成其他模型或接口时,要先确认参数和调用方式是否一致。
如果想把这个思路用到别的题目上,关键是两点:提示里要有能让模型写出可执行代码的示例,运行代码的环境要能拿到所有需要的库[1]。
下一步
更多细节和示例代码可以去 reasoning-machines/pal 的 GitHub 仓库查看[1]。
本文改编自 DAIR.AI《Prompt Engineering Guide》中的 PAL 页面[1],原文以 MIT 许可证发布。
来源
- 1PAL(程序辅助语言模型)DAIR.AI Prompt Engineering Guide (MIT)
引用本页: 程序辅助提示(PAL):让模型写代码来算. TellWorld, https://www.tellworld.net/zh/practice/practice-prompt-pal. 更新于 2026-11-14