📘 **TELUS Agriculture & Consumer Goods** 如何通过 **Haystack Agents** 转变促销交易

使用 jina-embeddings-v2-base-en 进行法律文件分析


2023年10月的一个雾蒙蒙的日子,我险些被免除了陪审团义务。我对此心情复杂,因为这似乎是一桩相当有趣的案件(Google诉Sonos)。几个月后,我无聊地想知道诉讼结果如何。我可以直接看新闻,但那有什么意思呢?让我们看看AI如何解决这个问题。

Jina.ai 最近发布了 jina-embeddings-v2-base-en。它是一个开源文本嵌入模型,能够容纳多达8192个token。将文本分割成更大的块有助于理解较长的文档。该模型特别适用于法律文件分析等用例。

在此演示中,我们将构建一个 RAG 管道,以使用以下技术来发现 Google诉Sonos 案的结果

前提条件

首先,安装所有必需的依赖项。

!pip3 install pypdf
!pip install haystack-ai jina-haystack chroma-haystack "huggingface_hub>=0.22.0"

然后输入我们的凭证。

from getpass import getpass
import os

os.environ["JINA_API_KEY"]  = getpass("JINA api key:")
os.environ["HF_API_TOKEN"] = getpass("Enter your HuggingFace api token: ")

构建一个索引管道

高层次上,LinkContentFetcher 从其 URL 中提取此文档。然后,我们将其从 PDF 转换为 Haystack 可以理解的 Document 对象。

我们通过删除空格和冗余子字符串来预处理它。然后将其分割成块,生成嵌入,并将这些嵌入写入 ChromaDocumentStore

from haystack_integrations.document_stores.chroma import ChromaDocumentStore
document_store = ChromaDocumentStore()
from haystack import Pipeline

from haystack.components.fetchers import LinkContentFetcher
from haystack.components.converters import PyPDFToDocument
from haystack.components.writers import DocumentWriter
from haystack.components.preprocessors import DocumentCleaner
from haystack.components.preprocessors import DocumentSplitter
from haystack_integrations.components.retrievers.chroma import ChromaEmbeddingRetriever
from haystack.document_stores.types import DuplicatePolicy

from haystack_integrations.components.embedders.jina import JinaDocumentEmbedder
from haystack_integrations.components.embedders.jina import JinaTextEmbedder

fetcher = LinkContentFetcher()
converter = PyPDFToDocument()
# remove repeated substrings to get rid of headers/footers
cleaner = DocumentCleaner(remove_repeated_substrings=True)

# Since jina-v2 can handle 8192 tokens, 500 words seems like a safe chunk size
splitter = DocumentSplitter(split_by="word", split_length=500)

# DuplicatePolicy.SKIP is optional but helps avoid errors if you want to re-run the pipeline
writer = DocumentWriter(document_store=document_store, policy=DuplicatePolicy.SKIP)

retriever = ChromaEmbeddingRetriever(document_store=document_store)

# There are both small and large embedding models available, depending on your computing resources and requirements.
# Here we're using the larger model.
document_embedder = JinaDocumentEmbedder(model="jina-embeddings-v2-base-en")

indexing_pipeline = Pipeline()
indexing_pipeline.add_component(instance=fetcher, name="fetcher")
indexing_pipeline.add_component(instance=converter, name="converter")
indexing_pipeline.add_component(instance=cleaner, name="cleaner")
indexing_pipeline.add_component(instance=splitter, name="splitter")
indexing_pipeline.add_component(instance=document_embedder, name="embedder")
indexing_pipeline.add_component(instance=writer, name="writer")

indexing_pipeline.connect("fetcher.streams", "converter.sources")
indexing_pipeline.connect("converter.documents", "cleaner.documents")
indexing_pipeline.connect("cleaner.documents", "splitter.documents")
indexing_pipeline.connect("splitter.documents", "embedder.documents")
indexing_pipeline.connect("embedder.documents", "writer.documents")

# This case references Google V Sonos, October 2023
urls = ["https://cases.justia.com/federal/district-courts/california/candce/3:2020cv06754/366520/813/0.pdf"]

indexing_pipeline.run(data={"fetcher": {"urls": urls}})

查询管道

现在,真正的乐趣开始了。让我们创建一个查询管道,以便我们可以实际开始提问。我们编写了一个提示,允许我们将文档传递给 Mistral-7B LLM。然后,我们通过 HuggingFaceAPIGenerator 初始化 LLM。

要使用此模型,您需要在此处接受条款:https://hugging-face.cn/mistralai/Mixtral-8x7B-Instruct-v0.1

在 Haystack 2.0 中,retrieverDocumentStores 紧密耦合。如果我们传入之前初始化的 retriever,此管道就可以访问我们生成的嵌入,并将它们传递给 LLM。


from haystack.components.generators import HuggingFaceAPIGenerator
from haystack.components.builders.prompt_builder import PromptBuilder

from haystack_integrations.components.embedders.jina import JinaTextEmbedder
prompt = """ Answer the question, based on the
content in the documents. If you can't answer based on the documents, say so.

Documents:
{% for doc in documents %}
  {{doc.content}}
{% endfor %}

question: {{question}}
"""

text_embedder = JinaTextEmbedder(model="jina-embeddings-v2-base-en")
generator = HuggingFaceAPIGenerator(
    api_type="serverless_inference_api",
    api_params={"model": "mistralai/Mixtral-8x7B-Instruct-v0.1"})  


prompt_builder = PromptBuilder(template=prompt)
query_pipeline = Pipeline()
query_pipeline.add_component("text_embedder",text_embedder)
query_pipeline.add_component(instance=prompt_builder, name="prompt_builder")
query_pipeline.add_component("retriever", retriever)
query_pipeline.add_component("generator", generator)

query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
query_pipeline.connect("retriever.documents", "prompt_builder.documents")
query_pipeline.connect("prompt_builder.prompt", "generator.prompt")

是时候提问了!

question = "Summarize what happened in Google v. Sonos"

result = query_pipeline.run(data={"text_embedder":{"text": question},
                                  "retriever": {"top_k": 3},
                                  "prompt_builder":{"question": question},
                                  "generator": {"generation_kwargs": {"max_new_tokens": 350}}})

print(result['generator']['replies'][0])

您可以尝试的其他问题

  • If This Then That 在 Google诉Sonos 案中扮演了什么角色?
  • Google诉Sonos 案由哪位法官审理?
  • Sonos 应该采取哪些不同的做法?

要探索的备选案例

索引管道的编写方式使得您可以插入其他文档并对其进行分析。您可以尝试将以下 URL(或任何英文 PDF)插入索引管道并重新运行其下方的所有代码块。

注意:如果您想更改提示模板,还需要重新运行从定义 DocumentStore 开始的代码块。

总结

感谢您的阅读!如果您有兴趣了解更多关于此处使用的技术,请查看这些博客文章