重庆大学 | 优化ChatGPT代码生成的提示词
2023-10-7 14:27:52 Author: mp.weixin.qq.com(查看原文) 阅读量:6 收藏

原文标题:Improving ChatGPT Prompt for Code Generation
原文作者:Chao Liu, Xuanlin Bao, Hongyu Zhang, Neng Zhang, Haibo Hu, Xiaohong Zhang, Meng Yan
发表状态:preprint
原文链接:https://arxiv.org/abs/2305.08360
主题类型:代码生成
笔记作者:z3verse
主编:黄诚@安全学术圈

0x01 研究对象

使用ChatGPT进行代码生成时候的有效性,可能在很大程度上受到所选择prompt的影响。本文研究了 ChatGPT 在生成代码任务中,使用各种提示工程(prompt engineering)方法对其有效性的影响。具体来说是借助 CodeXGlue 数据集 [1] 评估 ChatGPT 在两项自动化代码生成任务(包括T2C和C2C)中的能力。

prompt engineering 与 对应的 CodeBLEU 分数:

  1. basic prompts:
    1. “write a Java method that” + 对于具体T2C任务的自然语言描述   --> 22.76分
    2. ”translated C# code into Java code:” + 对 C2C 任务的代码 --> 39.37分
  2. 进阶 prompts:
    1. 利用多步优化的思维链策略(chain-of-thought strategy)人工设计 prompt,根据 ChatGPT 的反馈进行多步优化,进而提升代码生成任务的有效性。随后 T2C 任务提升至 50.18 分,C2C任务提升至 48.80 分。

使用ChatGPT进行代码生成的两种生成方式

  • Text-to-Code (T2C):用自然语言(NL)描述来表达开发人员的需求。例如:开发人员要求 "将Java中的整数变量n转换为字符串",然后ChatGPT给出”String s = Integer.toString(n)”的回答
  • Code-to-Code (C2C):将现有的代码片段从一种编程语言翻译成另一种编程语言(有点像针对代码的翻译任务)。例如:把某段代码从 C# 转换为 Java

[1] Codexglue: A machine learning benchmark dataset for code understanding and generation,

0x02 关键问题

如何设计 prompts 才能使 ChatGPT 生成更好的代码?

0x03 研究方法

3.1 评价数据集与指标

针对两类代码生成任务:

  1. T2C
  2. C2C:在本文中,这个任务是完成 C# 代码 到 Java 代码的转换

用于评估的 dataset

  1. T2C 数据集:CodeXGLUE中的CONCODE。该数据集从 GitHub 收 集了约 33k 个 Java 仓库,包括 100k 个训练数据、2k 个有 效数据和 2k 个测试数据。数据中的每个实例都是由三个 元素组成的元组:1) 代码片段(Code Snippet),它是代 码生成的基本事实;2) 自然语言描述(Natural Language Description),它是从代码片段的 Javadoc 中提取的,用 于生成输入;3) 代码环境(Code Environment),它描述 了代码片段工作的类文件(即程序上下文),包括类名、 类路径、成员变量和成员函数的签名。
  2. C2C 数据集:数据中的每个实例都包含 一对用 C# 和 Java 编写的代码片段,它们具有相同的功能 ,但用不同的编程语言实现。在本研究中,我们将 Java 代 码片段视为 T2C 数据集的生成目标,并将 C# 代码片段作 为输入。

评估指标:BLEU 和 CodeBLEU(总体评价指标)

  1. BLEU 是衡量不同长度代码片段生成准确度的常用指标。具体来说,BLEU = BP ∗ e^((logP1+...+logPn)/n) 其中,BP 是简短度惩罚值,如果生成的代码比标准的答案(ground-truth)长,则该值等于 1。否则,它等于两个代码长度之比。Pi 是生成代码中出现的 i-grams 包与基本值之间重叠的度量。
  2. CodeBLEU 是 BLEU 的一种变体,它也考虑代码生成的语法和语义数据流的正确性。它与 BLEU 相似,但它是基于一组代码词组而非自然语言 n-gram 来计算精度分数的。一般来说,CodeBLEU 是生成的代码与ground-truth之间的词法、抽象语法树和数据流匹配度的加权平均值。

3.2 Prompt Design

1. Methods for Prompt Design

思维链(CoT)提示是一种关键策略,它通过引导 LLM 在给出最终答案之前完成一系列中间步骤,从而使 LLM 能够解决问题。一般来说,为了指导 ChatGPT 完成代码生成任务,我们采用 CoT 策略分两步设计提示:

  1. Prompt Description:我们首先分析代码生成任务的需求,以自然的方式设计基本提示。然后,我们将基本提示提供给 ChatGPT,并询问 ”how to improve the prompt?”,根据 ChatGPT 的建议进一步改进提示。
  2. Multi-Step Optimizations:我们在相关数据集的训练数据中的一些样本上测试第一步的提示,分析生成性能与ground-truth,并通过向 ChatGPT 提供一系列新的提示来不断优化生成结果。表 II 显示了 ChatGPT 在使用表 I 中 设计的不同提示组合时的代码生成表现。

