创建自定义文档存储
创建您自己的文档存储来管理您的文档。
自定义文档存储是您可以构建并在 Haystack 中没有现成解决方案的情况下使用的资源。例如:
- 您正在使用 Haystack 尚不支持的向量存储。
- 您需要非常具体的检索策略来搜索您的文档。
- 您想自定义 Haystack 读取和写入文档的方式。
与自定义组件类似,只要您能将自定义文档存储的代码导入到您的 Python 程序中,就可以在 Haystack 管道中使用它。最佳实践是将自定义文档存储分发为独立的集成包。
建议
在开始之前,我们提供一些建议,以确保自定义文档存储的行为与 Haystack 生态系统的其他部分保持一致。归根结底,文档存储只是用 Haystack 可以理解的方式编写的 Python 代码,但您命名、组织和分发它的方式可能会产生影响。这些建议并非强制性,但我们鼓励您尽可能遵循。
命名约定
我们建议您的文档存储遵循以下格式命名:<TECHNOLOGY>-haystack,例如:chroma-haystack。这将使其与其他组件保持一致,降低用户的使用认知负荷,并易于发现。
此命名约定适用于 Git 仓库的名称(https://github.com/your-org/example-haystack)和 Python 包的名称(example-haystack).
结构
大多数情况下,文档存储可能相当复杂,设置一个专用的 Git 仓库会很有用且面向未来。为了简化这一步骤,我们准备了一个GitHub 模板,它提供了在专用仓库中托管自定义文档存储所需的结构。
请参阅有关如何使用模板的说明,以便您入门。
打包
与任何其他Haystack 集成一样,可以通过安装额外的 Python 包来将文档存储添加到您的 Haystack 应用程序中,例如使用pip。一旦您有了托管文档存储的 Git 仓库和一个pyproject.toml 文件来创建一个example-haystack 包(使用我们的GitHub 模板),则可以直接从源代码pip install,例如:
pip install git+https://github.com/your-org/example-haystack.git
虽然快速交付原型非常实用,但如果您希望其他人使用您的自定义文档存储,我们建议您在 PyPI 上发布一个包,这样它就可以被版本化并可以通过简单的
pip install example-haystack
提示
我们的GitHub 模板附带了一个 GitHub 工作流,该工作流将自动将文档存储包发布到 PyPI。
文档
我们建议您通过详细的 README 文件来彻底记录您的自定义文档存储,并可能使用静态生成器来生成 API 文档。
作为参考,请查看neo4j-haystack 仓库及其文档页面。
实现
DocumentStore 协议
您可以使用任何 Python 类作为文档存储,前提是它实现了 Haystack 中定义的DocumentStore Python 协议的所有方法。
class DocumentStore(Protocol):
def to_dict(self) -> Dict[str, Any]:
"""
Serializes this store to a dictionary.
"""
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "DocumentStore":
"""
Deserializes the store from a dictionary.
"""
def count_documents(self) -> int:
"""
Returns the number of documents stored.
"""
def filter_documents(self, filters: Optional[Dict[str, Any]] = None) -> List[Document]:
"""
Returns the documents that match the filters provided.
"""
def write_documents(self, documents: List[Document], policy: DuplicatePolicy = DuplicatePolicy.FAIL) -> int:
"""
Writes (or overwrites) documents into the DocumentStore, return the number of documents that was written.
"""
def delete_documents(self, document_ids: List[str]) -> None:
"""
Deletes all documents with a matching document_ids from the DocumentStore.
"""
该DocumentStore 接口支持您通常会对数据库或存储系统执行的基本 CRUD 操作,以及大多数通用组件,如DocumentWriter 使用它。
附加方法
通常,文档存储会附带一些附加方法,这些方法可以提供高级搜索功能。这些方法不属于DocumentStore 协议,也不遵循任何特定约定。我们这样设计是为了在文档存储使用底层数据库的任何特定功能时,提供最大的灵活性。
例如,当您的文档存储定义了一个特定的search 方法,该方法接受一组仅在特定向量数据库上下文中才有意义的长参数列表时,Haystack 不会从中阻碍。通常,Retriever 组件会使用此附加搜索方法。
Retrievers (检索器)
为了充分利用您的自定义文档存储,在大多数情况下,您需要创建一到多个配套的 Retriever,这些 Retriever 会使用上述附加搜索方法。在继续实现自定义 Retriever 之前,了解 Haystack 文档中关于Retrievers 的一般信息可能会有所帮助。
从实现角度来看,Haystack 中的 Retriever 与任何其他自定义组件一样。有关更多详细信息,请参阅创建自定义组件文档页面。
虽然不是强制性的,但我们鼓励您为自定义 Retriever 遵循更具体的命名约定。
序列化
Haystack 要求每个组件都可以用 Python 字典表示,以便正确实现序列化。某些组件,如 Retriever 和 Writer,会维护对 Document Store 实例的引用。因此,DocumentStore 类应实现from_dict 和to_dict 方法。这允许在从文件读取管道后重新构建实例。
对于序列化自定义文档存储的内容,可以考虑一个使用 IP 地址和数据库名称创建的数据库客户端。在构造要返回的字典时,to_dict,您会存储 IP 地址和数据库名称,而不是数据库客户端实例。
Secrets 管理
用户很有可能需要提供敏感数据,例如密码、API 密钥或私有 URL,来创建文档存储实例。这些敏感数据在明文传递时可能会泄露。
Haystack 有一种特殊的方式可以将敏感数据包装到称为 Secrets 的特殊对象中。这可以防止数据在序列化往返过程中泄露。我们强烈建议广泛使用此功能来确保数据安全(防患于未然!)。
您可以在 Haystack 文档中详细了解 Secrets 管理。
测试
Haystack 附带了一些您可以在自定义文档存储中使用的测试功能。特别是,一个继承自DocumentStoreBaseTests 的空类将已经运行了任何文档存储在正常工作之前都应通过的标准测试。
实现技巧
- 学习如何编写自定义文档存储的最佳方法是查看现有的:
InMemoryDocumentStore(它是 Haystack 的一部分),或ElasticsearchDocumentStore(它是核心集成)都是不错的起点。 - 从头开始时,可以更容易地一次创建一个文档存储协议的四个 CRUD 方法,并逐个进行测试。例如:实现
- count_documents
的逻辑. - 在您的
test_document_store.py模块中,定义测试类TestDocumentStore(CountDocumentsTest)。请注意,我们仅继承自特定的测试混合类CountDocumentsTest. - 使测试通过。
- count_documents
write_documents. - 更改
test_document_store.py,使您的类现在也继承自WriteDocumentsTest混合类:TestDocumentStore(CountDocumentsTest, WriteDocumentsTest). - 继续迭代剩余的方法。
- count_documents
- 有一个 Notebook,用户可以在其中尝试您的文档存储的完整管道,这有助于提高采纳率,并且是一个很好的文档来源。我们的haystack-cookbook 仓库具有良好的可见性,我们鼓励贡献者创建 PR 并添加他们自己的。
在集成页面获得推荐
集成网页https://haystack.com.cn/integrations 使 Haystack 集成对社区可见,这是一个展示您工作的绝佳机会。一旦您的文档存储可用并正确打包,您就可以在haystack-integrations GitHub 仓库中打开一个 PR 来添加一个集成磁贴。
有关更多详细信息,请参阅集成文档页面。
更新于 1 年前
