宣布 LlamaCloud 全面可用(以及我们的 1900 万美元 A 轮融资)!
LlamaIndex

2024-04-29

使用 LlamaIndex、Fireworks 和 MongoDB 简化知识工作

这是 Team CLAB 的一篇客座文章,他们在我们最近与 MongoDB 联合举办的黑客马拉松中获得了“LlamaIndex 最佳应用奖”。

想象一下:你正在深入一个编码项目,然后关于某个特定工具或库的一个关键问题出现了。你开始了令人头疼的文档查找——搜索维基、常见问题,甚至为特定工具(如 LlamaIndex、FireworksAI 或其他任何工具)启动一个单独的聊天机器人。这太令人沮丧了!🤯 我们想改变这一切。

这就是为什么 Team CLAB 构建了 LlamaWorksDB(试试看!),你友好的 AI 驱动文档向导 ✨。不再需要零散的搜索!它通过一个统一的聊天机器人界面,接入了我们黑客马拉松多个赞助商的知识,包括 LlamaIndex、Fireworks.ai 和 MongoDB。需要 MongoDB 文档中的解释?没问题!想要 Fireworks.ai 的代码示例?轻松搞定!

基础:LlamaIndex 和数据摄取

LlamaIndex 是 LlamaWorksDB 的核心与灵魂。它就像一个超万能的工具箱,用来处理各种文档!我们主要使用了他们的开源读取器直接从网站抓取信息。我们做了一个很酷的技巧,就是定制了 SimpleWebPageReader。我们教它忽略网站导航栏,这为我们节省了大量宝贵的 tokens。💪 虽然这对于文档网站非常有效,但我们使用 LlamaIndex 的 GithubRepositoryReader 轻松地读取了每个仓库。

from llama_index.readers.web import SimpleWebPageReader
import re

class LlamaDocsPageReader(SimpleWebPageReader):
   def load_data(self, urls):
       documents = super().load_data(urls)
       processed_documents = []
       for doc in documents:
           processed_doc = self.process_document(doc)
           processed_documents.append(processed_doc)
       return processed_documents

   def process_document(self, document):
       # Split the document text by "Table of Contents"
       pattern = r'(?i)\n\n*table\s*of\s*contents\n\n*'
       parts = re.split(pattern, document.text, maxsplit=1)
       # If there is a part after "Table of Contents", use it as the document text
       if len(parts) > 1:
           document.text = "Table of contents".join(parts[1:])
       return document


如何划分文档很有趣。LlamaIndex 提供了从基础的 SentenceSplitter 到其 SemanticNodeParser 的多种选项,后者使用 AI 对相似的想法进行分组。我们选择了后者,以获得大小合适、有意义的文本块。

最后,我们嵌入了每个“节点”,并将每个节点作为一个文档发送到 MongoDB。这效率真是高!MongoDB 存储了文本、元数据以及我们的嵌入——这非常适合我们想要构建的那种搜索。我们通过 Fireworks 使用了 Nomic 灵活的嵌入模型,这让我们能够微调维度以实现最高效率。

# FireworksEmbedding defaults to using model
embed_model = FireworksEmbedding(api_key=os.getenv('FIREWORKS_API_KEY'),
                                model="nomic-ai/nomic-embed-text-v1.5",
                                embed_batch_size=10,
                                dimensions=768 # can range from 64 to 768
                                )

# the tried and true sentence splitter
text_splitter = SentenceSplitter(chunk_size=1000, chunk_overlap=200)
# the semantic splitter uses our embedding model to group semantically related sentences together
semantic_parser = SemanticSplitterNodeParser(embed_model=embed_model)

# we set up MongoDB as our document and vector database
vector_store = MongoDBAtlasVectorSearch(
   pymongo.MongoClient(os.getenv('MONGO_URI')),
   db_name="fireParse",
   collection_name="llamaIndexDocs",
   index_name="llama_docs_index"
)

#finally we use LlamaIndex's pipeline to string this all together
pipeline = IngestionPipeline(
   transformations=[
       semantic_parser, #can replace with text_splitter
       embed_model,
   ],
   vector_store=vector_store,
)

设置完成后,我们就可以从 MongoDB 中的 URL 创建文档了!下面是使用三个 URL 的示例,但我们使用了数百个。

example_urls = [
   "https://docs.llamaindex.org.cn/en/stable/examples/cookbooks/llama3_cookbook",
   "https://docs.llamaindex.org.cn/en/stable/examples/cookbooks/anthropic_haiku/",
  "https://docs.llamaindex.org.cn/en/stable/examples/vector_stores/MongoDBAtlasVectorSearch/"
]

# read in the documents and pass them through our pipeline
documents = LlamaDocsPageReader(html_to_text=True).load_data(example_urls)
pipeline.run(documents=documents, show_progress=True)

您可以在 MongoDB 中看到我们的文档包含文本、嵌入(768 维)和元数据。

通过管道处理后生成的 MongoDB Atlas 中的示例文档