TABLE I:为两个代码生成任务设计的不同类型的提示。请注意,#{nl}、#{cn}、#{mv}、#{mf} 和 #{code} 分别代表类名、成员变量、成员函数和代码变量。分别代表类名、成员变量、成员函数和代码变量,这些变量将由数据集的实际输入填充。

TABLE II:在每个生成任务的训练数据中随机抽取的 100 个样本上测试表 I 中的不同提示组合。注意,p5(api) 表示我们只使用了提示 p5 的 api 部分。

Prompt Design for Text-to-Code Generation

Prompt Description:”write a Java method that + #{NL}”(TABLE I-P1)

Multi-Step Optimizations:

  1. 先用 P1 询问 ChatGPT:”how to improve the prompt: write a Java method that converts int to string”。ChatGPT 告诉我们:“通过提供更具体的方法行为细节、编程上下文和输入/输出示例,我们可以创建一个更清晰、信息量更大的提示,帮助指导生成一个设计良好的 Java 方法。”
  2. 正好 CONCODE 数据集中的 Code Environment 可以作为细节信息,因此设计了 P2 这句提示词:“remember you have a Java class named + ’#{CN}’, member variables + ’#{MV}’, member functions + ’#{MF}’”
  3. 因为ground-truth在四个方面进行了预处理,所以作者设计了 P3 来促使生成的结果可以取得更好的分数
  4. 通过比较生成的代码和ground-truth,我们注意到 ChatGPT 可能会生成不同 API 和异常处理代码。我们自然会要求 ChatGPT 根据其响应和用户的具体要求重新生成代码。为了提取对 API 和异常处理的要求,我们设计了如下prompt来询问ChatGPT  ”list the used methods with names only in the following Java methods and do not explain: #{Code}” and ”does the code contain exception handling? + #{Code}” 然后,我们编写脚本,根据 API(即名称列表)和异常处理(即真或假)的要求对响应进行分析。有了这两项要求,我们就用行为提示取代了任务提示:"编写一个 Java 方法 #{that calls ...} with[out] exception handling to #{NL}"(表 I-P5)。
Prompt Design for Code-to-Code Generation

Prompt Description:”translate C# code into Java code: #{Code}” (Table I-P1).

值得注意的是 C2C 任务在最初就有 39.37 的得分,并且C2C任务不涉及到对相关类等情况的处理。因此后续的优化得分差异不大

Multi-Step Optimizations:

  1. ChatGPT 会在 C# 代码后生成注释,但ground-truth删除了所有注释。因此,作者在任务提示中添加了一个简单的处理 prompt P3。
  2. ChatGPT 能够理解提示中的 markdown 语法。因此,在任务提示中,作者将 #{Code} 改为"'#{Code}'",作为更新后的任务 prompt(表 I-P4)
  3. 因为同样涉及对 API 和程序异常处理的处理,因为作者设计了 P5
小结

通过组合不同的 Prompts,可以看到BLEU和CodeBLEU分数并不是同时增长的。例如在C2C任务中P5就有着负面的影响。因此作者设计实验来对4个问题进行了探究。

0x04 实验设计

RQ 1:为 ChatGPT 设计的提示效果如何?

目的:证明 Prompt 设计方法的有效性

测试基线 ChatGPT-task:仅使用 P1 ChatGPT-detail:P1-P4 的组合 ChatGPT-behaviour:在 ChatGPT-detail 基础上加入 P5

结果:ChatGPT-behaviour在T2C任务上有着显著提升。而ChatGPT-detail在C2C任务上的表现更好。

RQ 2:简洁性要求对 ChatGPT 有何影响?

因为ChatGPT生成的代码仍然比ground-truth更为复杂,所以作者在这里探索在生成目标前添加 "concise" 一词,对生成结果的影响。例如将P5 修改为 ”write a concise Java method ...”

结果:简洁性要求对 T2C 生成有用,但对 C2C 生成无用。

RQ 3:会话设置对 ChatGPT 有何影响?

默认情况下,我们为每个提示打开一个单独的会话,并与 ChatGPT 进行交流。相比之下,我们可以通过 一个连续的会话来进行交流。这样,ChatGPT 就能从上下文中学习,并为代码生成任务生成更好的反应。因此,本研究问题旨在分析会话设置的影响。

