深圳 汽车网站建设,大城网站制作,网站被镜像 站长学院,0基础怎么学服装设计这是两篇面向LLM的大前端架构的第二篇#xff0c;主要写我对LLM辅助开发能力的认知以及由此推演出的适合LLM辅助开发的技术架构。
LLM之于代码
商业代码对质量的要求其实对LLM是有点高的。主要是输入准确度、输出准确度#xff08;这个是绝大部分人质疑的点#xff09;、知…这是两篇面向LLM的大前端架构的第二篇主要写我对LLM辅助开发能力的认知以及由此推演出的适合LLM辅助开发的技术架构。
LLM之于代码
商业代码对质量的要求其实对LLM是有点高的。主要是输入准确度、输出准确度这个是绝大部分人质疑的点、知识新鲜度和上下文长度。 现有的玩票类的代码辅助看起来非常酷炫也证明了LLM的潜力特别是chatdev放到商业环境下还是不太行。Copilot简单使用了相似的线上代码所以可用性好很多但是LLM的参与度非常低。AutoDev、UnitMesh做了很多东西源码上看prompt有些简单没有真的用过不敢评价。 简单解释一下我觉得有挑战的这几个方面
输入准确度要保证完备且精准的把需求写进prompt。而且要把边界条件、异常处理都加上这个就比较离谱了因为大部分人是做不了这么详细的技术设计的或者能细致如斯那离真正代码就太近了不太值得费心思用LLM输出准确度这个好理解想办法规避幻觉。不论是代码本身层面的还是业务逻辑层面的知识新鲜度LLM对新知识的追加是非常困难的而且不天然具备新知识比旧知识权重高的特点。对于大前端这种人均轮子王的技术栈很难给出足够现代的代码上下文长度即便是最新的gpt4面对轻松松百万行的代码处理也是有心无力的更不要说超长上下文带来的lost in context问题。就算是想办法把业务上下文处理掉组件、内部基建的上下文是极难搞定的
修改架构以适应LLM
核心思路严格的SOLID和代码拆解减少单次生成范围不造轮子让LLM做准确度要求不高的工作。
流程
编码只是整个开发过程的一部分基于前面的分析这部分提效最困难。而开发过程的其他部分反而有非常适合LLM的有的简单调整也可以快速应用LLM。单次开发流程大概是需求分析-技术设计-写代码-自测-CR-bugfix-上线。
需求分析
主要是把业务正常、异常情况潜在扩展点非业务逻辑类的需求性能、安全性等列清楚并且确定业务归属的子域DDD。 需要做的根据需求文档做问答、对上下文进行常见的扩写异常情况、扩展点、其他要求非常适合LLM。但是确定业务归属不太合适不过也不太值得用LLM。
技术设计
确定模块、分层、用的技术点、核心复杂度的拆解和设计、风险评估、扩展点实现方式等。 需要做的有不少是搜索retrieve类的工作技术点、风险评估、核心复杂度的拆解方式、设计模式是非常适合LLM的如果能对接搜索引擎的就基本完美了。 识别核心复杂度是个分类任务还不需要特别新的知识这个也非常适合LLM。 还有另一个大部分工作是应用规则的模块、分层、细节设计、任务拆解和依赖梳理、相关代码梳理这些对LLM比较难。
写代码
见下文
自测
主要是手点和UT手点没办法UT见下文
CR
CR其实要确定三件事是做到位的技术使用、业务合理、多端一致。
技术CR主要就是看遵循习俗、规范。只要不是有特别多内部基建和奇异写法LLM的知识和理解力是完全胜任的业务CR。这个需要有完整的业务定义的仅靠当前的技术评审文档是不够的。和代码合到一起上下文会非常爆炸不太行多端一致。这个其实完全可以在写代码的时候靠翻译我们落地效果非常好。如果是硬对齐是需要LLM分别解释代码到一个中间态然后再用LLM做中间态的一致性判断的。这里面又涉及到了不同端基建行为的不一致所以问题会比较多
bugfix
由于技术带来的bug一般都问题不大由业务逻辑带来的bug一般都解不了。
上线
这部分主要是merge代码处理冲突。这个上下文会非常长但是如果能有业务解释文档prompt历史记录做背景解冲突可能会很好用。没试过不敢保证。
新App
基建
简单一句尽量用最流行的开源库。用hook、字节码、fork来做底层修改但是保证api与公有知识一致。这样LLM生成的代码能非常简单的适配。 即便做不到这个那一定要有智能规则来做转化这个转换可以也利用LLM。 如果没有流行开源库那一定按照广为流传的标准定义或者计算机基本原理中的术语不是黑话来定义接口。LLM的理解和近迁移还是相对厉害的如果复杂任务中远迁移是强模所难。
UI/业务组件
要么能用规则说明白设计稿与组件的对应关系让LLM一次性直接生成使用组件的代码。要么就是生成原始代码再利用RAG相反的思路去做组件替换。 前者没有试过我司用的figma导出的设计稿并不能包含组件信息虽然在figma页面上能看到。后者逻辑上可行还没来得及试。
分层
一定要严格、规整的MVX分层严格、规整的数据驱动或者状态机保证每一层的关注点是独立的且上一层的代码只需要理解和依赖下一层。规避任何context、单例、全局变量等不受控的信息扩散。保证任何一层的代码生成只需要当层的业务描述和下一层的接口声明且接口必须明确变化和不变字段。
分块
分块是为了尽可能减少单模块的上下文需求和迭代所需要的历史代码。 几个关键点
平衡模块大小和通信降低大小核心目的是控制上下文长度。如果通信过多的话上下文会比业务逻辑描述还要更麻烦。M层用DDD拆分按业务逻辑边界拆开V层用视图位置拆分按设计稿边界拆开X层如果是VM的话按V层拆分如果是P层的话按M层拆分。这个比较麻烦需要实践中规范SOP。MVVM和MVIredux应该是更合理的选型
函数式
分块的粒度最终会是方法不会是类。因为类会有成员变量对生成准确性影响会比较大所以要尽可能规避。而最好的办法就是函数式。
打包/组件化
幻觉是不可避免的人和IDE一定是在相当长时间内作为纠错机制存在的。虽然已经有利用编译错误进行编译错误修复的功能但是这个的正确与否是极为客观的修复也是极为客观的语法规则。而一般情况下业务的正确与否还是需要人来校准的否则就可以通过细化步骤完全规避幻觉了在用LLM的过程中发现任务的核心复杂度严重影响最终结果可用性细化步骤ReAct来把单任务的核心复杂度降低并且利用前序消息做chat历史效果好很多。 那么快速试错就是开发过程中最重要的了。换句话说打包速度、小粒度快速运行会变得极为重要。打包又要成显学了就…。所以MVVM这种能把业务逻辑、交互逻辑都以UT方式验证的模式会比其他MVX模式要更适合。任何可以快速预览的UI框架也都更优于需要打包的框架。
UT
对于相对完整和独立的代码LLM是可以给出完整的UT的。如果是白盒补UT边界搞得比较准。但是有一些算法会明显被网络上不靠谱但错的很普遍的代码误导出问题。 再叠加验证速度很可能成为开发效率瓶颈应该更多的考虑黑盒的TDD甚至case本身会是非常好的提示词能非常准确的描述需求。从需求到UT这个还没找到靠谱的prompt直给的prompt效果不好能想到的多步骤是需求-简单代码框架翻译-边界条件联想-UT翻译这个路径但是我司并不写UT暂未实践。
迭代
迭代的挑战是远高于一次性生成的之前所以image2code的项目都选择性的无视了这个点导致不太能落地沦为KPI项目。 代码由于大部分源自于生成迭代方式一定会有大量变化。无非是两种可能性每次都重新生成和每次都带上老代码。 重新生成就必须把历史上次prompt和人工修改点记录下来那么commit的规范应该是生成记录代码和promptfix bugs。这样的下次生成最理想情况下LLM的温度和topxxx都是最稳定的那档是可以直接重新生成cherry-pick来形成下一个迭代结果的。但注意很可能代码生成是一连串对话的结果所以可能对话导出单独文件是更明智的选择比如codexxx.kt有一个配套的codexxx.chat.log来记录完整prompt过程。 带上次代码这部分没有持续试过但简单尝试发现很难正确描述代码。或者说很难把修改点让LLM弄明白。Chat效果相对好一些不过也不是很乐观。
风格一致性和协作
这里是不是真的需要我是有一些怀疑的。如果所有代码都是生成的那么协作规模应该是相对小的即便是大团队边界也会更加明确人的作用也更多的是cr和流程管理所以由大规模协作带来的风格一致性、规范等等问题会不会就不需要了只要保证模型能迭代就ok了。 但是一致性带来的技术收敛就没有了对hook、依赖管理会有更高的要求。
老App
老代码会希望演变到新App描述的状态或者说把屎山变成稍微有条理的代码。有一些额外的工作可以试着用LLM也有一些大概率当前的LLM不能胜任。从大到小大概是这些工作。这部分很多来自我自己的知乎回答。
模块化和业务分割
受困于上下文长度和代码理解的精准程度这种偏全局的工作很难直接利用LLM。但是在原有静态分析工具的基础上把结果规范化之后让LLM做全局分析应该是问题不大的。因为静态分析之后做模块化和拆分其实是根据依赖做最大流最小割以及对代码做分类这两个上下文要求就小很多了分类还是LLM最强的能力之一。
整体分层
分层比单纯模块化需要更多的业务知识是根据业务特征把分好的模块归入不同的层级。毕竟对于IDaaS和支付公司来说登录是完全不同的业务定位代码所处的层级也是完全不同的。这个其实不太需要LLM有个正经业务架构师正经分析一下业务情况给一个原则性指导文件就好。但是让LLM根据这个指导文件来指导后续代码的实施还是很有价值的至少是可以做一个文件问答让每个人都能更好的理解其中的原理。
冗余
发现和去掉冗余/重复代码也是去屎山的重要步骤。对于完全基于LLM的App来说这个也是非常重要的因为LLM上下文天然决定了除非用非常强的RAG和大量反反复复的chat否则一定会出现大量重复或极小差异的代码。 这部分直接裸用LLM不行但是用LLM做标注、embedding后做相似度应该是可以的只不过做全代码聚类的成本比较高需要有的放矢的查和改。如果能fine tune embedding直接对代码表意能去掉标注步骤可以真的做全代码的聚类和修改。
局部分层
就是把BBM搞成合理分层的MVX。如果是想真的把MVX分好这个难度很大LLM不太能理解分层的清晰边界是啥但是如果是人明确规则比如buildview、setdata、updateconstraints这种明确的代码特征那非常好用。有了这些方法其实人再做分层也没那么麻烦了。 主要还是困于LLM应用原则中距离迁移的能力并不是很强。
老代码迁移
迁移到函数式
这个相对简单一般这个量级的代码对gpt4来说问题不大。函数式也是一个通用概念。任务本身难度没那么大。
迁移到更通用的库
完全看现有库是不是接口非常离谱。如果老库只是实现非常蹩脚但是还是使用业界相关命名迁移效果非常好。如果老库取的是Eva这种不着调的名字那很可能会大规模跑偏。因为被激活的包含了完全不同领域的部分。
性能问题
看性能来源是什么
全局设计问题这种通常是业务设计问题LLM不太行局部设计问题这种通常是使用的技术不太对或者实现方式不合理。如果是成熟老技术那问题不大如果最好的解法是新技术可能会有点问题
梳理
或者说与代码对话。 全局搜索类的靠RAG是非常值得做的。我自己实现了一版半效果还是可以的。如果不考虑成本把能上的手段都上了把embedding的ft也做了应该会非常惊艳。 局部分析类的直接把代码丢给GPT4也是OK的只是代码最好和正常思路是一致的要不然代码中命名、逻辑激活的常见思路和实际情况的差异会带来大量的幻觉。
总结
LLM对于开发来说当前情况下最大的贡献点在于非代码部分和最细节的代码部分。为了适配LLM的能力水平流程需要识别出适合LLM的点并且规范化输入输出尽可能交给LLM代码需要极限的拆解让每一块代码都更聚焦人需要增强cr能力和表达能力充分利用好工具IDE需要更好的集成和基于prompt的协作支持。