当前位置: 首页 > news >正文

langchain4j 构建条件工作流

一.背景

1.业务场景驱动

        随着大语言模型(LLM)在企业级应用中的落地深化,基于 langchain4j 开发的智能应用(如招聘助手、智能客服、文档分析系统等)不再局限于 “单一输入→单一输出” 的线性交互模式,而是需要处理多分支、多条件、动态决策的复杂业务逻辑:

  • 以招聘场景为例:系统需根据候选人简历匹配度(如 “完全匹配 / 部分匹配 / 不匹配”),自动触发不同流程 —— 匹配则发送面试邀约、安排线下面试;部分匹配则发起二次评估;不匹配则发送标准化拒信。
  • 以智能客服为例:需根据用户问题类型(如 “咨询 / 投诉 / 售后”)、用户等级(VIP / 普通),分流至不同的对话链(如转接人工、自动解答、推送解决方案文档)。这些场景的核心诉求是:基于预设条件(如文本分析结果、元数据标签、外部系统状态)驱动工作流分支执行,实现 LLM 应用的自动化、标准化落地。

2.传统实现的技术痛点

        在未基于 langchain4j 构建条件工作流时,企业级 LLM 应用开发存在以下问题:

  1. 逻辑耦合严重:条件判断(如 “简历是否符合岗位要求”)与 LLM 调用、外部系统交互(如发送邮件、更新数据库)的代码混杂,难以维护和扩展;
  2. 灵活性不足:硬编码的条件分支无法快速适配业务规则变更(如招聘流程调整、客服分流规则修改),每次变更需重新开发、测试;
  3. 与 langchain4j 生态脱节:常规工作流框架(如 Flowable、Camunda)无法原生适配 langchain4j 的核心组件(如 Document、ChatMemory、Tool),需大量适配代码,增加开发成本;
  4. 可观测性差:条件分支的执行轨迹、LLM 调用结果、异常节点难以追溯,不利于问题排查和流程优化。

3.langchain4j 构建条件工作流的核心价值

        langchain4j 作为轻量级、专为 LLM 应用设计的框架,其组件化、可插拔的特性天然适配条件工作流的构建需求:

  1. 生态原生适配:可直接复用 langchain4j 的 Document 处理、Tool 调用、LLM 交互能力,无需跨框架适配;
  2. 轻量化部署:相较于重型工作流引擎,基于 langchain4j 构建的条件工作流无需额外中间件,契合微服务 / 轻量级应用的部署需求;
  3. 动态决策能力:可将 LLM 本身作为条件判断的核心(如通过 LLM 分析文本内容生成决策标签),实现 “AI 驱动的智能工作流”;
  4. 易于扩展:通过 langchain4j 的 Chain、Agent 等组件,可快速扩展工作流节点(如添加日志记录、异常重试、外部 API 调用)。

        综上,基于 langchain4j 构建条件工作流,能够解决企业级 LLM 应用从 “单点能力” 到 “全流程自动化” 的落地痛点,实现业务规则与 LLM 能力的深度融合,提升应用的稳定性、灵活性和可维护性。

二.具体实现

1.创建java工程,引入依赖

<dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j</artifactId> <version>1.10.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>1.10.0</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-agentic</artifactId> <version>1.10.0-beta18</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-embeddings-bge-small-en-v15-q</artifactId> <version>1.10.0-beta18</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.5.12</version> </dependency>

2.创建大模型工具类

package com.example; import dev.langchain4j.model.chat.ChatModel; import dev.langchain4j.model.openai.OpenAiChatModel; import static dev.langchain4j.model.openai.OpenAiChatModelName.GPT_4_O_MINI; public class ChatModelProvider { public static ChatModel createChatModel() { return OpenAiChatModel.builder() .baseUrl("xxx") .apiKey("xxx") .modelName("gpt-4.1-2025-04-14") .logRequests(true) .logResponses(true) .build(); } }

3.创建工具类

