从一段文本中提取预定义的实体。
模块 named_entity_extractor
NamedEntityExtractorBackend
用于命名实体识别的 NLP 后端。
HUGGING_FACE
使用 Hugging Face 模型和管道。
SPACY
使用 spaCy 模型和管道。
NamedEntityExtractorBackend.from_str
@staticmethod
def from_str(string: str) -> "NamedEntityExtractorBackend"
将字符串转换为 NamedEntityExtractorBackend 枚举。
NamedEntityAnnotation
描述单个 NER 注释。
参数:
entity: 实体标签。start: 实体在文档中的起始索引。end: 实体在文档中的结束索引。score: 模型计算的分数。
NamedEntityExtractor
注释文档集合中的命名实体。
该组件支持两个后端:Hugging Face 和 spaCy。前者可与 Hugging Face 模型中心的任何序列分类模型一起使用,后者可与任何包含 NER 组件的spaCy 模型一起使用。注释将作为元数据存储在文档中。
使用示例
from haystack import Document
from haystack.components.extractors.named_entity_extractor import NamedEntityExtractor
documents = [
Document(content="I'm Merlin, the happy pig!"),
Document(content="My name is Clara and I live in Berkeley, California."),
]
extractor = NamedEntityExtractor(backend="hugging_face", model="dslim/bert-base-NER")
extractor.warm_up()
results = extractor.run(documents=documents)["documents"]
annotations = [NamedEntityExtractor.get_stored_annotations(doc) for doc in results]
print(annotations)
NamedEntityExtractor.__init__
def __init__(
*,
backend: Union[str, NamedEntityExtractorBackend],
model: str,
pipeline_kwargs: Optional[dict[str, Any]] = None,
device: Optional[ComponentDevice] = None,
token: Optional[Secret] = Secret.from_env_var(["HF_API_TOKEN", "HF_TOKEN"],
strict=False)
) -> None
创建命名实体提取器组件。
参数:
backend: 用于 NER 的后端。model: 模型名称或本地磁盘上的模型路径。取决于后端。pipeline_kwargs: 传递给管道的关键字参数。管道可以覆盖这些参数。取决于后端。device: 加载模型的设备。如果None,默认设备会自动选择。如果设备/设备映射在pipeline_kwargs中指定,它将覆盖此参数(仅适用于 HuggingFace 后端)。token: 用于从 Hugging Face 下载私有模型的 API 令牌。
NamedEntityExtractor.warm_up
def warm_up()
初始化组件。
引发:
ComponentError: 如果后端未能成功初始化。
NamedEntityExtractor.run
@component.output_types(documents=list[Document])
def run(documents: list[Document], batch_size: int = 1) -> dict[str, Any]
注释每个文档中的命名实体,并将注释存储在文档的元数据中。
参数:
documents: 要处理的文档。batch_size: 用于处理文档的批处理大小。
引发:
ComponentError: 如果后端未能处理文档。
返回值:
已处理的文档。
NamedEntityExtractor.to_dict
def to_dict() -> dict[str, Any]
将组件序列化为字典。
返回值:
包含序列化数据的字典。
NamedEntityExtractor.from_dict
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "NamedEntityExtractor"
从字典反序列化组件。
参数:
data: 要反序列化的字典。
返回值:
反序列化后的组件。
NamedEntityExtractor.initialized
@property
def initialized() -> bool
返回提取器是否已准备好注释文本。
NamedEntityExtractor.get_stored_annotations
@classmethod
def get_stored_annotations(
cls, document: Document) -> Optional[list[NamedEntityAnnotation]]
返回文档的命名实体注释(如果存在)存储在其元数据中。
参数:
document: 要获取注释的文档。
返回值:
存储的注释。
模块 llm_metadata_extractor
LLMMetadataExtractor
使用大型语言模型(LLM)从文档中提取元数据。
通过向 LLM 提供一个生成元数据的提示来提取元数据。
此组件期望的输入是文档列表和提示。提示应包含一个名为document 的变量,该变量将指向文档列表中的单个文档。因此,要访问文档内容,您可以使用{{ document.content }} 在提示中。
该组件将对列表中的每个文档运行 LLM 并从中提取元数据。元数据将添加到文档的元数据字段。如果 LLM 未能从文档中提取元数据,则该文档将被添加到failed_documents 列表中。失败的文档将在其元数据中包含键metadata_extraction_error 和metadata_extraction_response。可以使用此处的metadata_extraction_response 和metadata_extraction_error 再次使用另一个提取器重新运行这些文档来提取元数据。
from haystack import Document
from haystack.components.extractors.llm_metadata_extractor import LLMMetadataExtractor
from haystack.components.generators.chat import OpenAIChatGenerator
NER_PROMPT = '''
-Goal-
Given text and a list of entity types, identify all entities of those types from the text.
-Steps-
1. Identify all entities. For each identified entity, extract the following information:
- entity: Name of the entity
- entity_type: One of the following types: [organization, product, service, industry]
Format each entity as a JSON like: {"entity": <entity_name>, "entity_type": <entity_type>}
2. Return output in a single list with all the entities identified in steps 1.
-Examples-
######################
Example 1:
entity_types: [organization, person, partnership, financial metric, product, service, industry, investment strategy, market trend]
text: Another area of strength is our co-brand issuance. Visa is the primary network partner for eight of the top
10 co-brand partnerships in the US today and we are pleased that Visa has finalized a multi-year extension of
our successful credit co-branded partnership with Alaska Airlines, a portfolio that benefits from a loyal customer
base and high cross-border usage.
We have also had significant co-brand momentum in CEMEA. First, we launched a new co-brand card in partnership
with Qatar Airways, British Airways and the National Bank of Kuwait. Second, we expanded our strong global
Marriott relationship to launch Qatar's first hospitality co-branded card with Qatar Islamic Bank. Across the
United Arab Emirates, we now have exclusive agreements with all the leading airlines marked by a recent
agreement with Emirates Skywards.
And we also signed an inaugural Airline co-brand agreement in Morocco with Royal Air Maroc. Now newer digital
issuers are equally
------------------------
output:
{"entities": [{"entity": "Visa", "entity_type": "company"}, {"entity": "Alaska Airlines", "entity_type": "company"}, {"entity": "Qatar Airways", "entity_type": "company"}, {"entity": "British Airways", "entity_type": "company"}, {"entity": "National Bank of Kuwait", "entity_type": "company"}, {"entity": "Marriott", "entity_type": "company"}, {"entity": "Qatar Islamic Bank", "entity_type": "company"}, {"entity": "Emirates Skywards", "entity_type": "company"}, {"entity": "Royal Air Maroc", "entity_type": "company"}]}
#############################
-Real Data-
######################
entity_types: [company, organization, person, country, product, service]
text: {{ document.content }}
######################
output:
'''
docs = [
Document(content="deepset was founded in 2018 in Berlin, and is known for its Haystack framework"),
Document(content="Hugging Face is a company that was founded in New York, USA and is known for its Transformers library")
]
chat_generator = OpenAIChatGenerator(
generation_kwargs={
"max_tokens": 500,
"temperature": 0.0,
"seed": 0,
"response_format": {"type": "json_object"},
},
max_retries=1,
timeout=60.0,
)
extractor = LLMMetadataExtractor(
prompt=NER_PROMPT,
chat_generator=generator,
expected_keys=["entities"],
raise_on_failure=False,
)
extractor.warm_up()
extractor.run(documents=docs)
>> {'documents': [
Document(id=.., content: 'deepset was founded in 2018 in Berlin, and is known for its Haystack framework',
meta: {'entities': [{'entity': 'deepset', 'entity_type': 'company'}, {'entity': 'Berlin', 'entity_type': 'city'},
{'entity': 'Haystack', 'entity_type': 'product'}]}),
Document(id=.., content: 'Hugging Face is a company that was founded in New York, USA and is known for its Transformers library',
meta: {'entities': [
{'entity': 'Hugging Face', 'entity_type': 'company'}, {'entity': 'New York', 'entity_type': 'city'},
{'entity': 'USA', 'entity_type': 'country'}, {'entity': 'Transformers', 'entity_type': 'product'}
]})
]
'failed_documents': []
}
>>
LLMMetadataExtractor.__init__
def __init__(prompt: str,
chat_generator: ChatGenerator,
expected_keys: Optional[list[str]] = None,
page_range: Optional[list[Union[str, int]]] = None,
raise_on_failure: bool = False,
max_workers: int = 3)
初始化 LLMMetadataExtractor。
参数:
prompt: 将用于 LLM 的提示。chat_generator: 代表 LLM 的 ChatGenerator 实例。为了使组件正常工作,LLM 应配置为返回 JSON 对象。例如,在使用 OpenAIChatGenerator 时,应传递{"response_format": {"type": "json_object"}}在generation_kwargs.expected_keys: LLM 的 JSON 输出中预期的键。page_range: 要从中提取元数据的页面范围。例如,page_range=['1', '3'] 将从每个文档的第一页和第三页提取元数据。它还接受可打印的范围字符串,例如:['1-3', '5', '8', '10-12'] 将从第 1、2、3、5、8、10、11、12 页提取元数据。如果为 None,则将从文档列表中每个文档的整个文档中提取元数据。此参数是可选的,并且可以在run方法中。raise_on_failure: 在 Generator 执行期间或 JSON 输出验证失败时是否引发错误。max_workers: 在线程池执行程序中使用最大线程数。
LLMMetadataExtractor.warm_up
def warm_up()
预热 LLM 提供商组件。
LLMMetadataExtractor.to_dict
def to_dict() -> dict[str, Any]
将组件序列化为字典。
返回值:
包含序列化数据的字典。
LLMMetadataExtractor.from_dict
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "LLMMetadataExtractor"
从字典反序列化组件。
参数:
data: 包含序列化数据的字典。
返回值:
组件的实例。
LLMMetadataExtractor.run
@component.output_types(documents=list[Document],
failed_documents=list[Document])
def run(documents: list[Document],
page_range: Optional[list[Union[str, int]]] = None)
使用大型语言模型从文档中提取元数据。
如果如果提供了page_range,则将从指定的页面范围提取元数据。此组件会将文档拆分成页面,并从指定的页面范围提取元数据。如果未提供
page_range,则将从整个文档中提取元数据。原始文档将返回并更新提取的元数据。
参数:
documents: 要从中提取元数据的文档列表。page_range: 要从中提取元数据的页面范围。例如,page_range=['1', '3'] 将从每个文档的第一页和第三页提取元数据。它还接受可打印的范围字符串,例如:['1-3', '5', '8', '10-12'] 将从第 1、2、3、5、8、10、11、12 页提取元数据。如果为 None,则将从文档列表中每个文档的整个文档中提取元数据。
返回值:
一个字典,包含键
- "documents": 已成功更新提取元数据的文档列表。
- "failed_documents": 提取元数据失败的文档列表。这些文档将在其元数据中包含 "metadata_extraction_error" 和 "metadata_extraction_response"。可以使用此处的元数据再次使用提取器重新运行这些文档来提取元数据。
模块 image/llm_document_content_extractor
LLMDocumentContentExtractor
使用支持视觉的大型语言模型(LLM)从基于图像的文档中提取文本内容。
此组件使用 DocumentToImageContent 组件将每个输入文档转换为图像,使用提示指导 LLM 如何提取内容,并使用 ChatGenerator 根据提供的提示提取结构化的文本内容。
提示不得包含变量;它应该只包含对 LLM 的指令。图像数据和提示一起作为聊天消息传递给 LLM。
对于 LLM 无法提取内容的文档,将返回一个单独的failed_documents 列表。这些失败的文档将在其元数据中包含一个content_extraction_error 条目。此元数据可用于调试或稍后重新处理文档。
使用示例
from haystack import Document
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.extractors.image import LLMDocumentContentExtractor
chat_generator = OpenAIChatGenerator()
extractor = LLMDocumentContentExtractor(chat_generator=chat_generator)
documents = [
Document(content="", meta={"file_path": "image.jpg"}),
Document(content="", meta={"file_path": "document.pdf", "page_number": 1}),
]
updated_documents = extractor.run(documents=documents)["documents"]
print(updated_documents)
# [Document(content='Extracted text from image.jpg',
# meta={'file_path': 'image.jpg'}),
# ...]
LLMDocumentContentExtractor.__init__
def __init__(*,
chat_generator: ChatGenerator,
prompt: str = DEFAULT_PROMPT_TEMPLATE,
file_path_meta_field: str = "file_path",
root_path: Optional[str] = None,
detail: Optional[Literal["auto", "high", "low"]] = None,
size: Optional[tuple[int, int]] = None,
raise_on_failure: bool = False,
max_workers: int = 3)
初始化 LLMDocumentContentExtractor 组件。
参数:
chat_generator: 代表用于提取文本的 LLM 的 ChatGenerator 实例。此生成器必须支持基于视觉的输入并返回纯文本响应。prompt: 提供给 LLM 的说明性文本。它不得包含 Jinja 变量。提示应只包含关于如何提取基于图像的文档内容的说明。file_path_meta_field: Document 中包含图像或 PDF 文件路径的元数据字段。root_path: 存储文档文件的根目录路径。如果提供,文档元数据中的文件路径将相对于此路径解析。如果为 None,则文件路径被视为绝对路径。detail: 图像的可选详细程度(仅 OpenAI 支持)。可以是 "auto"、"high" 或 "low"。在处理图像时,这将传递给 chat_generator。size: 如果提供,则将图像调整为适合指定的尺寸(宽度,高度),同时保持纵横比。这可以减小文件大小、内存使用量和处理时间,这在处理具有分辨率限制的模型或向远程服务传输图像时非常有用。raise_on_failure: 如果为 True,则会引发 LLM 的异常。如果为 False,则会记录并返回失败的文档。max_workers: 使用 ThreadPoolExecutor 并行处理跨文档的 LLM 调用的最大线程数。
LLMDocumentContentExtractor.warm_up
def warm_up()
如果 ChatGenerator 具有 warm_up 方法,则预热它。
LLMDocumentContentExtractor.to_dict
def to_dict() -> dict[str, Any]
将组件序列化为字典。
返回值:
包含序列化数据的字典。
LLMDocumentContentExtractor.from_dict
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "LLMDocumentContentExtractor"
从字典反序列化组件。
参数:
data: 包含序列化数据的字典。
返回值:
组件的实例。
LLMDocumentContentExtractor.run
@component.output_types(documents=list[Document],
failed_documents=list[Document])
def run(documents: list[Document]) -> dict[str, list[Document]]
使用支持视觉的 LLM 对一系列基于图像的文档运行内容提取。
每个文档都与预定义的提示一起传递给 LLM。响应用于更新文档的内容。如果提取失败,文档将返回到failed_documents 列表中,并带有描述失败的元数据。
参数:
documents: 要处理的基于图像的文档列表。每个文档的元数据中都必须有一个有效的文件路径。
返回值:
一个字典,包含
- "documents": 已成功处理的文档,已更新提取的内容。
- "failed_documents": 处理失败的文档,带有失败元数据注释。
