LangChain 核心原理与 Java 工程化实践
随着人工智能技术的飞速发展,大语言模型(LLM)正在重塑软件工程的范式。LangChain 作为在应用层和底层 LLM 之间的编程框架,类似于 AI 时代的 Spring 框架,负责桥接业务逻辑与底层模型能力,使开发者能够快速构建复杂的 AI 应用。
1. LangChain 解决什么问题
如果把 LLM 比喻为数据库或中间件等基础设施,应用层则是业务逻辑的组合,那么 LangChain 的核心价值在于桥接两者。它解决了两个关键问题:
- 模型交互标准化:屏蔽不同底层模型(如 ChatGPT、ChatGLM、通义千问)的接口差异,提供统一的调用方式。
- 原子能力编排:将单次 LLM 调用视为原子能力,通过 Chain 和工作流编排这些能力来解决复杂的业务需求,而非简单的对话框聊天。
2. LangChain 的核心概念
2.1 Model I/O
Model I/O 封装了背后的 LLM 模型。开发者可以通过配置快速切换底层模型,无需修改核心业务代码。此外,它还提供了缓存等高级功能,对于语义相似的 Query,若缓存命中可直接返回结果,降低延迟和成本。
2.2 Retriever(检索器)
Retriever 旨在打通大模型与用户私有数据。传统的检索基于关键词匹配,而 LLM 场景下更多依赖向量数据库进行语义检索。
典型流程:
文档 -> 分词 -> Embedding(向量化)-> 向量数据库存储 -> 查询(Query)-> 获取 Top N 相似片段 -> 上下文 + 用户提问 + Prompt -> LLM -> 返回结果
关键技术点:
- Embedding 技术选型:将现实物体转化为高维向量,保证特征表达清晰。常见方案包括通义千问 Embedding、OpenAI Embeddings 等。
- 向量数据库:存储向量并支持相似度查询。例如'我的名字是小明'和'我叫小明'在向量空间中距离很近。
- TOP N 选择:根据向量距离筛选最相关的上下文片段。
2.3 Chain(链)
Chain 代表业务类型的组合,类似于工作流的编排。它可以串联多个组件(如 Prompt、模型、检索器),形成完整的处理链路。
2.4 Memory(记忆)
LLM 本身是无状态的,Memory 机制允许开发者将历史对话记录传入给 LLM,实现多轮对话上下文感知。通常使用外部存储(如数据库、Redis)保存会话状态。
2.5 Agent(智能体)
Agent 赋予应用程序基于大模型推理能力的工具调用权限。由于 LLM 无法直接联网或访问内部系统,Agent 通过代理工具(Tools)来扩展能力。
ReAct 模式:
- Thought:思考当前步骤,识别意图。
- Action:决定调用哪个工具,生成 JSON 格式参数。
- Observation:观察工具执行结果。
- Answer:综合信息给出最终回答。
3. 实际场景中的实践
以下实践基于集团内部开发的 Java 版本 LangChain 框架,结合开源大模型 ChatGLM-6B 进行。
3.1 淘宝开放平台智能问答
针对内部托管的上万个 API 咨询问题,升级为基于大模型的智能问答。
知识库 Embedding 过程:
采用通义千问提供的 Embedding 方法对 Question-Answer 形式的知识库进行向量化。
TongYiEmbeddings embeddings = new TongYiEmbeddings();
embeddings.setServerAccessId(ALINLP_EMBEDDINGS_ACCESSID);
embeddings.setServerUrl(ALINLP_EMBEDDINGS_SERVER_URL);
embeddings.setServerUuid(ALINLP_EMBEDDINGS_UUID);
Document document = new Document();
document.setPageContent(rawText);
List<Document> documents = embeddings.embedDocument(Arrays.asList(document));
Document vecDocument = documents.get(0);
String embeddingString = JSON.toJSONString(vecDocument.getEmbedding()).replaceAll("[", "{")
.replaceAll("]", "}");
return embeddingString;
向量数据库存储和查询:
使用 Hologres 向量数据库存储向量化数据。查询时计算欧氏距离或余弦相似度。
SELECT origin_content AS originContent,
origin_title AS originTitle,
pm_approx_squared_euclidean_distance(embedding_title, #{embeddingTitle}) AS distance
FROM vs_knowledge
ORDER BY distance ASC
LIMIT #{limit};
大模型问答链路:
初始化 ChatGLM 参数,编写 Prompt 模板,配置检索 QA 链。
ChatGLMV2Internal chatGLMV2Internal = new ChatGLMV2Internal();
chatGLMV2Internal.setTemperature(0.01d);
chatGLMV2Internal.setMaxLength(2048);
PromptTemplate prompt = new PromptTemplate();
String template = "已知信息:\n" +
"{context} \n\n" +
"根据上述已知信息,简洁和专业的来回答用户的问题。如果无法从中得到答案,请说'根据已知信息无法回答该问题'或'没有提供足够的相关信息',不允许在答案中添加编造成分,答案请使用中文。问题是:{question}";
prompt.setTemplate(template);
RetrievalQA qa = new RetrievalQA();
qa.setRecommend(5);
qa.setMaxDistanceValue(10000.0d);
qa.setLlm(chatGLMV2Internal);
qa.setPrompt(prompt);
qa.setRetriever(holoRetriver.asRetriever());
qa.init();
Map<String, Object> inputs = new HashMap<>();
inputs.put("question", question);
inputs.put("input", question);
Map<String, Object> outputs = qa.run(inputs);
llmKonwledgeDO.setContent(String.valueOf(outputs.get("text")));
return llmKonwledgeDO;
3.2 AI Agent 实践
实现了一个网关 API 调用日志解析的 Agent。
Agent 工具注册:
定义工具名称、描述及输入参数结构。
this.setName("ApiLogTool");
this.setDescription("这是一个调用日志查询接口,如果[{question}]中包含 requestId 关键字,你可以请求这个工具与日志系统进行交互,调用这个工具。\n请先提取出 requestId 的值,将它赋值为 value。调用参数:[{"requestId": "value", "type": "String", "description": "调用请求 id"}]");
工具解析逻辑:
Map<String,Object> parse = (Map<String,Object>)JSON.parse(toolInput);
if(parse.get("requestId")==null){
return new ToolExecuteResult("");
}
String requestId = parse.get("requestId").toString();
ApiLogSearchQuery apiLogSearchQuery = new ApiLogSearchQuery();
思考决策逻辑(Format Instructions):
public static final String FORMAT_INSTRUCTIONS_CH =
"用户提出了一个问题:{question} \n" +
"你可以选择使用下面这些工具:\n"+
"{tool_list_description}"+"\n"+
"同时你的思考过程如下:"+
"Thought: 每一次你需要首先思考你应该做什么\n" +
"Action: 你需要决定是否使用工具,应该是[{tool_names}] 中的一个 Action,格式为 JSON。如果匹配不到工具,就不要思考了,直接返回结果,请不要把思考过程返回给用户。\n" +
"Input: 如果匹配到工具,使用的工具的输入参数,赋值给 params\n" +
"Observation: 如果匹配到工具,工具的输出结果 格式为[]。\n" +
"Answer: 每一步回答问题的答案,格式为 JSON。你可以多次使用 Thought/Action/Input/Observation/Answer 来一步一步的思考如何回答问题。\n";
4. 架构演进与最佳实践
4.1 微服务向 Agent 工厂演进
未来微服务架构(如 HSF)可能向上演进为 Agent 工厂或 Agent 服务框架。搭建好基础框架后,各业务方可快速集成到 Agent 服务上,被上层 AI 应用层调用,实现能力的复用。
4.2 多 Agent 联动
单个 Agent 的能力有限,多个 Agent 的协同联动才是实现真正智能化的关键。这涉及到任务分解、路由分发及结果聚合。
4.3 Agent 体系架构
Agent 体系可分为慎思型、反应型和混合型。
- 慎思型:负责规划和推理行为。
- 反应型:处理需要快速响应的重要事件。
- 混合型:信念 - 期望 - 意图(BDI)体系架构是重要类型。Agent 的行为被描述为拥有信念(知识)、期望(目标)和意图(计划)的思维状态。
4.4 生产环境建议
- 成本控制:合理设置 Temperature 和 MaxLength,利用缓存减少重复调用。
- 隐私安全:敏感数据在送入 LLM 前需脱敏,私有化部署可保障数据安全。
- 评估指标:建立 RAG 系统的评估体系,关注检索准确率(Recall)和生成质量(Faithfulness)。
- 容错机制:当 LLM 无法回答或工具调用失败时,应有降级策略或人工介入通道。
5. 总结
LangChain 极大地简化了 LLM 应用的开发流程。通过理解其核心组件(Model I/O、Retriever、Chain、Memory、Agent)的原理,并结合具体的 Java 工程实践,开发者可以构建出稳定、高效的企业级 AI 应用。随着 Agent 技术的发展,未来的软件架构将更加智能化,能够自主规划并执行复杂任务。