package com.example; import dev.langchain4j.agent.tool.P; import dev.langchain4j.agent.tool.Tool; import java.util.ArrayList; import java.util.Date; import java.util.List; public class OrganizingTools { @Tool public Date getCurrentDate(){ return new Date(); } @Tool("根据指定的岗位编号,查询需出席该岗位线下面试的人员名单及对应的电子邮箱地址") public List<String> getInvolvedEmployeesForInterview(@P("job description ID") String jobDescriptionId){ // dummy implementation for demo return new ArrayList<>(List.of( "Anna Bolena: hiring.manager@company.com", "Chris Durue: near.colleague@company.com", "Esther Finnigan: vp@company.com")); } @Tool("根据员工的电子邮箱地址创建日程条目") public void createCalendarEntry(@P("list of employee email addresses") List<String> emailAddress, @P("meeting topic") String topic, @P("start date and time in format yyyy-mm-dd hh:mm") String start, @P("end date and time in format yyyy-mm-dd hh:mm") String end){ // dummy implementation for demo System.out.println("*** CALENDAR ENTRY CREATED ***"); System.out.println("Topic: " + topic); System.out.println("Start: " + start); System.out.println("End: " + end); } @Tool public int sendEmail(@P("list of recipient email addresses") List<String> to, @P("list of CC email addresses") List<String> cc, @P("emailsubject") String subject, @P("body") String body){ // dummy implementation for demo System.out.println("*** EMAIL SENT ***"); System.out.println("To: " + to); System.out.println("Cc: " + cc); System.out.println("Subject: " + subject); System.out.println("Body: " + body); return 1234; // dummy email ID } @Tool public void updateApplicationStatus(@P("job description ID") String jobDescriptionId, @P("candidate (first name, last name)") String candidateName, @P("new application status") String newStatus){ // dummy implementation for demo System.out.println("*** APPLICATION STATUS UPDATED ***"); System.out.println("Job Descirption ID: " + jobDescriptionId); System.out.println("Candidate Name: " + candidateName); System.out.println("New Status: " + newStatus); } }

4.创建RAG检索类

package com.example; import dev.langchain4j.data.document.Document; import dev.langchain4j.data.document.splitter.DocumentSplitters; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.internal.Utils; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.rag.content.retriever.ContentRetriever; import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever; import dev.langchain4j.store.embedding.EmbeddingStoreIngestor; import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; import dev.langchain4j.model.embedding.onnx.bgesmallenv15q.BgeSmallEnV15QuantizedEmbeddingModel; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import static dev.langchain4j.data.document.loader.FileSystemDocumentLoader.loadDocument; public class RagProvider { public static ContentRetriever loadHouseRulesRetriever() { Document doc = Document.from(""" 吸烟区限定:仅允许在停车场后方指定的户外区域吸烟。 办公静音时段:每日下午 2 点至 4 点为办公静音时段,在此期间请避免在开放办公区大声交谈。 会议室预约:员工使用会议室须提前 24 小时通过内部日历系统进行预约。 自行车停放:自行车需停放至主楼外指定的自行车停放架处。 外来访客登记:所有外来访客进入办公区域前,须到前台出示有效身份证件办理登记手续。 访客证件佩戴:所有外来访客均需领取临时访客证,并全程将证件佩戴在显眼位置。 """); EmbeddingModel embeddingModel = new BgeSmallEnV15QuantizedEmbeddingModel(); InMemoryEmbeddingStore<TextSegment> store = new InMemoryEmbeddingStore<>(); EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder() .documentSplitter(DocumentSplitters.recursive(200, 10)) .embeddingModel(embeddingModel) .embeddingStore(store) .build(); ingestor.ingest(List.of(doc)); return EmbeddingStoreContentRetriever.builder() .embeddingStore(store) .embeddingModel(embeddingModel) .maxResults(2) .minScore(0.8) .build(); } public static Path toPath(String relativePath) { try { URL fileUrl = Utils.class.getClassLoader().getResou
http://www.jsqmd.com/news/192435/

相关文章:

  • 2026最新免钉胶厂家top10推荐榜!优质品牌及供应商权威榜单发布,环保高效助力建筑装饰 - 全局中转站
  • 【好写作AI】你的导师,到底支持你用AI写论文吗?一份“血压波动”调查报告
  • Unreal Engine实时渲染:追求影视级画质的终极目标
  • mac M系列芯片安装 brew 和旧版本 php (5.6-7.4)
  • 简单理解:I2C 两大顺序禁区!错 1 个就卡死总线,90% 工程师踩过!
  • 主构造函数到底香不香?C# 12这一改动让90%开发者直呼太高效!
  • 2025年靠谱的GEO优化公司推荐,GEO优化服务商与项目全解析 - 工业推荐榜
  • 深度解析 GB/T 45581-2025:完整社区设施建设与运营技术指南
  • 【C#高性能编程秘诀】:利用集合表达式和扩展方法实现代码飞跃
  • 基于AI的数字人视频合成工具HeyGem使用全攻略
  • HeyGem输出目录在哪里?深入解析outputs文件夹管理机制
  • Pip国内镜像源配置:加快HeyGem相关包的安装速度
  • 2025年抛丸机厂家推荐:吊钩式抛丸机哪家靠谱? - 工业设备
  • 2026年 广东/深圳残疾人税收优惠政策权威解析:政策扶持、税收筹划与合规申报全攻略 - 品牌企业推荐师(官方)
  • 2026年抖音图片去水印工具实测报告:10款免费高效工具深度对比 - 老周说教育
  • 筑牢制造业研发数据的知识产权护城河
  • 如何在VS Code中高效调试C#跨平台应用?3步实现无缝排查
  • 权威且高性价比:股权激励方案机构的优质之选 - myqiye
  • 使用rsync同步HeyGem输出目录到异地存储
  • 2026小红书去水印存图工具:秒级处理 + 无痕免费工具精准推荐 - 老周说教育
  • FLAC无损音质体验:追求极致还原的HeyGem高级用法
  • Git LFS大文件支持:克隆HeyGem项目时必须启用的功能
  • ChromeDriver下载地址收藏:用于自动化测试HeyGem登录流程
  • 2026最新耐候胶厂家top10推荐榜!建筑密封材料优质品牌及供应商权威榜单发布,品质与性能双优助力工程建设 - 全局中转站
  • 2026最新美缝剂厂家top9推荐榜!优质品牌及供应商权威榜单发布,技环保性能双优助力精致装修 - 全局中转站
  • 为什么顶尖C#工程师都在用Span进行数据转换?真相令人震惊
  • GEO优化服务商如何选?2026年最新横向评测及5家实力推荐 - 品牌推荐
  • 2026必备!8个一键生成论文工具,助研究生高效完成论文!
  • 西门子1200 PLC轴运动控制程序模板:实战经验分享
  • [学习笔记]强化学习基础入门