用于向量搜索的 MongoDB Atlas

MongoDB Atlas 是我们存储文档文本和嵌入的首选。它具有令人难以置信的多功能性!在 Atlas 中设置向量搜索轻而易举,这使我们能够快速找到最相关的文档块。此外,LlamaIndex 的元数据解析与 Atlas 完美配合——我们可以轻松地根据文档来源或主题等信息过滤结果。

设置向量搜索: 这非常简单!我们只需要指定以下几项:

  • 文档中嵌入字段的路径。
  • 嵌入维度大小。
  • 相似度指标(例如,余弦相似度)。
  • 它是一个向量索引。

过滤能力(可选): 为了实现更精细的控制,我们可以添加我们希望用于过滤搜索结果的字段路径(例如,公司名称)。

无论您是构建复杂的 Web 应用还是快速的 Streamlit 原型,LlamaIndex ChatEngines 都能满足您的需求。它们毫不费力地管理对话历史记录,让您执行闪电般的向量搜索,并解锁一整套强大的工具。

我们直接从可靠的 MongoDB 索引构建了 ChatEngine。这种集成出奇地简单

def get_index():
   logger.info("Connecting to index from MongoDB...")
   store = MongoDBAtlasVectorSearch(
       db_name=os.environ["MONGODB_DATABASE"],
       collection_name=os.environ["MONGODB_VECTORS"],
       index_name=os.environ["MONGODB_VECTOR_INDEX"],
   )
   index = VectorStoreIndex.from_vector_store(store)
   logger.info("Finished connecting to index from MongoDB.")
   return index

index = get_index()
index.as_chat_engine(
    llm = Fireworks(
             api_key=env_vars['FIREWORKS_API_KEY'],
             model="accounts/fireworks/models/mixtral-8x22b-instruct" #Can be changed out for Llama3
             )
    chat_mode="best", 
    context_prompt=(
           """ You are a software developer bot that is an expert at reading over documentation to answer questions.
           Use the relevant documents for context:
           {context_str}
           \nInstruction: Use the previous chat history, or the context above, to interact and help the user.
           """
           ),
    verbose=True
    )

create-llama:从想法到应用,创纪录的速度

Create-Llama 真的给我们留下了深刻的印象。通常,构建一个全栈应用需要时间,但 Create-Llama 让我们在不到 15 分钟内就运行起来了!我们所做的就是将它指向我们的向量数据库,并提供一些基本信息。说实话,它让开发变得非常愉快!这篇博客文章更详细地介绍了如何使用 create-llama。

create-llama 设置屏幕
create-llama 应用,已定制并准备就绪

部署:Render 和 Vercel

为了让 LlamaWorksDB 具备生产就绪性并易于访问,我们转向了 RenderVercel。Render 非常适合我们的 Python FastAPI 后端,因为它专注于部署便捷性和可伸缩性。Vercel 无缝处理了我们的 Next.js 前端——我们喜欢它以开发者为中心的方法和轻松的构建过程。这两个平台都让部署变得轻而易举,让我们能够专注于编码而不是复杂的基础设施设置。

未来方向

我们在黑客马拉松中取得的成功仅仅是个开始。我们设想 LlamaWorksDB 发展成为一个开发者在技术文档中寻找答案的强大工具。以下是我们对其发展的构想:

  • 增强检索: 我们很高兴能尝试 LlamaIndex 的强大功能,例如 MultiVectorSearch,以进一步改进我们的结果。集成不同的 LLM 将为 LlamaWorksDB 如何理解和交互技术内容开辟新的可能性。
  • 专注于文档: 我们希望加倍努力,使 LlamaWorksDB 成为导航文档的终极工具。这意味着探索专门为理解复杂技术信息而设计的技术和工具。

LlamaWorksDB 是一个处于 Beta 阶段的开源项目,我们坚信协作的力量!如果您对 AI 驱动的文档工具有热情,我们邀请您:

  • 试用: 浏览我们的 GitHub 仓库,并尝试 LlamaWorksDB
  • 贡献: 帮助我们构建新功能、测试集成并改进我们的搜索能力。
  • 分享您的反馈: 告诉我们如何才能让 LlamaWorksDB 变得更好。

让我们一起彻底改变开发者与文档交互的方式!

🔗 探索我们的项目并加入创新: https://github.com/clab2024/clab/

https://clab-ui.vercel.app/ (前端) (使用免费配额,响应较慢)

https://clab.onrender.com/docs (后端)

认识 Team CLAB!🎉

  • Chris Wood:冉冉升起的技术奇才,即将毕业,并从他在 Tutello 的实习中获得了宝贵的见解。
  • Leo Walker:数据科学家,拥有军事退伍军人的纪律和精确性。
  • Andrew Townsend:加州州立大学圣何塞分校的计算机科学毕业生,带来了新的学术视角。
  • Barath Subramaniam:Adobe 产品安全 AI 和数据工程背后的战略策划者。Twitter: @baraths84
Team CLAB(加上 Laurie)