Jiang, X., Dong, Y., Wang, L., Fang, Z., Shang, Q., Li, G., Jin, Z., & Jiao, W. (2024). Self-Planning Code Generation with Large Language Models. ACM Transactions on Software Engineering and Methodology, 33(7), Article 182.
研究背景与动机
研究背景
大型语言模型在代码生成任务上已展现出强大能力,但在处理复杂的人类意图时仍面临挑战。人类在解决复杂编程问题时,通常会先进行规划,将问题分解为多个子问题并安排解决步骤,然后再进行具体实现。然而,现有的代码生成方法(如直接生成或基于思维链的方法)未能有效引入这种规划机制,导致在复杂任务上表现不佳。
研究动机
本文旨在将“规划”引入代码生成过程,以帮助LLM更好地理解复杂意图,降低问题求解的难度。作者提出了一种自规划代码生成方法,通过两阶段(规划阶段与实现阶段)的方式,使LLM能够自主生成解决方案步骤,并依此生成代码。
研究问题
如何在不依赖大量标注数据的情况下,利用LLM自身能力进行规划,并基于规划生成高质量、可读性强、鲁棒的代码。
论文核心方法和步骤
方法概述
自规划代码生成分为两个阶段:
- 规划阶段:使用少量示例构建提示,引导LLM从意图中抽象并分解出解决方案步骤(即“计划”)。
- 实现阶段:将规划阶段的输出(计划)与原始意图拼接,作为输入引导LLM生成最终代码。
数学建模
该方法可形式化为如下概率模型:
$$
\mathcal{P}(z|x,C) = \underbrace{\mathcal{P}(z|y,x)}{\text{实现阶段}} \cdot \underbrace{\mathcal{P}(y|x,C)}{\text{规划阶段}}
$$
其中:
- $x$ 是意图,
- $C$ 是提示(包含少量意图-计划对),
- $y$ 是生成的计划,
- $z$ 是最终生成的代码。
提示构建原则
- 计划以编号列表形式组织;
- 每一步表示一个易于实现的子任务,使用动词开头的祈使句;
- 步骤应简洁、高层,避免具体实现细节;
- 可包含条件与循环结构。
实施细节
- 使用 code-davinci-002 作为基础模型;
- 规划阶段采用贪心搜索生成一个计划;
- 实现阶段根据计划生成代码;
- 提示示例数量通常为 4 或 8。
实验结果与结论
实验设置
- 基准数据集:HumanEval, MBPP, HumanEval-X, MBPP-ET 等;
- 评估指标:Pass@k, AvgPassRatio, CodeBLEU;
- 对比方法:Direct, Few-shot, Code CoT, Ground-truth Planning 等。
主要结果
- 性能提升:自规划方法在 Pass@1 上相比 Direct 提升高达 25.4%,优于 Code CoT(提升 11.9%);
- 多语言适应性:在 Python, Java, Go, JavaScript 等多种语言上均表现优异;
- 问题复杂度影响:自规划在处理高复杂度问题时优势更显著;
- 代码质量:人工评估显示自规划生成的代码在正确性、可读性和鲁棒性上均优于基线方法。
结论与意义
- 自规划代码生成是一种涌现能力,主要在大规模LLM中显现;
- 通过规划,LLM能更好地分解复杂问题,生成更结构化和可维护的代码;
- 该方法无需训练,仅需少量示例即可实现,具有高数据效率和低使用门槛;
- 为将软件工程中的需求分析与分解方法引入LLM代码生成提供了新思路。
未来方向
- 探索自动化提示生成与优化;
- 将自规划方法扩展至更复杂的软件工程任务,如系统设计与需求分析。