G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

admin 2024年2月16日00:04:43评论12 views字数 3995阅读13分19秒阅读模式

 最近看了一些LLMs与静态分析结合的文章,包括使用LLMs进行代码总结、注释补充等等,因此想稍微总结并测试一下prompt的正确写法。

1. 测试目标

    测试目标和最近在做的工作有关系,主要是想测试GPT-4在程序summary上面的效果如何。首先明确一下希望GPT-4抽取出来的结果:

    对于下面这样一个函数,我希望GPT能够帮我抽取出来这个函数中与buffer 访问相关的所有信息,例如memcpy等等。

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

因此,我希望GPT能抽取出来的结果是:

“””Condition1: <#0 && #2 && #1 != 0 && #3> <Memcpy stmts: <memcpy(*out, data, datalen);>Params: -|*out, data, datalen|-Relate to args: -|#2, #0, #1|->”””

其中,#+num代表着对应函数的第几个参数

2. 简单测试

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

      得到如下结果

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

    可以看到,虽然我们给出了所谓的Desired format,并且给出了角色“expert in the area of static analysis”, GPT-4依然说出来了很多废话,虽然抽取的结果还是比较准确。

并且一旦遇到复杂一点点的例子,就会开始胡言乱语,比如下面这个例子:

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

依然很简单,只是包括了一个Loop在里面

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

    GPT-4的抽取结果就不正确了,在输出结果的最后一行,GPT并没有将datalen正确抽取成“#+num”的格式,而是留了一个datalen-=2在结果中,这样的例子还有很多。这种结果肯定不能直接用来辅助静态分析的。

3. Prompt优化

    于是我看了一些论文&博客,来寻找优化prompt的方法。

在“ChatGPT Prompt Engineering for Developers[1]”中吴恩达提到了 Prompt 的两大原则:

  • 编写清晰且具体的指令(Write clear and specific instructions);

  • 给模型思考的时间(Give the model time to think)。

我个人的理解是,对于prompt,要给出更多、更细化的例子,并且给出来例子的原理供模型思考。例如在论文 “The Hitchhiker's Guide to Program Analysis: A Journey with Large Language Models[2]” 中使用的prompt如下图所示

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

一个截屏都放不下,不过可以看出来,这个Prompt长并且详细。首先,这个prompt将需要GPT处理的情况划分成了两个Type, Type A 和Type B。随后对这两个Type都给出了两个例子,并且最重要的是对于这些例子都做出了详细的解释,告诉GPT“思维链”是什么。

Chain-of-Thought

    "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models [3]" 这篇文章里也提到了思维链的重要性,在数学运算、代码编写等领域,提供“思维链” 都能够提升1-2倍的准确率。

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

因此回到我们自己的例子进行测试,这次prompt写的很长,这里只进行简要描述

As a Linux kernel specialist, your task is to Extract and summarize the important entities mentioned in the function below. First extract all “memcpy” function statements, then extract all parameters, then use data flow analysis to trace back to the beginning of the function, and out put all the statements related to the parameters.Desired format:Condition1: <> {Memcpy stmts: <comma_separated_list_of_company_names>Params: -||-Related stmts: -||-}Condition2: <> {Memcpy stmts: <comma_separated_list_of_company_names>Params: -||-Related stmts: -||-}If you encounter an call like int sm4_cbc_sm3_hmac_decrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen), you should go inside of the function body for more analysis.Type A. Trace back to parameters: Consider a scenario where a variable is used after a function check, such as:“””Int bmc_init(SM4_CBC3 *ctx, size_t inline, int* in){  memcpy(ctx->mac + ctx->maclen, in, inlen);}”””Here, you should trace it as :“””Condition1: <> <Memcpy stmts: <memcpy(ctx->mac + ctx->maclen, in, inlen)>Params: -|ctx->mac + ctx->maclen, in, inlen|-Related stmts: -|#0->mac + #0->maclen, #2, #1|->”””Here, the #0 means it is the first param of the current function . Another variant (Type A') can be the case:....Here, you should trace it as :.....TypeB: There are dataflow between memcpy and parameters......TypeC: There are Loops between memcpy and parameters......

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

这次废话少了很多,结果也好了很多,但是抽取结果并不准确, 在condition和路径抽取上,产生了很多错误。经过多次修改prompt也没能解决。

LLM self-critique

于是我想要尝试一下LLMs的自检测功能,也就是告诉LLMs需要注意检查的条目,让LLMs自行检测自己的输出是否正确,并输出一个新的结果。

对于这一点,实际上有很多争论,例如“GPT-4 不知道自己错了!LLM 新缺陷曝光,自我纠正成功率仅 1%[4]”里面就表示,对于图形着色问题,LLM并不能完成自我修复,并且“越修越差”。只有在外部的检测器提供指导后,才能使效果有所提升。

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

但是无论如何还是自己测试一下,我选择了LLMs输出中容易出错的条目总结下来,例如需要检测condition和path是否匹配等等,并写成prompt。

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

这次的结果可以说是非常完美了, 虽然有些丑陋:( 

同时,也可以看到GPT-4输出了自己的思维链条, 也是很符合静态分析的需求。

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

Results

后面我又做了更多的测试,列出来一个小表格。当然只是自己测试,参考意义不大。

测试样本 测试函数 正确数量 自我检查后正确数量
gmssl 5 2 4
openssl 5 3 5

3. 其他技巧

当然,gpt有时候还是会胡说,包括我们只需要GPT输出结果,但是GPT同时也说出了很多无关紧要的话,例如“Ok,let's summerize it”等等。这些小问题也有很多博客提出了解决方法,在编写 Prompt 的时候,如果使用“{}”、“"""”、“<tag>” 之类的分隔符来分割 Prompt 中的指令、上下文等,可以有效帮助 GPT 模型更好地理解输入。

再或者,给出一个模版让GPT去续写,参考OpenAI官方教程[5]

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

如果在prompt里面加入一个import,让GPT续写,则会消除掉前面的一堆废话

G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

还有很多别的技巧,例如常说“step by step”等等。当然,也有很多开发框架例如LangChain能够维护模版、提升prompt质量等等,后续或许我会做更多的尝试。

[1] “ChatGPT Prompt Engineering for Developers”: https://www.deeplearning.ai/short-courses/chatgpt-prompt-engineering-for-developers/

[2] The Hitchhiker's Guide to Program Analysis: A Journey with Large Language Models https://arxiv.org/abs/2308.00245

[3] Chain-of-Thought Prompting Elicits Reasoning in Large Language Models:  https://arxiv.org/abs/2201.11903

[4] GPT-4 不知道自己错了!LLM 新缺陷曝光,自我纠正成功率 1% : https://www.ithome.com/0/726/667.htm

[5] OpenAI官方教程 : https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api

原文始发于微信公众号(安全研究GoSSIP):G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月16日00:04:43
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   G.O.S.S.I.P 阅读推荐 2023-10-31 如何写好 Prompt,让 GPT适用于静态分析http://cn-sec.com/archives/2164129.html

发表评论

匿名网友 填写信息