《陈雅菲-打造LLM高质量代码生成的神兵利器.pdf》由会员分享,可在线阅读,更多相关《陈雅菲-打造LLM高质量代码生成的神兵利器.pdf(36页珍藏版)》请在三个皮匠报告上搜索。
1、打造LLM高质量代码生成的神兵利器陈雅菲 中兴通讯演讲嘉宾陈雅菲中兴通讯 公司资深软件架构师 资深敏捷教练深耕软件领域20余年,拥有丰富的大型软件项目架构、设计与开发经验,在软件设计开发理论与实践上均有独到见解。长期致力于敏捷技术实践指导与推广,多次获得公司十佳敏捷教练称号。目前研究方向是LLM辅助设计编码。目 录CONTENTS1.LLM代码生成面临的问题2.问题的解决思路与方案3.实践情况与效果评估4.总结&展望LLM代码生成面临的问题PART 01LLM代码生成面临的问题软件开发目标之一高效输出高质量代码编码人需要充分理解设计才能编写出高质量的代码好的设计设计如何让LLM充分理解设计问题
2、的解决思路与方案PART 02解决思路语义模型驱动设计(Semantic Model Driven Design)一种应对高软件复杂度的设计方法抽象出针对特定问题领域的语义模型采用结构化表达描述语义模型不同LLM有不同使用约束根据不同使用约束提炼提示模式需求测试(UT)设计编码SMDD解决方案:SMDD需求测试(UT)设计SMDD编码语义模型驱动设计(SMDD)总览匹配的人员能力思想通过构建语义模型驱动出好的设计语义模型构建三步法DSL语义模型的语义与问题领域的核心需求相匹配语义模型提供的框架具备可组合性原则语义模型驱动设计(SMDD)框架深入分析特定问题领域、挖掘问题领域核心需求核心需求使用
3、语义模型构建语义模型构建三步法三步法,从核心需求抽象出语义模型语义模型,其语义要与特定问题领域的核心需求相匹配基于语义模型提供一套DSLDSL(Domain-Specific Language,领域特定语言)设计核心需求特定问题领域分析语义模型构建三步法抽象匹配语义模型语义模型是提供了与问题领域核心需求相匹配的语义、框架具备可组合性的计算模型原子原子最简单、最基本的实体组合方法组合方法把原子组合起来构成更复杂实体的方法命名复杂实体的手段,命名后的复杂实体可以像原子一样通过组合方法组合成更为复杂的实体抽象手段抽象手段解决方案:提示模式需求测试(UT)设计SMDD编码提示模式:不同使用约束、不同提
4、示模式交互方式:单轮对话+有代码上传提示模板:每个场景对应一个提示模板提示模式二交互方式:多轮对话+无代码上传提示模板:每轮对话对应一个提示模板提示模式一。是否支持多轮对话信息安全、合规要求LLM的使用约束提示模式一:多轮对话+无代码上传请按如下建议修改代码:1.aaa2.bbb.请按如下建议补充代码:1.xxx2.yyy.请你自己检查一下代码是否完整、正确地实现了这套DSL描述。先不要改代码,先告诉我检查结果。请给出目前所有代码。请你采用等价类与边界值的测试设计方法,使用JUNIT4生成所有类的单元测试代码,注意每个类对应一个测试类、每个测试用例一个测试方法。请按如下建议修改代码:1.aaa
5、2.bbb.请按如下建议补充代码:1.xxx2.yyy.请你自己检查一下单元测试代码是否完善。先不要改代码,先告诉我检查结果。请给出目前所有单元测试代码。你是一名.资深程序员,请编写程序实现一个系统:1.系统的输入是.,系统的输出是.。2.实现如下面的Markdown表格描述的一套DSL,注意可组合性:|核心概念|概念语义|原子/组合|形式化表达|-|-|-|-|.|.|.|.|.|.|.|.|.|请先不要给出代码。如果你对于这一套DSL描述有疑问,特别是Markdown表格概念语义列中的内容,请向我提问,我来回答你。请先不要给出代码。你确定没有疑问了吗?请生成代码。使用初始Prompt确认L
6、LM正确理解了Prompt内容使用LLM生成代码审查LLM生成的代码执行必要的修改或补充使用LLM生成单元测试代码审查LLM生成的单元测试代码执行必要的修改或补充提示模式二:场景代码生成代码缺陷修复全量代码生成增量代码生成单元测试代码生成无依赖代码的单元测试代码生成有依赖代码的单元测试代码生成交互方式:单轮对话+有代码上传提示模板:每个场景对应一个提示模板提示模式二提示模式二:代码生成说明:1.使用Markdown语法、按总分总结构书写提示。2.在任务重申部分强调一下需要LLM做的事情和注意事项。#任务概述你是一名.资深程序员,请编写程序实现一个系统:1.系统的输入是.,系统的输出是.。2.实
7、现如下面的Markdown表格描述的一套DSL,注意可组合性:|核心概念|概念语义|原子/组合|形式化表达|-|-|-|-|.|.|.|.|.|.|.|.|.|#任务重申1.请编写程序实现上述系统。.全量代码生成初始全量代码生成#任务概述你是一名.资深程序员,请编写程序实现一个系统:1.系统的输入是.,系统的输出是.。2.实现如下面的Markdown表格描述的一套DSL,注意可组合性:|核心概念|概念语义|原子/组合|形式化表达|-|-|-|-|.|.|.|.|.|.|.|.|.|3.已实现的条件或规则未列入表格。相关的实现代码在已有代码中。4.请在/TODO处新增代码。#已有代码java.#
8、待实现的代码java./TODO:.#任务重申1.请在/TODO处按要求新增代码。.增量代码生成基于已有代码,增量生成新的代码#任务概述你是一名.资深程序员,请编写程序实现一个系统:1.系统的输入是.,系统的输出是.。2.实现如下面的Markdown表格描述的一套DSL,注意可组合性:|核心概念|概念语义|原子/组合|形式化表达|-|-|-|-|.|.|.|.|.|.|.|.|.|3.已实现的条件或规则未列入表格。相关的实现代码在已有代码中。4.请在/FIXME处修复代码缺陷。#已有代码java.#待修复的代码java./FIXME:.#任务重申1.请在/FIXME处按要求修复代码缺陷。.代码
9、缺陷修复基于已有代码,修复已有代码缺陷提示模式二:单元测试代码生成#任务概述你是一名Java资深程序员。请你采用等价类与边界值的测试设计方法,使用JUNIT4生成所有被测代码的单元测试代码,注意每个类对应一个测试类、每个测试用例一个测试方法。#被测代码java.#任务重申1.请使用JUNIT4生成所有被测代码的单元测试代码。*注意采用等价类与边界值的测试设计方法。*每个类对应一个测试类、每个测试用例一个测试方法。.无依赖代码的单元测试代码生成1.初始全量单元测试代码生成2.针对对其他代码无依赖的被测代码生成单元测试代码#任务概述你是一名Java资深程序员。请你采用等价类与边界值的测试设计方法,
10、基于已有代码使用JUNIT4生成被测代码的单元测试代码,注意每个类对应一个测试类、每个测试用例一个测试方法。#已有代码java.#被测代码java.#任务重申1.请基于已有代码使用JUNIT4生成所有被测代码的单元测试代码。*注意采用等价类与边界值的测试设计方法。*每个类对应一个测试类、每个测试用例一个测试方法。.有依赖代码的单元测试代码生成针对对其他代码有依赖的被测代码生成单元测试代码LLM高质量代码生成的神兵利器LLM高质量代码生成的神兵利器SMDD(语义模型驱动设计)做出好的设计,输出结构化表达的语义模型,使得LLM能够充分理解设计提示模式交互方式+提示模板,使得LLM基于语义模型高效生
11、成高质量代码实践情况与效果评估PART 03实践案例:字符串转换重构相同逻辑的不同实现重复字符串转换重构:语义模型驱动设计示例核心概念概念语义原子/组合形式化表达规则规则的输入是源字符串,输出是Optional,其中String是转换后的字符串/rule:srcStr-Optional一一映射规则该规则由映射列表构造而成,映射列表的每个元素由一对mappingFrom和mappingTo构成。该规则接受的源字符串即mappingFrom,找到对应的mappingTo并输出原子规则oneToOne(mappingFrom,mappingTo)保留指定位数小数规则该规则由保留小数位数构造而成。该规
12、则对接受的源字符串进行保留指定位数小数处理后并输出原子规则decimalDigits(digitNum)条件应用分支规则该规则由条件、then规则、else规则构造而成。当条件满足时应用then规则,否则应用else规则组合规则whenThenElse(condition,thenRule,elseRule)顺序应用规则该规则由规则列表构造而成。按照给定的顺序依次应用多条规则。当某条规则应用成功,则返回该条规则的应用结果;如果该条规则应用失败,则继续应用下一条规则组合规则seq(rule)条件条件的输入是源字符串、输出boolean,条件满足时输出true、条件不满足时输出false/cond
13、ition:srcStr-true|false null条件该条件无构造参数。当该条件接受的源字符串为null时为true,否则为false原子条件nullString()空白字符串条件该条件无构造参数。当该条件接受的源字符串仅含空白字符或为空时为true,否则为false原子条件blankString()或条件布尔代数的或组合条件or(condition1,condition2)与条件布尔代数的与组合条件and(condition1,condition2).字符串转换重构:提示模式一交互方式:单轮对话+有代码上传提示模板:每个场景对应一个提示模板提示模式二交互方式:多轮对话+无代码上传提示模
14、板:每轮对话对应一个提示模板提示模式一字符串转换重构:代码生成A:好的,我理解了你对这一套DSL的描述。如果你对其中的任何部分有疑问,我会尽力回答。请告诉我如果你需要任何进一步的解释或有其他问题。Q:你是一名Java资深程序员,请编写程序实现一个系统:1.系统的输入是源字符串。系统的输出是Optional,其中String是转换后的字符串,如果转换成功,输出非empty的Optional,如果转换失败,输出Optional.empty。2.实现如下面的Markdown表格描述的一套DSL,注意可组合性:|核心概念|概念语义|原子/组合|形式化表达|-|-|-|-|规则|规则的输入是源字符串,输
15、出是Optional,其中String是转换后的字符串|/|rule:srcStr-Optional|一一映射规则|该规则由映射列表构造而成,映射列表的每个元素由一对mappingFrom和mappingTo构成。该规则接受的源字符串即mappingFrom,找到对应的mappingTo并输出|原子规则|oneToOne(mappingFrom,mappingTo)|.|条件|条件的输入是源字符串、输出boolean,条件满足时输出true、条件不满足时输出false|组合条件|condition:srcStr-true|false|null条件|该条件无构造参数。当该条件接受的源字符串为nu
16、ll时为true,否则为false|原子条件|nullString()|.请先不要给出代码。如果你对于这一套DSL描述有疑问,特别是Markdown表格概念语义列中的内容,请向我提问,我来回答你。A:我已经仔细阅读了您提供的DSL描述,并没有特别的疑问。我明白这是一个规则转换系统,其中包含了原子规则和组合规则,以及一些条件用于判断是否应用规则。您可以继续说明您的需求,我将等待您的指示。如果您需要对DSL的某些方面进行澄清或有其他问题,请随时告诉我,我会尽力回答。Q:请先不要给出代码。你确定没有疑问了吗?A:好的,下面是用Java实现这套DSL的代码:Q:请生成代码。字符串转换重构:单元测试代码
17、生成A:好的,我会使用等价类与边界值的测试设计方法,并使用JUnit 4生成单元测试代码。请注意,由于描述的规则和条件比较复杂,测试覆盖所有情况可能会比较繁琐。因此,我将选择一些典型的等价类和边界值来生成测试用例,以便展示测试的基本思路。你可以在此基础上进一步扩展测试用例,以确保代码的正确性。首先,我们将每个规则和条件对应的测试代码放在独立的测试类中,并使用JUnit 4进行测试。以下是测试类和测试方法的示例代码:.上述代码中,每个规则和条件对应一个测试类,测试类中包含了若干测试方法,每个方法对应一个测试用例。我选择了一些简单的测试用例来演示测试方法的设计,你可以根据实际需求添加更多测试用例。
18、在实际测试中,需要覆盖各种等价类和边界值来确保代码的正确性。请注意,上述测试代码仅用于演示目的,实际测试中应该尽可能全面地覆盖各种情况,以保证系统的稳健性和正确性。Q:请你采用等价类与边界值的测试设计方法,使用JUNIT4生成单元测试代码,注意每个类对应一个测试类、每个测试用例一个测试方法。字符串转换重构:提示模式二交互方式:单轮对话+有代码上传提示模板:每个场景对应一个提示模板提示模式二交互方式:多轮对话+无代码上传提示模板:每轮对话对应一个提示模板提示模式一字符串转换重构:全量代码生成#任务概述你是一名Java资深程序员,请编写程序实现一个系统:1.系统的输入是源字符串。系统的输出是Opt
19、ional,其中String是转换后的字符串,如果转换成功,输出非empty的Optional,如果转换失败,输出Optional.empty。2.实现如下面的Markdown表格描述的一套DSL,注意可组合性:|核心概念|概念语义|原子/组合|形式化表达|-|-|-|-|规则|规则的输入是源字符串,输出是Optional,其中String是转换后的字符串|/|rule:srcStr-Optional|一一映射规则|该规则由映射列表构造而成,映射列表的每个元素由一对mappingFrom和mappingTo构成。该规则接受的源字符串即mappingFrom,找到对应的mappingTo并输出|
20、原子规则|oneToOne(mappingFrom,mappingTo)|.|条件|条件的输入是源字符串、输出boolean,条件满足时输出true、条件不满足时输出false|组合条件|condition:srcStr-true|false|null条件|该条件无构造参数。当该条件接受的源字符串为null时为true,否则为false|原子条件|nullString()|.#任务重申1.请编写程序实现上述系统。字符串转换重构:增量代码生成#任务概述你是一名Java资深程序员,请编写程序实现一个系统:1.系统的输入是源字符串。系统的输出是Optional,其中String是转换后的字符串,如果
21、转换成功,输出非empty的Optional,如果转换失败,输出Optional.empty。2.实现如下面的Markdown表格描述的一套DSL,注意可组合性。|核心概念|概念语义|原子/组合|形式化表达|-|-|-|-|null或空白字符串条件|该条件应基于或条件生成,null条件与空白字符串条件相或。|组合条件|or(nullString(),blankString()|3.已实现的条件或规则未列入表格。相关的实现代码在已有代码中。4.请在/TODO处新增代码。#已有代码java/规则FunctionalInterfacepublic interface Rule Optional ap
22、ply(String srcStr);#待实现的代码java/日期时间规则。static Rule dateTime(String format)return srcStr-/TODO:请完成日期时间规则的实现。该规则对接受的源字符串按照日期时间格式字符串进行日期时间格式处理后并输出。return Optional.of(srcStr);#任务重申1.请在/TODO处按要求新增代码。字符串转换重构:代码缺陷修复#任务概述你是一名Java资深程序员,请编写程序实现一个系统。请使用OpenJDK 8实现。请使用函数式编程,不要使用面向对象编程。1.系统的输入是源字符串。系统的输出是Optional
23、,其中String是转换后的字符串,如果转换成功,输出非empty的Optional,如果转换失败,输出Optional.empty。2.实现如下面的Markdown表格描述的一套DSL,注意可组合性:|核心概念|概念语义|原子/组合|形式化表达|-|-|-|-|顺序应用规则|该规则由规则列表构造而成。按照给定的顺序依次应用多条规则。当某条规则应用成功,则返回该条规则的应用结果;如果该条规则应用失败,则继续应用下一条规则|组合规则|seq(rule)|3.已实现的条件或规则未列入表格。相关的实现代码在已有代码中。4.请在/FIXME处修复代码缺陷。#已有代码java/规则FunctionalI
24、nterfacepublic interface Rule Optional apply(String srcStr);#待修复的代码javapublic static Rule seq(List rules)/FIXME:按照给定的顺序依次应用多条规则。当某条规则应用成功,则返回该条规则的应用结果;如果该条规则应用失败,则继续应用下一条规则#任务重申1.请在/FIXME处按要求修复代码缺陷。字符串转换重构:无依赖代码的单元测试代码生成#任务概述你是一名Java资深程序员。请你采用等价类与边界值的测试设计方法,使用JUNIT4生成所有被测代码的单元测试代码,注意每个类对应一个测试类、每个测试用
25、例一个测试方法。#被测代码java/规则FunctionalInterfacepublic interface Rule Optional apply(String srcStr);class Rules ./条件FunctionalInterfacepublic interface Condition boolean apply(String srcStr);class Conditions .#任务重申1.请使用JUNIT4生成所有被测代码的单元测试代码。*注意采用等价类与边界值的测试设计方法。*每个类对应一个测试类、每个测试用例一个测试方法。字符串转换重构:有依赖代码的单元测试代码生成#
26、任务概述你是一名Java资深程序员。请你采用等价类与边界值的测试设计方法,基于已有代码使用JUNIT4生成被测代码的单元测试代码,注意每个类对应一个测试类、每个测试用例一个测试方法。#已有代码java/条件FunctionalInterfacepublic interface Condition boolean apply(String srcStr);#被测代码javaclass Conditions /或条件 public static Condition or(Condition condition1,Condition condition2)return srcStr-conditio
27、n1.apply(srcStr)|condition2.apply(srcStr);#任务重申1.请基于已有代码使用JUNIT4生成被测代码的单元测试代码。*注意采用等价类与边界值的测试设计方法。*每个类对应一个测试类、每个测试用例一个测试方法。神兵利器效果评估LLM高质量代码生成的神兵利器SMDD(语义模型驱动设计)做出好的设计,输出结构化表达的语义模型,使得LLM能够充分理解设计提示模式交互方式+提示模板,使得LLM基于语义模型高效生成高质量代码 消除了原有代码中的“重复”与“相同逻辑不同实现”等问题,使得可维护性大幅度提升可维护性可维护性可理解性可理解性 LLM生成的代码容易理解,一方面
28、是因为SMDD做出了好的设计,另一方面是LLM充分理解了该设计一致性一致性 LLM生成的代码与设计的核心概念实现了一一对应 LLM生成的代码与人编写的代码是相似的,甚至更好总结&展望PART 04总结LLM高质量代码生成的神兵利器SMDD(语义模型驱动设计)做出好的设计,输出结构化表达的语义模型,使得LLM能够充分理解设计提示模式交互方式+提示模板,使得LLM基于语义模型高效生成高质量代码适用场景适用场景 适用于软件复杂度高的场景亮点亮点 提示模式简单易学 多人多轮多案例验证,结果稳定、有效展望LLMs如何应对LLM的差异性如何写出好的Prompt代码生成的工程化人的能力要求 根据不同的LLM采用相应的提示模式 Prompt中关于SMDD的核心内容是不变的、适用于多种大模型 Prompt中的其他内容以及与LLM的交互方式需要调整,以适应不同的LLM 充分应用提示工程的基本原则 像跟人沟通一样跟LLM沟通 对软件架构提出了更高的要求 人员能力要求不降反升,既要具备软件设计、编码技能,又要掌握提示工程技能 提炼可落地、可推广的提示模式,尽量让LLM能够稳定生成代码,稳定不是100%准确 不建议过度追求100%的代码可用率 需要人来兜底THANKS