191 lines
14 KiB
Markdown
191 lines
14 KiB
Markdown
|
|
## ClassDef SummaryAdapter
|
|||
|
|
**SummaryAdapter**: SummaryAdapter类的功能是实现文档摘要的生成和处理。
|
|||
|
|
|
|||
|
|
**属性**:
|
|||
|
|
- `_OVERLAP_SIZE`: 重叠大小,用于处理文档时去除重叠部分。
|
|||
|
|
- `token_max`: 最大token数量,用于限制生成摘要的最大长度。
|
|||
|
|
- `_separator`: 分隔符,默认为两个换行符,用于连接文档。
|
|||
|
|
- `chain`: MapReduceDocumentsChain对象,用于执行文档的映射、规约和摘要合并操作。
|
|||
|
|
|
|||
|
|
**代码描述**:
|
|||
|
|
SummaryAdapter类提供了文档摘要的生成、处理和优化的功能。它通过`form_summary`类方法创建实例,该方法接受两个基于语言模型的参数(`llm`和`reduce_llm`),用于生成摘要和合并摘要,以及`overlap_size`和`token_max`参数,分别控制重叠部分的大小和生成摘要的最大token数量。此外,该类还提供了`summarize`和`asummarize`方法,用于同步和异步生成文档摘要,以及`_drop_overlap`和`_join_docs`私有方法,用于处理文档中的重叠部分和连接文档。
|
|||
|
|
|
|||
|
|
从功能角度看,SummaryAdapter类在项目中被用于处理和生成知识库文档的摘要。它通过调用`form_summary`方法创建实例,并使用`summarize`方法生成文档摘要。这些摘要随后被用于更新或创建知识库的摘要信息,如在`kb_summary_api.py`文件中的`recreate_summary_vector_store`和`summary_file_to_vector_store`方法中所示。
|
|||
|
|
|
|||
|
|
**注意**:
|
|||
|
|
- 在使用SummaryAdapter类时,需要确保提供的语言模型(`llm`和`reduce_llm`)能够有效地生成和合并文档摘要。
|
|||
|
|
- `overlap_size`和`token_max`参数应根据实际需求和文档的特性进行调整,以优化摘要生成的效果。
|
|||
|
|
- 在处理大量文档或需要高性能的场景下,应考虑使用`asummarize`方法进行异步摘要生成,以提高处理效率。
|
|||
|
|
|
|||
|
|
**输出示例**:
|
|||
|
|
```python
|
|||
|
|
[Document(page_content="这是生成的文档摘要。", metadata={"file_description": "文件描述", "summary_intermediate_steps": "摘要中间步骤", "doc_ids": "文档ID列表"})]
|
|||
|
|
```
|
|||
|
|
此输出示例展示了`summarize`方法返回的文档摘要列表,其中每个摘要包含了生成的摘要内容、文件描述、摘要生成的中间步骤和文档ID列表等元数据信息。
|
|||
|
|
### FunctionDef __init__(self, overlap_size, token_max, chain)
|
|||
|
|
**__init__**: 此函数的功能是初始化SummaryAdapter对象。
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `overlap_size`: 整型,表示文本块之间重叠的大小。
|
|||
|
|
- `token_max`: 整型,表示处理的最大令牌数。
|
|||
|
|
- `chain`: MapReduceDocumentsChain对象,用于处理文档的链式操作。
|
|||
|
|
|
|||
|
|
**代码描述**:
|
|||
|
|
此`__init__`方法是`SummaryAdapter`类的构造函数,用于初始化该类的实例。在这个方法中,首先将传入的`overlap_size`参数赋值给私有变量`_OVERLAP_SIZE`,这个变量定义了在文本摘要过程中,文本块之间应该有多大的重叠部分。这是为了确保在处理长文本时,可以平滑地过渡并保持上下文的连贯性。
|
|||
|
|
|
|||
|
|
其次,`token_max`参数被直接赋值给实例变量`token_max`,这个参数限制了在文本处理过程中,可以处理的最大令牌(例如,单词或字符)数量。这是为了控制处理的复杂度和资源消耗。
|
|||
|
|
|
|||
|
|
最后,`chain`参数是一个`MapReduceDocumentsChain`对象,它被赋值给实例变量`chain`。这个对象代表了一个处理文档的链式操作序列,允许对文档进行复杂的处理流程,如分词、摘要生成等。
|
|||
|
|
|
|||
|
|
**注意**:
|
|||
|
|
- 在使用`SummaryAdapter`类时,需要确保传入的`overlap_size`和`token_max`参数是合理的,以避免处理时出现性能问题或结果不准确的情况。
|
|||
|
|
- `chain`参数需要是一个有效的`MapReduceDocumentsChain`实例,这意味着在使用之前应该正确配置链式操作。
|
|||
|
|
***
|
|||
|
|
### FunctionDef form_summary(cls, llm, reduce_llm, overlap_size, token_max)
|
|||
|
|
**form_summary**: 该函数用于形成文本摘要。
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- **llm**: 用于生成摘要的语言模型。
|
|||
|
|
- **reduce_llm**: 用于合并摘要的语言模型。
|
|||
|
|
- **overlap_size**: 文本重叠部分的大小。
|
|||
|
|
- **token_max**: 每个摘要块的最大token数量,默认为1300。
|
|||
|
|
|
|||
|
|
**代码描述**:
|
|||
|
|
`form_summary`函数是`SummaryAdapter`类的一个方法,负责创建一个文本摘要的处理流程。该流程包括使用语言模型生成摘要、合并摘要以及处理文本块以确保每个摘要块的长度不超过指定的最大token数量。函数首先定义了文档格式化的模板,然后定义了一个处理链`llm_chain`,用于生成摘要。接着,定义了另一个处理链`reduce_llm_chain`,用于合并这些摘要。最后,通过`MapReduceDocumentsChain`将生成摘要和合并摘要的流程结合起来,返回一个配置好的摘要处理流程实例。
|
|||
|
|
|
|||
|
|
在项目中,`form_summary`函数被多个地方调用,包括重建知识库摘要向量存储、将文件摘要转换为向量存储以及根据文档ID将摘要转换为向量存储等场景。这些调用场景表明,`form_summary`函数是处理知识库文档摘要的核心功能,它能够根据不同的需求生成和合并文档摘要,为知识库的构建和更新提供支持。
|
|||
|
|
|
|||
|
|
**注意**:
|
|||
|
|
- 确保传入的`llm`和`reduce_llm`参数是有效的语言模型实例。
|
|||
|
|
- `overlap_size`和`token_max`参数应根据实际需求合理设置,以优化摘要生成的效果和性能。
|
|||
|
|
- 该函数返回的是一个配置好的摘要处理流程实例,需要通过调用其`summarize`方法来执行摘要的生成和合并操作。
|
|||
|
|
|
|||
|
|
**输出示例**:
|
|||
|
|
由于`form_summary`函数返回的是一个配置好的摘要处理流程实例,而非直接的摘要结果,因此没有直接的输出示例。但在使用返回的实例调用`summarize`方法后,可以得到如下格式的摘要结果:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "摘要生成成功",
|
|||
|
|
"summarize": [
|
|||
|
|
{
|
|||
|
|
"doc_id": "文档ID1",
|
|||
|
|
"summary": "这里是文档摘要内容..."
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"doc_id": "文档ID2",
|
|||
|
|
"summary": "这里是另一个文档的摘要内容..."
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
这个示例展示了摘要处理流程实例在处理完文档后返回的摘要结果格式,其中包含了文档的ID和对应的摘要内容。
|
|||
|
|
***
|
|||
|
|
### FunctionDef summarize(self, file_description, docs)
|
|||
|
|
**summarize**: 此函数的功能是同步调用异步生成文档摘要的方法。
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `file_description`: 字符串类型,描述文件的内容。
|
|||
|
|
- `docs`: `DocumentWithVSId` 类型的列表,默认为空列表。这些文档将被用来生成摘要。
|
|||
|
|
|
|||
|
|
**代码描述**:
|
|||
|
|
`summarize` 函数是 `SummaryAdapter` 类的一个方法,用于同步调用异步方法 `asummarize` 生成文档的摘要。该函数首先根据 Python 版本检查来决定如何获取或创建事件循环。如果 Python 版本低于 3.10,它将使用 `asyncio.get_event_loop()` 来获取当前事件循环;对于 Python 3.10 及以上版本,它尝试使用 `asyncio.get_running_loop()` 获取正在运行的事件循环,如果失败,则创建一个新的事件循环并设置为当前事件循环。之后,函数通过事件循环的 `run_until_complete` 方法同步调用 `asummarize` 方法,并传入文件描述和文档列表作为参数,最终返回一个包含 `Document` 对象的列表。
|
|||
|
|
|
|||
|
|
**注意**:
|
|||
|
|
- 该函数是一个同步包装器,用于在同步代码中调用异步方法 `asummarize`,确保异步方法能够在同步环境中正确执行。
|
|||
|
|
- 如果传入的文档列表 `docs` 为空,`asummarize` 方法将直接返回一个空的 `Document` 对象列表。
|
|||
|
|
- 在使用该函数时,需要注意 Python 版本的兼容性问题,以确保事件循环能够正确获取或创建。
|
|||
|
|
|
|||
|
|
**输出示例**:
|
|||
|
|
调用 `summarize` 函数可能会返回如下格式的列表:
|
|||
|
|
```python
|
|||
|
|
[
|
|||
|
|
Document(
|
|||
|
|
page_content="这里是合并后的摘要内容。",
|
|||
|
|
metadata={
|
|||
|
|
"file_description": "文件描述信息",
|
|||
|
|
"summary_intermediate_steps": "中间步骤的信息",
|
|||
|
|
"doc_ids": "文档ID列表"
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
这个列表包含一个 `Document` 对象,其中 `page_content` 属性包含了生成的摘要内容,`metadata` 属性包含了文件描述、中间步骤的信息和文档ID列表。
|
|||
|
|
***
|
|||
|
|
### FunctionDef asummarize(self, file_description, docs)
|
|||
|
|
**asummarize**: 此函数的功能是异步生成文档的摘要。
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `file_description`: 字符串类型,描述文件的内容。
|
|||
|
|
- `docs`: `DocumentWithVSId` 类型的列表,默认为空列表。这些文档将被用来生成摘要。
|
|||
|
|
|
|||
|
|
**代码描述**:
|
|||
|
|
`asummarize` 函数是`SummaryAdapter`类的一个异步方法,用于处理文档摘要的生成。该过程分为两个主要部分:首先,对每个文档进行处理,得到每个文档的摘要;其次,将这些摘要合并成一个最终的摘要,并且可以返回中间步骤的信息。
|
|||
|
|
|
|||
|
|
在处理文档摘要时,该函数首先记录开始生成摘要的日志信息。然后,通过调用`chain.combine_docs`方法,传入文档列表和任务简介,来生成文档的摘要。这个方法会返回合并后的摘要和中间步骤的信息。函数会打印出合并后的摘要和中间步骤的信息,以便于调试和查看。
|
|||
|
|
|
|||
|
|
函数还会记录文档ID,并将文件描述、中间步骤的信息以及文档ID作为元数据,与合并后的摘要一起封装成一个`Document`对象。最后,函数返回一个包含这个`Document`对象的列表。
|
|||
|
|
|
|||
|
|
**注意**:
|
|||
|
|
- 该函数是异步的,需要在异步环境中调用。
|
|||
|
|
- 如果传入的文档列表为空,函数将直接返回一个空的`Document`对象列表。
|
|||
|
|
- 函数中有一段被注释的代码,说明在某些情况下可能需要重新生成摘要,这部分逻辑在当前版本中未被启用。
|
|||
|
|
|
|||
|
|
**输出示例**:
|
|||
|
|
调用`asummarize`函数可能会返回如下格式的列表:
|
|||
|
|
```python
|
|||
|
|
[
|
|||
|
|
Document(
|
|||
|
|
page_content="这里是合并后的摘要内容。",
|
|||
|
|
metadata={
|
|||
|
|
"file_description": "文件描述信息",
|
|||
|
|
"summary_intermediate_steps": "中间步骤的信息",
|
|||
|
|
"doc_ids": "文档ID列表"
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
这个列表包含一个`Document`对象,其中`page_content`属性包含了生成的摘要内容,`metadata`属性包含了文件描述、中间步骤的信息和文档ID列表。
|
|||
|
|
***
|
|||
|
|
### FunctionDef _drop_overlap(self, docs)
|
|||
|
|
**_drop_overlap**: 此函数的功能是去除文档列表中页面内容句子重叠的部分。
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `docs`: 一个包含DocumentWithVSId实例的列表,每个实例代表一个文档,其中包含页面内容。
|
|||
|
|
|
|||
|
|
**代码描述**:
|
|||
|
|
`_drop_overlap` 函数接收一个文档列表作为输入,这些文档通过DocumentWithVSId类的实例表示,每个实例包含一个页面内容属性。该函数的目的是处理文档列表,去除其中页面内容句子重叠的部分,以便于后续的文档处理或摘要生成过程中,减少冗余信息的干扰。
|
|||
|
|
|
|||
|
|
函数首先初始化一个空列表`merge_docs`,用于存储处理后的文档内容。然后,通过遍历输入的文档列表`docs`,逐个处理每个文档。对于列表中的第一个文档,其页面内容直接被添加到`merge_docs`列表中,作为处理的起始点。对于后续的文档,函数检查当前文档的页面内容开头是否与前一个文档的页面内容结尾存在重叠部分。如果存在重叠,函数则从当前文档的页面内容中去除这部分重叠的内容,只将非重叠部分添加到`merge_docs`列表中。
|
|||
|
|
|
|||
|
|
重叠检测和去除的具体实现是通过迭代减少前一个文档页面内容的长度,并与当前文档页面内容的开头进行比较,直到找到重叠的部分或达到一定的迭代条件。这里使用了`self._OVERLAP_SIZE`和`self._separator`两个属性来辅助确定重叠检测的条件和处理逻辑。
|
|||
|
|
|
|||
|
|
**注意**:
|
|||
|
|
- `_drop_overlap`函数依赖于`DocumentWithVSId`类的`page_content`属性来获取文档的页面内容。因此,确保传入的文档列表中的每个实例都包含有效的页面内容。
|
|||
|
|
- 函数处理的效果和性能可能会受到`self._OVERLAP_SIZE`和`self._separator`值的影响,适当调整这些值可以优化处理结果。
|
|||
|
|
|
|||
|
|
**输出示例**:
|
|||
|
|
假设有两个文档的页面内容分别为"今天天气不错,适合出去玩。适合出去玩,不要忘记带伞。"和"适合出去玩,不要忘记带伞。明天也是好天气。",经过`_drop_overlap`函数处理后,返回的`merge_docs`列表可能如下:
|
|||
|
|
```
|
|||
|
|
["今天天气不错,适合出去玩。适合出去玩,不要忘记带伞。", "明天也是好天气。"]
|
|||
|
|
```
|
|||
|
|
这表示第二个文档中与第一个文档重叠的部分已被成功去除。
|
|||
|
|
***
|
|||
|
|
### FunctionDef _join_docs(self, docs)
|
|||
|
|
**_join_docs**: 此函数的功能是将字符串列表连接成一个字符串,并在必要时返回None。
|
|||
|
|
|
|||
|
|
**参数**:
|
|||
|
|
- `docs`: 字符串列表,即要连接的文档列表。
|
|||
|
|
|
|||
|
|
**代码描述**:
|
|||
|
|
`_join_docs` 函数接收一个字符串列表作为参数。它使用实例变量 `_separator` 作为分隔符,将这些字符串连接成一个新的字符串。然后,它会去除新字符串两端的空白字符。如果处理后的字符串为空(即长度为0),函数将返回 `None`;否则,返回处理后的字符串。
|
|||
|
|
|
|||
|
|
这个函数的设计考虑到了可能存在的空字符串或全空白字符的字符串列表,确保在这种情况下不会返回一个空字符串而是返回 `None`,这在很多情况下对于后续的逻辑判断是有帮助的。
|
|||
|
|
|
|||
|
|
**注意**:
|
|||
|
|
- `_separator` 应该在类的其他部分被定义,它决定了如何在字符串之间插入分隔符。如果 `_separator` 没有被正确定义,这个函数可能不会按预期工作。
|
|||
|
|
- 传入的 `docs` 列表不能为空,否则函数将返回 `None`。
|
|||
|
|
|
|||
|
|
**输出示例**:
|
|||
|
|
假设 `_separator` 被定义为逗号 `,`,并且 `docs` 参数为 `["Hello", "world", "!"]`,那么函数的返回值将是 `"Hello,world,!"`。如果 `docs` 为空列表,或者列表中的所有字符串都是空或者只包含空白字符,函数将返回 `None`。
|
|||
|
|
***
|