Appearance
问答系统
基于文档的问答
基本实现
java
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.segmenter.CharacterTextSegmenter;
import dev.langchain4j.data.segmenter.TextSegment;
import dev.langchain4j.embedding.openai.OpenAiEmbeddingModel;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.chain.rag.RetrievalAugmentedGenerationChain;
import dev.langchain4j.model.openai.OpenAiChatModel;
public class DocumentQASystem {
public static void main(String[] args) {
// 1. 加载文档
Document document = FileSystemDocumentLoader.builder()
.path("path/to/document.txt")
.build()
.load();
// 2. 分割文档
CharacterTextSegmenter segmenter = CharacterTextSegmenter.builder()
.maxSegmentSize(1000)
.overlapSize(100)
.build();
List<TextSegment> segments = segmenter.segment(document);
// 3. 创建嵌入模型
EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
// 4. 创建嵌入存储并添加文档片段
EmbeddingStore embeddingStore = new InMemoryEmbeddingStore();
embeddingStore.addAll(segments, embeddingModel);
// 5. 创建检索器
EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.maxResults(3)
.minScore(0.7)
.build();
// 6. 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
// 7. 创建 RAG 链
RetrievalAugmentedGenerationChain ragChain = RetrievalAugmentedGenerationChain.builder()
.retriever(retriever)
.model(model)
.build();
// 8. 执行问答
String question = "文档中关于量子计算的内容是什么?";
String answer = ragChain.run(question);
System.out.println("问题: " + question);
System.out.println("回答: " + answer);
}
}高级实现
java
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.DirectoryDocumentLoader;
import dev.langchain4j.data.segmenter.SentenceTextSegmenter;
import dev.langchain4j.data.segmenter.TextSegment;
import dev.langchain4j.embedding.openai.OpenAiEmbeddingModel;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.chroma.ChromaEmbeddingStore;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.chain.rag.RetrievalAugmentedGenerationChain;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.prompt.PromptTemplate;
public class AdvancedDocumentQASystem {
public static void main(String[] args) {
// 1. 加载多个文档
DirectoryDocumentLoader loader = DirectoryDocumentLoader.builder()
.directoryPath("path/to/documents")
.supportedFileExtensions(".txt", ".md", ".pdf")
.build();
List<Document> documents = loader.load();
// 2. 分割文档
SentenceTextSegmenter segmenter = SentenceTextSegmenter.builder()
.maxSegmentSize(1000)
.overlapSize(100)
.build();
List<TextSegment> allSegments = new ArrayList<>();
for (Document document : documents) {
allSegments.addAll(segmenter.segment(document));
}
// 3. 创建嵌入模型
EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
// 4. 创建 Chroma 嵌入存储并添加文档片段
EmbeddingStore embeddingStore = ChromaEmbeddingStore.builder()
.baseUrl("http://localhost:8000")
.collectionName("documents")
.build();
embeddingStore.addAll(allSegments, embeddingModel);
// 5. 创建检索器
EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.maxResults(5)
.minScore(0.7)
.build();
// 6. 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4") // 使用更强大的模型
.build();
// 7. 创建自定义提示词模板
PromptTemplate promptTemplate = PromptTemplate.from(
"你是一个专业的问答系统,根据以下信息回答问题。\n" +
"请确保回答基于提供的信息,不要添加外部知识。\n" +
"如果信息不足,请明确说明。\n\n" +
"信息:\n{information}\n\n" +
"问题:{question}\n\n" +
"回答:"
);
// 8. 创建 RAG 链
RetrievalAugmentedGenerationChain ragChain = RetrievalAugmentedGenerationChain.builder()
.retriever(retriever)
.model(model)
.promptTemplate(promptTemplate)
.build();
// 9. 执行问答
String question = "量子计算的基本原理是什么?";
String answer = ragChain.run(question);
System.out.println("问题: " + question);
System.out.println("回答: " + answer);
}
}多文档问答
基本实现
java
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.DirectoryDocumentLoader;
import dev.langchain4j.data.segmenter.CharacterTextSegmenter;
import dev.langchain4j.data.segmenter.TextSegment;
import dev.langchain4j.embedding.openai.OpenAiEmbeddingModel;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.chain.rag.RetrievalAugmentedGenerationChain;
import dev.langchain4j.model.openai.OpenAiChatModel;
public class MultiDocumentQASystem {
public static void main(String[] args) {
// 1. 加载目录中的所有文档
DirectoryDocumentLoader loader = DirectoryDocumentLoader.builder()
.directoryPath("path/to/documents")
.supportedFileExtensions(".txt", ".md")
.build();
List<Document> documents = loader.load();
// 2. 分割所有文档
CharacterTextSegmenter segmenter = CharacterTextSegmenter.builder()
.maxSegmentSize(1000)
.overlapSize(100)
.build();
List<TextSegment> allSegments = new ArrayList<>();
for (Document document : documents) {
allSegments.addAll(segmenter.segment(document));
}
// 3. 创建嵌入模型
EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
// 4. 创建嵌入存储并添加所有文档片段
EmbeddingStore embeddingStore = new InMemoryEmbeddingStore();
embeddingStore.addAll(allSegments, embeddingModel);
// 5. 创建检索器
EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.maxResults(5)
.minScore(0.7)
.build();
// 6. 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
// 7. 创建 RAG 链
RetrievalAugmentedGenerationChain ragChain = RetrievalAugmentedGenerationChain.builder()
.retriever(retriever)
.model(model)
.build();
// 8. 执行问答
String question = "这些文档中关于人工智能的内容是什么?";
String answer = ragChain.run(question);
System.out.println("问题: " + question);
System.out.println("回答: " + answer);
}
}带元数据过滤的多文档问答
java
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.Metadata;
import dev.langchain4j.data.document.loader.DirectoryDocumentLoader;
import dev.langchain4j.data.segmenter.CharacterTextSegmenter;
import dev.langchain4j.data.segmenter.TextSegment;
import dev.langchain4j.embedding.openai.OpenAiEmbeddingModel;
import dev.langchain4j.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.chain.rag.RetrievalAugmentedGenerationChain;
import dev.langchain4j.model.openai.OpenAiChatModel;
public class FilteredDocumentQASystem {
public static void main(String[] args) {
// 1. 加载目录中的所有文档
DirectoryDocumentLoader loader = DirectoryDocumentLoader.builder()
.directoryPath("path/to/documents")
.supportedFileExtensions(".txt", ".md")
.build();
List<Document> documents = loader.load();
// 2. 为文档添加元数据
List<Document> documentsWithMetadata = new ArrayList<>();
for (Document document : documents) {
Metadata metadata = document.metadata().copy();
// 添加自定义元数据
metadata.put("category", getDocumentCategory(document.content()));
documentsWithMetadata.add(Document.from(document.content(), metadata));
}
// 3. 分割所有文档
CharacterTextSegmenter segmenter = CharacterTextSegmenter.builder()
.maxSegmentSize(1000)
.overlapSize(100)
.build();
List<TextSegment> allSegments = new ArrayList<>();
for (Document document : documentsWithMetadata) {
allSegments.addAll(segmenter.segment(document));
}
// 4. 创建嵌入模型
EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
// 5. 创建嵌入存储并添加所有文档片段
EmbeddingStore embeddingStore = new InMemoryEmbeddingStore();
embeddingStore.addAll(allSegments, embeddingModel);
// 6. 创建带过滤的检索器
EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.maxResults(5)
.minScore(0.7)
.build();
// 7. 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
// 8. 创建 RAG 链
RetrievalAugmentedGenerationChain ragChain = RetrievalAugmentedGenerationChain.builder()
.retriever(retriever)
.model(model)
.build();
// 9. 执行问答
String question = "关于技术领域的内容是什么?";
String answer = ragChain.run(question);
System.out.println("问题: " + question);
System.out.println("回答: " + answer);
}
private static String getDocumentCategory(String content) {
// 简单的分类逻辑
if (content.contains("技术") || content.contains("编程") || content.contains("计算机")) {
return "技术";
} else if (content.contains("商业") || content.contains("市场") || content.contains("经济")) {
return "商业";
} else if (content.contains("科学") || content.contains("研究") || content.contains("实验")) {
return "科学";
} else {
return "其他";
}
}
}复杂问题处理
多步骤问答
java
import dev.langchain4j.chain.sequential.SequentialChain;
import dev.langchain4j.chain.llm.LLMChain;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.prompt.PromptTemplate;
public class MultiStepQASystem {
public static void main(String[] args) {
// 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
// 创建第一步链:分析问题
PromptTemplate analysisTemplate = PromptTemplate.from(
"分析以下问题,确定需要哪些信息来回答:\n{question}\n\n需要的信息:"
);
LLMChain analysisChain = LLMChain.builder()
.promptTemplate(analysisTemplate)
.model(model)
.build();
// 创建第二步链:检索信息
PromptTemplate retrievalTemplate = PromptTemplate.from(
"根据需要的信息,从知识库中检索相关内容:\n{required_info}\n\n检索到的信息:"
);
LLMChain retrievalChain = LLMChain.builder()
.promptTemplate(retrievalTemplate)
.model(model)
.build();
// 创建第三步链:生成答案
PromptTemplate answerTemplate = PromptTemplate.from(
"根据检索到的信息,回答原始问题:\n\n问题:{question}\n\n检索到的信息:{retrieved_info}\n\n回答:"
);
LLMChain answerChain = LLMChain.builder()
.promptTemplate(answerTemplate)
.model(model)
.build();
// 创建顺序链
SequentialChain sequentialChain = SequentialChain.builder()
.addChain(analysisChain, "question", "required_info")
.addChain(retrievalChain, "required_info", "retrieved_info")
.addChain(answerChain, "question,retrieved_info", "answer")
.build();
// 执行多步骤问答
String question = "量子计算如何改变密码学?";
Map<String, Object> inputs = new HashMap<>();
inputs.put("question", question);
Map<String, Object> results = sequentialChain.runForMap(inputs);
System.out.println("问题: " + question);
System.out.println("分析需要的信息: " + results.get("required_info"));
System.out.println("检索到的信息: " + results.get("retrieved_info"));
System.out.println("回答: " + results.get("answer"));
}
}带推理的问答
java
import dev.langchain4j.chain.llm.LLMChain;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.prompt.PromptTemplate;
public class ReasoningQASystem {
public static void main(String[] args) {
// 创建模型
OpenAiChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4") // 使用更强大的模型进行推理
.build();
// 创建带推理的提示词模板
PromptTemplate reasoningTemplate = PromptTemplate.from(
"请逐步思考并回答以下问题:\n{question}\n\n思考过程:\n1. ")
.build();
// 创建链
LLMChain chain = LLMChain.builder()
.promptTemplate(reasoningTemplate)
.model(model)
.build();
// 执行问答
String question = "如果一个篮子里有 5 个苹果,你拿走了 3 个,然后又放回去 2 个,现在篮子里有几个苹果?";
String response = chain.run(question);
System.out.println("问题: " + question);
System.out.println("回答: " + response);
}
}最佳实践
文档处理:
- 选择合适的文档加载器
- 优化文本分割策略
- 添加有意义的元数据
嵌入与检索:
- 选择合适的嵌入模型
- 配置适当的检索参数
- 考虑使用专业的向量数据库
提示词优化:
- 设计清晰的提示词模板
- 明确任务要求
- 提供足够的上下文
模型选择:
- 根据任务复杂度选择模型
- 平衡性能和成本
- 考虑使用更强大的模型处理复杂问题
系统设计:
- 模块化设计
- 错误处理
- 性能优化
评估与改进:
- 定期评估系统性能
- 收集用户反馈
- 持续优化系统