Prompt 策略:代码库 AI 助手的语义化搜索设计

这篇具有很好参考价值的文章主要介绍了Prompt 策略:代码库 AI 助手的语义化搜索设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在过去的一周里,为了更好的构建 AI Agent 框架 Chocolate Factory(以下简称 CF),我们加入了一个新的应用:代码库 AI 助手。

在设计时,为了更好的在框架底层提供这种能力,我们参阅了 Bloop 应用、LangChain、Spring AI、LlamaIndex 框架等的代码与思想,参考/复制(基于 Apache 2.0 协议) LangChain4j 的一部分 VectorStore 实现。

详细见代码库:https://github.com/unit-mesh/chocolate-factory

详细文档见:https://framework.unitmesh.cc/

Demo 视频见:

引子:代码库 AI 助手

首先,先让 ChatGPT 根据我们的素材总结了一下:什么是代码库 AI 助手?负责读取和格式化数据,以便将其分成适合存储在数据库中的片段。

代码库 AI 助手是一种智能工具,通常使用自然语言处理和机器学习技术,旨在帮助开发者更有效地管理和理解大型代码库。这些助手能够回答关于代码库的问题、提供文档、搜索代码、识别错误源头、减少代码重复等,从而提高开发效率、降低错误率,并减轻开发者的工作负担。

其设计目标是使开发者能够以更直观和自然的方式与代码库进行互动,减少繁琐的文档查找和编码任务,从而加速软件开发过程。

简单来说,用户直接提出问题,基于现有的业务逻辑实现,去进去后续的任务,如:需求是如何实现的?根据 bug 来分析与代码的关系,并提供修复意见。

先让我们看个示例:

代码库 AI 助手问答示例

问题:Semantic Workflow 是如何实现的?

ChatGPT 根据 CF 检查的代码,返回的答案:

根据提供的代码,我们可以看到 CodeSemanticWorkflow 是一个继承自 Workflow 的类,它实现了 execute 方法来执行语义化的代码搜索。

在 execute 方法中,它首先创建了一个 ElasticsearchStore 对象,并获取了用户最后一条消息的内容作为问题。然后,它使用 SemanticProblemAnalyzer 对象来分析问题,该对象使用 llmProvider 来完成问题的解析。接下来,它使用 SemanticSolutionExecutor 对象来执行语义化的代码搜索,并将结果转换为 Flowable。最后,它调用 toFlowableResult 方法将结果转换为 Flowable 并返回。

下面是一个使用 PlantUML 绘制的流程图,展示了 CodeSemanticWorkflow 的执行过程:

@startuml
start
:创建 ElasticsearchStore对象;
:获取用户最后一条消息的内容;
:使用 SemanticProblemAnalyzer对象分析问题;
:使用 SemanticSolutionExecutor对象执行语义化的代码搜索;
:将结果转换为 Flowable<Answer>;
:将结果转换为 Flowable<WorkflowResult>;
stop
@enduml

希望以上信息能够回答您的问题。

CF 代码库 AI 助手设计

在设计 Chocolate Factory(以下简称 CF)时,我们依旧采用的是 DDD 思想所构建的。

第一部分,围绕于问题空间的求解,对用户问题进行分析与转换,以获得潜在的解决方案。

第二部分,围绕于解决空间的实现,即通过检索增强(RAG,Retrieval Augmented Generation),来获得对应问题的答案。

为此,在第一部分,我们将会分析问答的问题,以构建出一个针对于解决方案的 DSL。然后,围绕于 DSL 来进行检索,获得相应的答案,最后交由 LLM 来进行总结。

Prompt 构建策略阶段 1:问题求解

在设计上,为了更好的进进行检索,在设计 CoUnit 时,我们拆分成三种检查条件:

  • englishQuery,将中文翻译成英文,再结合英文进行搜索。

  • originLanguageQuery,如我们在使用中文里,翻译成英语可能不标准,但是注释中则可能是使用中文存在,所以相似式也会很靠谱。

  • hypotheticalDocument,假设性文档,即根据用户的请求生成代码,再结合生成的代码进行相似式搜索。

所以,在阶段一就需要由 LLM 来分析用户的问题,并给出如上的三个检查条件。hypotheticalDocument 参考的是 Bloop 的设计:

  • hypotheticalDocument is a code snippet that could hypothetically be returned by a code search engine as the answer.

  • hypotheticalDocument code snippet should be between 5 and 10 lines long

不过,由于一次给了三个条件,偶尔还是存在概率性的假设性文档出错的问题。

Prompt 构建策略阶段 2:检索增强

在现有的设计里,一个代码库 AI 助手本质也是 RAG(检索增强,Retrieval Augmented Generation),因此可以分为 indexing 阶段和 querying 阶段。

代码库 AI 助手:indexing 阶段

Prompt 策略:代码库 AI 助手的语义化搜索设计,人工智能,prompt,chatgpt

在 indexing 阶段,基本上就是:

  • 文本分割(TextSplitter)。负责将源数据分割成较小单元(Chunks)的工具或组件。

  • 文本向量化(Vectoring)。负责将拆分好的 Chunk 转变化向量化数组。

  • 数据库(Vector Database)负责通过高效的向量检索技术来实现文档片段的快速检索。

