系列文章索引
J-LangChain 入门
在自然语言处理(NLP)领域,PDF 文件往往包含大量的非结构化文本,如何从中提取有用信息并生成简洁的摘要,是一个重要的应用场景。今天,我们将探讨如何通过 j-langchain
框架结合 PDF 文档处理和文本摘要生成,快速构建一个高效的 PDF 摘要生成系统。
背景
j-langchain
是一个强大的 Java 框架,专为构建与大语言模型(如 GPT-3、ChatGPT)相关的自然语言应用而设计。其提供了一个高层次的抽象,使得用户能够更方便地与各种 NLP 模型进行交互。在本文中,我们将演示如何使用 j-langchain
结合 PDF 文件的加载、文本提取、文本摘要等功能,来实现一个 PDF 摘要生成的应用。
项目依赖
首先,我们需要依赖一些用于加载 PDF 文件的工具类,以及 j-langchain
中的相关模块。下面是基本的依赖配置:
<dependency>
<groupId>io.github.flower-trees</groupId>
<artifactId>j-langchain</artifactId>
<version>1.0.7-preview</version>
</dependency>
pdfbox-loader
是我们用来加载 PDF 文件并提取文本的工具库,j-langchain
则是核心 NLP 框架,用于处理文本摘要的生成。
OCR 识别支持
在处理包含图像的 PDF 文件时,传统的文本提取方法可能无法涵盖图像中的文字。为了支持 OCR(光学字符识别)处理,我们可以启用 Tesseract
进行图像中的文本识别。在 j-langchain
中,我们可以通过以下配置来启用 OCR 支持:
# RAG配置
rag:
ocr:
tesseract:
use: true
通过启用 OCR 配置,PdfboxLoader
将能够识别 PDF 文档中包含的图像并提取其中的文本内容。在代码中,我们只需要将 extractImages(true)
设置为 true
即可,允许加载并处理图像中的文本。
Tesseract
的安装参考:详细介绍Tess4J的使用:从PDF到图像的OCR技术实现,安装后配置环境变量,如:export TESSDATA_PATH=/opt/homebrew/Cellar/tesseract/5.5.0
代码实现
接下来,我们通过一个简单的代码实例来展示如何使用 j-langchain
对 PDF 文档进行摘要处理。
步骤 1:加载 PDF 文件
首先,我们使用 PdfboxLoader
类来加载 PDF 文件,并提取文本内容。以下是如何读取 PDF 的代码:
PdfboxLoader loader = PdfboxLoader.builder()
.filePath("./files/pdf/en/Transformer.pdf")
.extractImages(true) // 启用图像提取
.build();
List<Document> documents = loader.load();
通过 PdfboxLoader
,我们可以加载指定路径的 PDF 文件,并将文件中的内容转化为一个 Document
列表。在这个过程中,我们选择提取图像内容,因为有时候图像可能会带来对理解文档内容的有用信息。
步骤 2:提取文本内容
接下来,我们将从 documents
列表中提取每一页的文本内容,并将它们合并到一个大的字符串中:
StringBuilder contentBuilder = new StringBuilder();
for (Document doc : documents) {
contentBuilder.append(doc.getPageContent()).append("\n");
}
String content = contentBuilder.toString();
此时,content
变量包含了整个 PDF 文档的文本内容。如果文档内容非常长,我们可能需要做进一步处理。
步骤 3:生成摘要
对于较长的文档,我们将只提取前后部分的内容进行摘要,以避免过长的输入对生成过程产生影响。如果文档长度小于 2000 字符,则直接使用全文作为输入进行摘要。否则,我们提取前 1000 个字符和最后 1000 个字符,进行摘要生成:
int contentLength = content.length();
String textToSummarize;
if (contentLength < 2000) {
textToSummarize = content;
} else {
String startText = content.substring(0, 1000);
String endText = content.substring(content.length() - 1000);
textToSummarize = startText + "\n\n" + endText;
}
这样,我们能够确保在摘要生成时,文本不会过长,同时仍然覆盖文档的关键部分。
步骤 4:构建 Prompt 和调用大语言模型
我们使用 PromptTemplate
来创建一个摘要请求的提示模板,接着调用大语言模型生成摘要。以下是使用 ChatOllama
模型生成摘要的代码:
String promptTemplate = """
Please summarize the following text (within 100 words):
${text}
Summary:
""";
BaseRunnable<StringPromptValue, ?> prompt = PromptTemplate.fromTemplate(promptTemplate);
ChatOllama llm = ChatOllama.builder().model("deepseek-r1:7b").build();
FlowInstance chain = chainActor.builder().next(prompt).next(llm).next(new StrOutputParser()).build();
ChatGeneration result = chainActor.invoke(chain, Map.of("text", textToSummarize));
System.out.println(result);
整体代码实例
import org.salt.function.flow.FlowInstance;
import org.salt.jlangchain.core.BaseRunnable;
import org.salt.jlangchain.core.ChainActor;
import org.salt.jlangchain.core.llm.ollama.ChatOllama;
import org.salt.jlangchain.core.parser.StrOutputParser;
import org.salt.jlangchain.core.parser.generation.ChatGeneration;
import org.salt.jlangchain.core.prompt.string.PromptTemplate;
import org.salt.jlangchain.core.prompt.value.StringPromptValue;
import org.salt.jlangchain.rag.loader.pdf.PdfboxLoader;
import org.salt.jlangchain.rag.media.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class PdfSummaryExample {
@Autowired
ChainActor chainActor;
public void pdfSummary() {
// 加载 PDF 文件并提取图像中的文本
PdfboxLoader loader = PdfboxLoader.builder()
.filePath("./files/pdf/en/Transformer.pdf")
.extractImages(true) // 启用图像提取
.build();
List<Document> documents = loader.load();
// 合并提取的文本内容
StringBuilder contentBuilder = new StringBuilder();
for (Document doc : documents) {
contentBuilder.append(doc.getPageContent()).append("\n");
}
String content = contentBuilder.toString();
int contentLength = content.length();
// 如果文档长度较长,则提取前后各1000个字符
String textToSummarize;
if (contentLength < 2000) {
textToSummarize = content;
} else {
String startText = content.substring(0, 1000);
String endText = content.substring(content.length() - 1000);
textToSummarize = startText + "\n\n" + endText;
}
// 摘要生成提示模板
String promptTemplate = """
Please summarize the following text (within 100 words):
${text}
Summary:
""";
// 创建 Prompt 和模型对象
BaseRunnable<StringPromptValue, ?> prompt = PromptTemplate.fromTemplate(promptTemplate);
ChatOllama llm = ChatOllama.builder().model("deepseek-r1:7b").build();
// 使用链式调用模型生成摘要
FlowInstance chain = chainActor.builder().next(prompt).next(llm).next(new StrOutputParser()).build();
// 执行摘要生成,并打印结果
ChatGeneration result = chainActor.invoke(chain, Map.of("text", textToSummarize));
System.out.println("Generated Summary: " + result);
}
}
代码执行
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
@SpringBootConfiguration
public class PdfExampleTest {
@Autowired
PdfSummaryExample pdfSummaryExample;
@Test
public void pdfSummary() {
pdfSummaryExample.pdfSummary();
}
}
总结
通过 j-langchain
框架,我们能够高效地将 PDF 文档中的文本提取出来并生成简洁的摘要。在实际应用中,这种方法不仅能够提高处理效率,还能使得文本摘要更加贴近我们需要的关键信息。通过启用图像提取和 OCR 技术,我们可以进一步扩展文档处理的范围,使得不仅仅是文本,还能从图像中提取到有价值的信息。这种方式特别适用于处理包含丰富视觉内容的 PDF 文件,如学术论文、技术手册等。
参考:
LangChain教程 - RAG - PDF摘要
使用 Apache PDFBox 提取 PDF 中的文本和图像
详细介绍Tess4J的使用:从PDF到图像的OCR技术实现