如何改进从大型语言模型(LLMs)获得的编码建议?

几周前,Josh Collinsworth 写了一篇题为“我担心我们的 Copilot 会落下一些乘客”的文章,我一直对此念念不忘,尤其是这一部分:
"为什么我们应该接受 LLM 工具不仅无法至少提供相同的警告,反而积极地将我们推向错误的方向?
那种持续的压力才是我真正担忧的。
当然,你应该在看到糟糕的代码时识别出来,并且不应该让它通过。但如果你整天都在看到糟糕的代码呢?
当你不能确定代码是好是坏时,会发生什么?
人们普遍吹捧 Copilot 的一个好处是,它在处理新的或不熟悉的语言时非常有帮助。但如果你处于那种情况,当你看到一个糟糕的想法时,你又如何能辨别出来呢?
再说一次:我在这里关心的不是某种柏拉图式的代码质量理想;我关心的是它对用户体验和可访问性的真实影响。"
我之所以对此念念不忘,是因为我相信可以有所作为。如果我们获得的建议是有缺陷或错误的,那么我们需要对此采取行动。
对于在各个层面都错误的建议,就像 Josh 的例子中不必要地阻止用户那样,我们需要确保永远不再收到这样的建议。
当我们的行为展示了“构建软件的正确方法”时,它们应该影响未来的建议。随着我们对“正确方法”的定义不断演变,我们从 LLM 工具中获得的建议也应该随之演变。
那么,你可以做些什么来改进从大型语言模型(LLMs)获得的编码建议呢?
1. 提供清晰全面的指示
优点
- 如果你知道自己在做什么,这很容易
- 你可以根据需要为每种情况定制
缺点
- 你的指示可能需要非常精确,以至于直接写代码反而更容易
- 这是一个缓慢、繁琐的过程,每个人每次都必须重复
2. 添加一个包含应始终遵循的指示的系统消息
优点
- 你可以设置一次然后忘记(例如,就像环境变量)
- 它适用于许多情况(例如,你的操作系统版本)
缺点
- 很难提前预测所有可能的指示
- 由于上下文长度限制,系统消息中只能包含有限的信息
3. 自动过滤掉明显糟糕的建议并请求新的建议
优点
- 你可以确保代码不违反许可协议、使用特定的库等
- 当过滤器捕获到一个建议时,你甚至可以自动重新提示
缺点
- 很难提前确定哪些过滤器是必要且充分的
- 这将导致一个缓慢且代价高昂的过滤系统,并且会变得非常庞大
4. 改进从代码库 + 软件开发生命周期中检索和使用上下文的方式
优点
- 有许多关于如何让基本的 RAG 系统工作的指南
- 使用文档和代码片段作为上下文有助于缓解知识截止日期问题
缺点
- 很难构建一个能够立即自动确定哪些上下文相关的系统
- 这可能需要大量的集成,而你必须永久维护这些集成
5. 使用不同的 LLM,并且使用多个 LLM
优点
- 大多数 LLM 工具使用 1-15B 参数的模型进行标签自动完成,并使用 GPT-4 回答问题
- 你可以针对特定情况(例如,专有编程语言)使用特定的模型
缺点
- 你可能无法使用你想要和需要的模型
- 你想要或需要的许多模型可能甚至不存在
6. 使用微调改进现有的 LLM
优点
- 它可以让模型学习你偏好的风格
- 它可以针对你的每个用例高度定制
缺点
- 这可能需要人们生成大量的领域特定指示以及 100 小时以上的 GPU 时间
- 它在学习新知识/新能力方面效果不佳
7. 使用领域自适应的持续预训练改进开源 LLM
优点
- 有许多相当强大的基础模型,如 Llama 2,具有开放权重
- Meta 创建 Code Llama 和 Nvidia 创建 ChipNeMo 就是通过这种方式实现的
缺点
- 这可能需要数十亿相关的公司数据 token + 数千小时的 GPU 时间
- 这是一种具有挑战性、昂贵且耗时的方法
8. 从头开始预训练自己的 LLM
优点
- 通过预处理训练数据,你可以决定模型学习哪些知识/能力
- GPT-4 和 DeepSeek Coder 等最好的模型就是这样创建的
缺点
- 这可能需要数万亿的互联网数据 token + 相关的公司数据 + 数百万小时的 GPU 时间
- 这是最具挑战性、最昂贵且最耗时的方法
结论
要做到其中许多事情,你需要比大多数现有 AI 代码辅助工具提供远多得多的可配置性。如果你的系统有任何一部分你无法控制,你会发现建议可能会而且将会在你不知情的情况下发生变化。
我相信我们需要做上述列出的所有事情,以确保我们的 copilots 不会落下任何乘客。去年夏天,我写了一篇关于我认为这最终需要什么的文章草稿,虽然有点过时,但仍然值得一读:“是时候收集关于你如何构建软件的数据了”。
如果你想了解更多未来在 LLM 帮助下构建软件的社区人士的文章,请在这里订阅我们的月度通讯 这里。