在文本向量化上,我们使用的是 SentenceTransformer 的本地化极小 NLP 模型(22M 左右)。对于代码来说,它是结构化的形式,并且也经过了 GitHub Copilot、Bloop 的充分验证,所以准确度并不差。

由于使用的是本地化模型,通过 CPU 就可以快速计算完成,所以更新策略上可以和 CI、CD 集成。一旦有代码更新时,就可以 indexing。

代码库 AI 助手:querying 阶段

Prompt 策略:代码库 AI 助手的语义化搜索设计,人工智能,prompt,chatgpt

在 querying 阶段,我们会围绕阶段 1 的 DSL,先转换 DSL 的文本成对应的向量化形式。

再对其进行对应的内容检索:

// 基于英语的相关代码列表
val list = store.findRelevant(query, 15, 0.6)
// 基于中文的相关代码列表
val originLangList = store.findRelevant(originQuery, 15, 0.6)
// 相关的假设性代码列表
val hydeDocs = store.findRelevant(hypotheticalDocument, 15, 0.6)

随后,再对结果进行排序。考虑到诸如 《Lost in the Middle: How Language Models Use Long Contexts》对于长文本的影响,我们在 CF 中也引入了对应的方式,因此一个排序后的代码结果如下所示:

0.7847863// canonicalName: cc.unitmesh.cf.domains.semantic.CodeSemanticWorkflowTest
0.76635444// canonicalName: cc.unitmesh.cf.domains.semantic.CodeSemanticDecl
0.74648994// canonicalName: cc.unitmesh.cf.core.flow.ProblemAnalyzer
0.7410852// canonicalName: cc.unitmesh.cf.domains.spec.SpecDomainDecl
0.72767156// canonicalName: cc.unitmesh.cf.core.flow.DomainDeclaration
0.73245597// canonicalName: cc.unitmesh.cf.core.flow.model.WorkflowResult
0.7434818// canonicalName: cc.unitmesh.cf.domains.interpreter.CodeInterpreterWorkflow.execute
0.757218// canonicalName: cc.unitmesh.cf.core.flow.Workflow
0.7722022// canonicalName: cc.unitmesh.cf.domains.semantic.flow.SemanticProblemAnalyzer
0.807935// canonicalName: cc.unitmesh.cf.domains.semantic.CodeSemanticWorkflow.execute

前面的数字便是相关性的 score,后面的 canonicalName 则是相关代码的信息,可能是类、类方法、方法等。

Prompt 策略 3:代码拆分策略

在代码的分割上,不同的框架有不同的策略,LangChain 是基于关键字的方式,LlamaIndex 是基于 TreeSitter 方式,Bloop 则是基于 TreeSitter 的 S-表达式创建。

我们则是采用 ArchGuard Scanner 的标准化代码结构方式,除了可以直接利用 ArchGuard 项目的现有的 CLI 基础设施,在形式上与结果上也更加准确。诸如于可以针对于 Interface、abstract class 等进行优化 Chunk 的拆分规则,并构建出 canonicalName 的方式,来方便索引和定位。

代码拆分规则

我们参考的折分规则是:https://docs.sweep.dev/blogs/chunking-2m-files 。即:

  1. 代码的平均 Token 到字符比例约为1:5(300 个 Token),而嵌入模型的 Token 上限为 512 个。

  2. 1500 个字符大约对应于 40 行,大致相当于一个小到中等大小的函数或类。

  3. 挑战在于尽可能接近 1500 个字符,同时确保分块在语义上相似且相关上下文连接在一起。

对应的模型如下:

classCodeSplitter(
private val comment: String= "//",
private val chunkLines: Int= 40,
private val maxChars: Int= 1500,
// TODO: for unsupported languages, we can use the following heuristic to split the code
    val chunkLinesOverlap: Int= 15,
)

当然了,这里的 chunkLinesOverlap 是还没有襰的。

Chunk 拆分实现

由 CF 的代码库 AI 助手生成:

问题:CodeSplitter 是如何实现的

答案:

根据提供的代码,CodeSplitter 是一个用于将代码拆分成多个文档的类。它有一个 split 函数,该函数接受一个 CodeDataStruct 对象并返回一个 Document 对象的列表。

在 split 函数中,它首先根据代码的长度判断是否需要拆分。如果代码的长度小于等于 maxChars(默认为1500个字符),则直接将整个代码作为一个文档返回。

如果代码的长度大于 maxChars,则会遍历 CodeDataStruct 对象中的每个函数,并将函数的内容拆分成多个文档。拆分的方式是根据 chunkLines(默认为40行)将函数内容分割成多个部分。如果函数的行数超过了 chunkLines,则只取前 chunkLines 行作为一个文档的内容。

拆分后的文档的内容由 canonicalName 和函数的内容组成。如果拆分后的内容长度超过了 maxChars,则会截取前 maxChars 个字符作为文档的内容。

小结

