贡献给 LlamaIndex#
想要为 LlamaIndex 做贡献吗?以下是开始的方法!
贡献指南#
LlamaIndex 最棒的部分就是我们的用户和贡献者社区。
我应该做什么?#
- 🆕 通过贡献集成来扩展核心模块
- 📦 贡献工具、阅读器、包或数据集(以前来自 llama-hub)
- 🧠 为核心添加新功能
- 🐛 修复错误
- 🎉 添加使用示例
- 🧪 添加实验性功能
- 📄 改进代码质量和文档
此外,加入我们的 Discord 获取想法和讨论: https://discord.gg/dGcwcsnxhU.
1. 🆕 扩展核心模块#
为 LlamaIndex 做出最有影响的贡献方式是通过扩展我们的核心模块:
我们欢迎在上述 所有 模块中的贡献。 到目前为止,我们已经为每个模块实现了一组核心功能,所有这些功能都封装在 LlamaIndex 核心包中。作为贡献者,您可以帮助每个模块发挥其全部潜力。以下是这些模块的简要描述。您还可以参考此 Github 存储库中它们各自的文件夹,以获取一些示例集成。
贡献一个集成包括提交新的 Python 包的源代码。目前,这些集成将存储在 LlamaIndex Github 存储库中,并且团队将负责将该包发布到 PyPi。(考虑将这些包存储在此存储库之外,并由我们的社区成员维护。)
创建新的集成包#
llama-index
和 llama-index-core
都配备了一个命令行工具,可用于初始化新的集成包。
cd ./llama-index-integrations/llms
llamaindex-cli new-package --kind "llms" --name "gemini"
执行上述命令将在 llama-index-integrations/llms
目录中创建一个名为 llama-index-llms-gemini
的新文件夹。
请确保为您的新包添加详细的 README,因为它将出现在 llamahub.ai 和 PyPi.org 网站上。
除了准备您的源代码并提供详细的 README 外,我们还要求您为您的包添加一些元数据,以便在 llamahub.ai 中显示正确的信息。您可以通过在您的新包的 pyproject.toml
下添加所需的元数据来实现这一点。
以下是我们所有集成包所需的元数据示例。请将默认作者 "llama-index" 替换为您自己的 Github 用户名。
[tool.llamahub]
contains_example = false
import_path = "llama_index.llms.anthropic"
[tool.llamahub.class_authors]
Anthropic = "llama-index"
(来源)
注意:我们正在快速改进项目,因此某些接口仍然不够稳定。具体来说,我们正在积极努力使以下组件更加模块化和可扩展(上面未着色的框):核心索引、文档存储、索引查询、查询运行器
模块详细信息#
下面,我们将描述每个模块的功能,给出接口的高级概念,展示现有的实现,并提供一些贡献的想法。
数据加载器#
数据加载器将任何格式的数据从任何地方导入到 Document
对象中,然后可以对其进行解析和索引。
接口:
load_data
接受任意参数作为输入(例如数据路径),并输出Document
对象的序列。lazy_load_data
接受任意参数作为输入(例如数据路径),并输出Document
对象的可迭代对象。这是load_data
的延迟版本,对于大型数据集很有用。
注意:如果只实现了
lazy_load_data
,则将委托给它。
示例:
贡献数据加载器对社区来说既简单又有影响力。 贡献的首选方式是在 LlamaHub Github 上提交 PR。
想法
- 想要加载某些内容,但 LlamaHub 还没有相应的数据加载器?提交 PR 吧!
节点解析器#
节点解析器将 Document
对象解析为 Node
对象(LlamaIndex 操作的原子数据单元,例如文本块、图像或表格)。
它负责通过文本分割器拆分文本(通过文本分割器)并明确建模数据单元之间的关系(例如 A 是 B 的来源,C 是 D 之后的块)。
接口:get_nodes_from_documents
接受一个 Document
对象序列作为输入,并输出一个 Node
对象序列。
示例:
请参阅API 参考以获取完整详情。
想法:
- 添加新的
Node
关系以建模分层文档(例如 play-act-scene,chapter-section-heading)。
文本分割器#
文本分割器将长文本 str
按照所需的大小和分割“策略”分割成较小的文本 str
块,因为 LLMs 具有有限的上下文窗口大小,所以所使用的文本块质量作为上下文会影响查询结果的质量。
接口:split_text
接受一个 str
作为输入,并输出一个 str
序列。
示例:
文档/索引/KV 存储#
在底层,LlamaIndex 还支持可互换的存储层,允许您自定义文档存储(存储摄入的文档(即 Node
对象))和索引存储(存储索引元数据)。
我们有一个支持文档/索引存储的基础键值抽象。 目前,我们支持内存和 MongoDB 存储这些存储。欢迎贡献!
请参阅存储指南以获取详情。
托管索引#
托管索引用于表示通过 API 管理的索引,公开 API 调用以索引文档和查询文档。
目前,我们支持 VectaraIndex。 欢迎贡献!
请参阅托管索引文档以获取详情。
向量存储#
我们的向量存储类存储嵌入并支持通过相似性搜索进行查找。 这些作为我们向量索引的主要数据存储和检索引擎。
接口:
add
接受一个NodeWithEmbeddings
序列,并将嵌入(以及可能的节点内容和元数据)插入向量存储。delete
根据文档 ID 删除条目。query
根据查询嵌入检索前 k 个最相似的条目。
示例:
想法:
- 看到我们尚未支持的向量数据库了吗?提交一个 PR 吧!
请参阅参考以获取详情。
检索器#
我们的检索器类是轻量级类,实现了一个 retrieve
方法。
它们可以接受索引类作为输入 - 默认情况下,我们的每个索引(列表、向量、关键词)都有一个关联的检索器。输出是一组 NodeWithScore
对象(带有额外的 score
字段的 Node
对象)。
如果您愿意,您也可以选择在自己的数据之上实现自己的检索器类。
接口:
retrieve
接受一个str
或QueryBundle
作为输入,并输出一个NodeWithScore
对象列表。
示例:
想法:
- 除了建立在每个索引之上的“默认”检索器外,还有什么其他更高级的检索器?例如,接受其他检索器作为输入的检索器?或其他类型的数据?
查询引擎#
我们的查询引擎类是轻量级类,实现了一个 query
方法;查询返回一个响应类型。
例如,它们可以接受检索器类作为输入;我们的 RetrieverQueryEngine
除了接受 retriever
作为输入外,还接受一个用于响应合成的 BaseSynthesizer
类,query
方法在返回最终结果之前执行检索和合成。
它们也可以接受其他查询引擎类作为输入。
接口:
- query
接受 str
或 QueryBundle
作为输入,并输出一个 Response
对象。
示例:
查询转换#
查询转换通过关联的转换来增强原始查询字符串,以改善索引查询。这可以被理解为在核心索引查询逻辑执行之前的预处理阶段。
接口:run
接受 str
或 Querybundle
作为输入,并输出一个转换后的 QueryBundle
。
示例:
查看指南以获取更多信息。
标记使用优化器#
标记使用优化器用于优化检索到的 Nodes
,以减少在响应合成过程中的标记使用量。
接口:optimize
接受 QueryBundle
和文本块 str
作为输入,并输出一个经过优化的文本块 str
,以产生更优化的响应。
示例:
节点后处理器#
节点后处理器根据配置和上下文来优化一组检索到的节点。
接口:postprocess_nodes
接受一组 Nodes
和额外的元数据(例如相似性和查询),并输出一组经过优化的 Nodes
。
示例:
输出解析器#
输出解析器使我们能够从 LLM 生成的纯文本输出中提取结构化输出。
接口:
format
:使用结构化输出格式指令格式化一个查询str
,并输出格式化后的str
parse
:接受一个str
(来自 LLM 响应)作为输入,并给出一个解析的结构化输出(可选地也进行验证、纠错)。
示例:
查看指南以获取更多信息。
2. 📦 贡献一个 Pack、Reader、Tool 或 Dataset(原来来自 llama-hub)#
工具、读取器和包已经从llama-hub迁移到主要的 llama-index 仓库(即本仓库)。数据集仍驻留在 llama-hub,但将在不久的将来迁移到这里。
贡献新的读取器或工具涉及在llama-index-integrations/readers和llama-index-integrations/tools文件夹中提交一个新包。
LlamaIndex 命令行工具可用于初始化新的包和集成。(注意:llama-index-cli
已与llama-index
一起安装。)
cd ./llama-index-packs
llamaindex-cli new-package --kind "packs" --name "my new pack"
cd ./llama-index-integrations/readers
llamaindex-cli new-package --kind "readers" --name "new reader"
执行第一组 shell 命令将在llama-index-packs
目录中创建一个名为llama-index-packs-my-new-pack
的新文件夹。而第二组命令将在llama-index-integrations/readers
目录中创建一个名为llama-index-readers-new-reader
的新包目录。
请确保为您的新包添加详细的 README,因为它将出现在llamahub.ai和 PyPi.org 网站上。除了准备您的源代码并提供详细的 README 外,我们还要求您为您的包填写一些元数据,以便在llamahub.ai中显示正确的信息。您可以通过在pyproject.toml
中为您的新包添加所需的元数据在[tool.llamahub]
部分来完成这一点。
以下是包、读者和工具所需的元数据示例:
[tool.llamahub]
contains_example = true
import_path = "llama_index.packs.agent_search_retriever"
[tool.llamahub.class_authors]
AgentSearchRetrieverPack = "logan-markewich"
(来源)
3. 🧠 为核心功能添加新能力#
我们非常感谢对我们当前一系列功能的增强提出的任何贡献。也欢迎对这些核心抽象进行改进,使其更加健壮,从而更易于构建!
我们精心策划了一个贡献项目看板,可以提供一些关于如何对核心功能进行贡献的想法。
4. 🐛 修复错误#
大多数错误都是在GitHub问题页面上报告和跟踪的。我们会尽力对这些问题进行分类和标记:
- 标记为
bug
的问题是已确认的错误。 - 新贡献者可能希望从标记为
good first issue
的问题开始。
请随时提出问题,或者将问题分配给自己。
5. 🎉 添加使用示例#
如果您已经将 LlamaIndex 应用于独特的用例(例如有趣的数据集、定制的索引结构、复杂的查询),我们非常欢迎您以以下形式进行贡献:
- 指南:例如《LlamIndex + 结构化数据指南》
- 示例笔记本:例如电子邮件信息提取
6. 🧪 添加实验性功能#
如果您有一个疯狂的想法,请为其提交 PR!无论是最新的研究,还是您在淋浴时想到的,我们都希望看到改进 LlamaIndex 的创造性方式。
7. 📄 提高代码质量和文档#
我们希望您的帮助能使项目更加清洁、更加健壮、更容易理解。如果您发现某些内容令人困惑,很可能其他人也会这样认为。帮助我们变得更好!
开发指南#
设置环境#
LlamaIndex 是一个 Python 包。我们主要测试了 Python 版本 >= 3.8。以下是设置本地开发环境的简要指南。
- Fork LlamaIndex Github 仓库* 并将其克隆到本地。(第一次使用 GitHub / git?这里是操作指南。)
- 在终端中,
cd
进入您 fork 的仓库的本地克隆目录。 - 运行
pre-commit install
安装pre-commit hooks*。这些钩子是小型的日常脚本,每次进行 git 提交时都会执行,可以自动化许多琐事。 cd
进入您想要操作的特定包的目录。例如,如果我想要操作核心包,我会执行cd llama-index-core/
。(第一次使用终端 / 命令行?这里是入门指南。)- 准备一个虚拟环境。
- 安装 Poetry*。这将帮助您管理包依赖关系。
- 执行
poetry shell
。这个命令将为这个包创建一个虚拟环境,将安装的包限制在这个项目中。(第一次使用 Poetry,Python 的依赖和打包管理器?在这里了解其基本用法bus。) - 执行
poetry install --with dev,docs
*。这将安装本地开发所需的所有依赖项。要查看将要安装的内容,请阅读该目录下的pyproject.toml
。
带有星号(*
)的步骤是一次性任务。下次尝试贡献其他内容时,无需重复执行。
现在您应该已经准备好了!
验证您的更改#
让我们确保对我们的更改进行 format/lint
。对于较大的更改,让我们也确保进行 test
,并可能创建一个 example notebook
。
格式化 / Linting#
我们运行一系列的 linters:black
、ruff
、mypy
。
如果您在此仓库中安装了 pre-commit hooks,它们应该已经自动处理了格式化和 linting。
如果出于任何原因,您希望手动执行,您可以在根目录下使用以下命令格式化和 lint 您的更改:
make format; make lint
在幕后,我们仍然为您安装了 pre-commit hooks,这样您下次就不必手动执行了。
测试#
如果您修改或添加了代码逻辑,请创建测试,因为测试有助于防止其他维护者意外破坏您添加的好东西/重新引入您修复的错误。
- 几乎在所有情况下,都要添加单元测试。
- 如果您的更改涉及添加新的集成,还要添加集成测试。在这种情况下,请模拟与 LlamaIndex 集成的远程系统,这样当远程系统发生变化时,LlamaIndex 的开发人员就不会看到测试失败。
相应地,您应该在提交 git 提交之前运行现有测试(从您触及的每个软件包中),以确保您没有破坏其他人的良好工作。
(顺便说一句,当测试运行的目标是检测新版本代码库中是否出现故障时,这被称为“回归测试”。您还会听到人们说“测试_回归了_”这样更委婉地说“测试_失败了_”。)
我们的测试存储在每个软件包目录下的tests
文件夹中。我们使用测试框架 pytest,所以您可以只需在您触及的每个软件包中运行 pytest
来运行其所有测试。
就像格式化和 linting 一样,如果您更喜欢按照 make 的方式做事,请运行:
make test
无论您是否在本地运行了它们,CI 系统 在您提交 PR 时都会运行所有受影响的测试。在那里,测试是由我们选择的构建系统 Pants 协调的。有一点可能性是,CI 上的测试失败了,但在您的本地机器上没有失败,或者反过来。当发生这种情况时,请以我们的 CI 为真相。这是因为我们的发布流水线(用于构建用户将从 PyPI 下载的软件包)在 CI 上运行,而不是在您的机器上(即使您自愿),因此 CI 才是黄金标准。
创建示例笔记本#
对于涉及全新功能的更改,可能值得添加一个示例 Jupyter 笔记本来展示此功能。
示例笔记本可以在此文件夹中找到。
创建拉取请求#
请参阅这些说明以针对主 LlamaIndex 存储库打开拉取请求。