使用 jina-embeddings-v2-base-en 进行法律文件分析
最后更新:2025 年 3 月 10 日
2023年10月的一个雾蒙蒙的日子,我险些被免除了陪审团义务。我对此心情复杂,因为这似乎是一桩相当有趣的案件(Google诉Sonos)。几个月后,我无聊地想知道诉讼结果如何。我可以直接看新闻,但那有什么意思呢?让我们看看AI如何解决这个问题。
Jina.ai 最近发布了 jina-embeddings-v2-base-en。它是一个开源文本嵌入模型,能够容纳多达8192个token。将文本分割成更大的块有助于理解较长的文档。该模型特别适用于法律文件分析等用例。
在此演示中,我们将构建一个 RAG 管道,以使用以下技术来发现 Google诉Sonos 案的结果
jina-embeddings-v2-base-en模型- Haystack,开源 LLM 编排框架
- Chroma,用于存储我们的向量嵌入,通过 Chroma Document Store Haystack 集成
- 开源的 Mistral 7B Instruct LLM
前提条件
- 您需要一个 Jina AI 密钥 - 在此处免费获取。
- 您还需要一个 Hugging Face 访问令牌
首先,安装所有必需的依赖项。
!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 中,retriever 与 DocumentStores 紧密耦合。如果我们传入之前初始化的 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)插入索引管道并重新运行其下方的所有代码块。
- Google诉Oracle:https://supreme.justia.com/cases/federal/us/593/18-956/case.pdf
- JACK DANIEL’S PROPERTIES, INC. v. VIP PRODUCTS LLC:https://www.supremecourt.gov/opinions/22pdf/22-148_3e04.pdf
注意:如果您想更改提示模板,还需要重新运行从定义 DocumentStore 开始的代码块。
总结
感谢您的阅读!如果您有兴趣了解更多关于此处使用的技术,请查看这些博客文章