本文深入探讨了代码库AI助手的设计和实现策略,包括问题求解、检索增强和代码拆分。这些策略有助于提高开发者与代码库的互动效率和准确性,加速软件开发过程。

详细见代码库:https://github.com/unit-mesh/chocolate-factory 。

详细文档见:https://framework.unitmesh.cc/ 文章来源地址https://www.toymoban.com/news/detail-714177.html

到了这里,关于Prompt 策略:代码库 AI 助手的语义化搜索设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【复习】人工智能 第六章 搜索求解策略(又多又难)

    在求解一个问题时,涉及到两个方面: (1)该问题的表示 (2)相对合适的求解方法:由于绝大多数需要人工智能方法求解的问题缺乏直接求解的方法,因此, 搜索 为一种求解问题的一般方法。 另外如果真的想拿下这一章,还是走一下ppt或书上的八数码的对应的每一种情况

    2024年01月16日
    浏览(54)
  • 掌握AI助手的魔法工具:解密Prompt(提示)在AIGC时代的应用「中篇」

    在当今人工智能时代,我们越来越多地依赖于AI助手来解决问题和满足需求。然而,要让AI助手真正理解我们的意图并产生出我们期望的结果并不容易。在本篇文章中,我们将探讨一种关键的技巧,即prompt的使用。通过合理运用prompt,我们可以更好地引导AI助手的思考,从而得

    2024年02月11日
    浏览(40)
  • 掌握AI助手的魔法工具:解密`Prompt`(提示)在AIGC时代的应用(下篇)

    前言:在前面的两篇文章中,我们深入探讨了AI助手中的魔法工具—— Prompt (提示)的基本概念以及在 AIGC(Artificial Intelligence-Generated Content ,人工智能生成内容)时代的应用场景。在本篇中,我们将进一步探索多个领域中 Prompt 的应用,并通过具体的场景举例来加深理解。

    2024年02月07日
    浏览(56)
  • 掌握AI助手的魔法工具:解密Prompt(提示)在AIGC时代的应用「上篇」

    在当今的AIGC时代,我们面临着越来越多的人工智能技术和应用。其中一个引人注目的工具就是Prompt(提示)。它就像是一种魔法,可以让我们与AI助手进行更加互动和有针对性的对话。那么,让我们一起来了解一下Prompt,它是什么,为什么需要它,怎么使用它以及使用它会有

    2024年02月11日
    浏览(51)
  • 【AI 人工智能】Prompt 学习之基础篇

    2023 年,最火的可能就是 openAI 了,其组织代表的产品 chatGTP,相信大家已经有所耳闻。不少同学已经开始着手使用,并截图晒出 ChatGPT 是多么得智能与神奇。而有的同学在使用之后觉得有点差强人意,指出顶多算是一个比较聪明的聊天机器人而已。 其实,ChatGPT 的难点,在于

    2024年02月08日
    浏览(50)
  • 3DSEE:AI驱动的3D模型语义搜索引擎

    3DSEE (3D SEmantic Engine)是基于 AI 技术的 3D 模型语义搜索引擎,可以自动提取 3D 模型内涵的语义信息并存储入库,以帮助用户使用自然语言或高效地检索 3D 模型。3DSEE 提供完善的二次开发 API,无论使用Java、Python、PHP、JavaScript还是C#,都可以在自己的应用中集成 3D 模

    2024年02月03日
    浏览(36)
  • AI智能助手的未来:与人类互动的下一代人工智能技术

    智能助手是一种基于人工智能技术的应用程序或设备,旨在帮助用户完成各种任务、提供信息和服务。智能助手通常具备 语音识别 、 自然语言处理 和 机器学习 等技术,使其能够 理解和解释用户的指令 、 问题或请求 ,并以相应的方式 作出回应 。 智能助手可以运行在智能

    2024年02月11日
    浏览(63)
  • 【AI智能助手的未来】与人类互动的下一代人工智能技术

    智能助手是一种基于人工智能技术的应用程序或设备,旨在帮助用户完成各种任务、提供信息和服务。智能助手通常具备 语音识别 、 自然语言处理 和 机器学习 等技术,使其能够 理解和解释用户的指令 、 问题或请求 ,并以相应的方式 作出回应 。 智能助手可以运行在智能

    2024年02月07日
    浏览(72)
  • 第二十五章:AI大模型在人工智能助手领域的应用

    人工智能助手(AI Assistant)是一种通过自然语言交互与用户进行对话的软件系统,旨在提供有针对性的信息和服务。AI助手通常使用自然语言处理(NLP)和机器学习技术来理解用户的需求,并提供相应的回答和建议。随着AI技术的发展,AI助手已经成为了人们日常生活中不可或缺的一

    2024年02月21日
    浏览(72)
  • 人工智能AI绘画Midjourney绘画提示词Prompt大全【宝藏级收藏】

    SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型+国内AI全模型。本期针对源码系统整体测试下来非常完美,那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧。已支持GPT语音对话、GPT-4-Turbo模型、DALL-E3文生图、GPT-4-

    2024年01月20日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包