在大型语言模型(LLM)处理数值推理任务时,Chain-of-Thought(CoT)提示通过生成中间自然语言推理步骤显著提升了性能,但 LLM 自身执行复杂计算时仍易出错。Program-of-Thoughts(PoT)提示则创新地将推理过程转化为可执行的 Python 代码,由外部解释器负责计算,从而分离“思考”(reasoning)和“计算”(computation),在 GSM8K、FinQA 等基准上平均超越 CoT 12%,最高达 15%以上。这种设计不仅提高了准确性,还增强了可验证性和组合性,适用于数学、金融等数值密集场景。
PoT 的核心优势在于职责分离:LLM 只需生成逻辑正确的代码框架,精确计算交给 Python 解释器,避免了 LLM 在多步算术中的幻觉或计数错误。例如,在 GSM8K 数据集的 few-shot 设置下,Codex(基于 GPT-3)使用 PoT 的准确率达 94.1%,而 CoT 仅为 82.1%;zero-shot 下提升同样显著,达 69.3% vs. 58.0%。论文在 5 个数学数据集(GSM8K、AQuA、SVAMP、TabMWP、MultiArith)和 3 个金融 QA 数据集(FinQA、ConvFinQA、TAT-QA)上验证,PoT 在 few-shot 和 zero-shot 均获平均 12% 提升。结合 self-consistency(多次采样取多数投票),PoT 进一步刷新 SOTA,如 GSM8K 上达 97.6%。[1] 这种提升源于代码的可执行性:即使 LLM 推理路径正确,CoT 常因计算失误失败,而 PoT 通过解释器自验证确保结果精确。
落地 PoT 需要精心设计提示模板、执行流程和监控机制。首先,few-shot 提示:选取 3-8 个示例,每个包含问题 + 带注释的 Python 代码(如用 # 分隔自然语言解释)。模板示例:
Question: [问题]
# Python code
total = 初始值
# 逐步计算...
ans = 最终结果
Zero-shot 提示简化指令:“Write Python code to solve this. Use # for comments. Return 'ans'.” 温度设为 0.0(贪心)或 0.8(采样),采样 10-40 次用于 self-consistency。代码生成后,捕获非代码行(以 # 开头)作为注释,执行纯代码部分,使用 Python 3.8+ 和 SymPy 支持符号计算。
执行流程清单:
- LLM 生成代码(max_tokens=512,避免过长)。
- 解析代码:提取可执行块,替换变量为问题中具体数。
- 解释器执行:try-except 捕获 SyntaxError 或 NameError,重试 3 次(温度微调)。
- 自验证:多次执行取 mode(众数),阈值一致率 >80%。
- 组合性扩展:多步任务先 PoT 计算中间结果,再 CoT 解释(如时间格式转换)。
工程参数推荐:
- 模型选择:优先代码模型如 Codex/GPT-4o、DeepSeek-Coder;fallback 小模型 + CoT。
- 采样参数:self-consistency 时 n=20-40,top_p=0.95。
- 超时阈值:代码执行 <5s,超时回退零样本 CoT。
- 错误率监控:语法错误 <5%(通过预热提示优化);逻辑错误用单元测试验证 10% 样本。
- 成本优化:简单问题预判(关键词计数)用 CoT,复杂用 PoT;缓存常见模式代码。
风险与回滚:LLM 可能生成无效代码(47% 变量错误,33% 逻辑错),监控指标:执行成功率 >90%,否则切换 CoT。生产中集成 LangChain 或 LlamaIndex 工具链,实现无缝调用。
PoT 标志着提示工程从纯语言向工具增强演进,未来可扩展到更多领域如科学模拟。实际部署中,从基准验证起步,逐步调优提示,实现 10-20% 推理提升。
资料来源:
[1] Chen et al., Program of Thoughts Prompting, arXiv:2211.12588.
GitHub: https://github.com/wenhuchen/Program-of-Thoughts (数据集、代码)。