方法:在与 ChatGPT 的通信过程中,我们使用一个会话 为多个提示生成代码。当数量达到上限时,再发出的提示 将不会得到回应。然后,我们开始另一个新的会话。这样 ,我们就能确保每个会话都得到充分利用,而 ChatGPT 也能更好地理解上下文。我们知道,在一个会话中,之前 的提示的上下文信息量会比较低。因此,研究会话设置对 代码生成性能的影响毫无意义。

结果:连续会话有利于 C2C 生成任务,但对 T2C 生成任务没有改善。因此,单个会话更适合使用设计好的提示生成 T2C。

RQ 4:生成随机性对 ChatGPT 有何影响?

众所周知,ChatGPT 每次生成的结果是随机的,那么文章中的结果是否会存在较大偏差?

结果:由于设计的提示中描述了特定的指令,生成随机性对代码生成任务的影响很小。

RQX:其他分析结果

  1. 在生成 T2C 时,用我们设计的提示引导 ChatGPT 的效果优于最先进的微调 LLM,但在生成 C2C 时,由于提示中表达的上下文信息有限,其效果 较差。
  2. CodeBLEU 得分高,生成的代码就一定正确吗?与 T2C 任务相比,使用最佳prompt的 ChatGPT 在 C2C 任务中显示出更好的正确性,因为 NL 描述并不严格。
  3. 在实验数据集上,ChatGPT 生成的代码没有严重的错误或安全漏洞,但确实存在很多代码的不良习惯,开发者应当及时对其进行优化和修复。(使用SonarQube进行扫描之后得出的结论)

0x05 研究总结

在这篇文章中,作者为 ChatGPT 设计并优化了两类代码生成任务的prompts语句,分别是文本转代码和代码间的转换。实验显示,在广受欢迎的 CodeXGlue 数据集上,当请求 ChatGPT 生成代码时,本文的prompts表现出色。作者也深入探讨了影响代码生成任务引导语设计的关键因素,并对比了顶尖提示与最前沿的微调 LLM 的表现。同时,作者还对 ChatGPT 生成的代码的准确性和质量进行了评估。

0x06 研究局限

  1. 指定“角色”对T2C和C2C任务的影响?无论是在 “Prompt Engineering Guide”[1] 还是 “PENTESTGPT: An LLM-empowered Automatic Penetration Testing Tool”[2] 中都提到指定角色可以使 prompts 在 T2C 任务中有着不错的表现。但本文在设计 prompt 的时候并没有考虑这个方面。

[1] https://www.promptingguide.ai/applications/coding [2] https://mp.weixin.qq.com/s/STSqHgBIn8782vaL7ldiJg

0x07 文章亮点

这篇文章刚好对我在设计prompt时候观察到的几个现象进行了分析,例如:对每个T2C任务使用一个 session 窗口好,还是使用一个 session 窗口处理一系列的T2C任务号。其实在实践和测试中,我也倾向于使用一个session处理一个T2C task,因为这种方式输出的基本都是我想要的结果。但是后者则表现欠佳。

0x08 Other

其实在阅读这篇文章的时候我最想Get一个实践中极佳的Prompt,但是读完之后并没有获取到预期的内容。所以我想在本文的最后给出我针对 T2C 任务设计的1个 basic prompt。该prompt在实际中使用起来效果还不错,放在这里供大家参考。

当然,本文中提到的 P2 和 P5 可以在实际中,根据不同的情况和下面的 Prompt 进行组合使用。

You are a world-class Python developer with an eagle eye for unintended bugs and edge cases. And you can teach junior developers how to code. Don't explain the code, just write all of your code in a single block.

I wish you could use Python and the `XXX` package, write a code that + #{NL}

一个示例

You are a world-class Python developer with an eagle eye for unintended bugs and edge cases. And you can teach junior developers how to code. Don't explain the code. Just write all of your code in a single block. 

I wish you could use Python and the `requests` package, to write a code that fetches the content of the website `example.com` and prints the title of the page. Please be careful to handle exceptions such as network timeouts.

0x09 作者

刘超: 重庆大学,研究兴趣包括基于深度学习/基于搜索的模型来理解自然/编程语言

  • 个人主页:https://liuchaoss.github.io/
  • Google Scholar主页:https://scholar.google.com/citations?user=scet0mIAAAAJ&hl=en
安全学术圈招募队友-ing 
有兴趣加入学术圈的请联系 secdr#qq.com

文章来源: https://mp.weixin.qq.com/s?__biz=MzU5MTM5MTQ2MA==&mid=2247489750&idx=1&sn=f55c1cada34648f98ec33997a51e6301&chksm=fe2ee75dc9596e4b7c2a91ff5d7658fb2894b27156651528db7bc76c04c18758fcff1c87dee6&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh