news 2026/4/15 12:16:10

LangChain4j 项目结构目录设计实战:一套清晰的分层方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangChain4j 项目结构目录设计实战:一套清晰的分层方案

文章目录

    • 一、这种分层策略的核心思想
    • 二、为什么这种分层是合理的
      • 1)因为官方把 AI Service 定义成“高层编排入口”
      • 2)因为官方明确区分了“系统提示词、记忆、工具、RAG”这些横向能力
      • 3)因为 Spring Boot starter 本来就鼓励“配置驱动 + 自动装配”
    • 三、按官方能力边界,怎么理解你这几层
      • 1. `web/controller` 层:HTTP 入口层
      • 2. `application/service` 层:业务编排层
      • 3. `agent` 层:智能体运行层
      • 4. `tool` 层:可调用动作层
      • 5. `memory/session` 层:会话状态层
      • 6. `rag` 层:检索增强层
      • 7. `prompt/template` 层:提示词治理层
      • 8. `model` 层:模型适配层
      • 9. `config` 层:配置与装配层
    • 四、这种分层策略的真正价值
      • 1)避免 HTTP 层污染 AI 细节
      • 2)让 AI Service 成为“智能体运行面”,而不是“所有逻辑的垃圾桶”
      • 3)让 RAG 能独立演进
      • 4)让 prompt、memory、tools 成为独立治理对象
      • 5)让模型和向量库具备可替换性
    • 五.举例

LangChain4j 官方文档提供的能力边界,非常支持这种按职责分层的策略

AI Service 负责承接对话入口与编排;Tools 负责可调用动作;Chat Memory 负责会话记忆;ContentRetriever / EmbeddingStore 负责 RAG;Spring Boot Starter 负责配置与装配。也就是说,这种分层不是“官方规定写法”,但它是顺着官方能力模型自然长出来的工程化结构。(GitHub)


一、这种分层策略的核心思想

这套分层策略的本质,不是“把代码拆成很多包”,而是把一个 AI 应用拆成几类稳定职责:

  • 接口入口职责:收请求、返回响应
  • 业务编排职责:决定这次请求走哪条链路
  • Agent 运行职责:把模型、工具、记忆、检索拼起来
  • 知识检索职责:负责文档入库、检索、上下文构造
  • 提示词职责:负责 prompt 的存储、选择、渲染
  • 模型适配职责:负责具体厂商接入
  • 配置装配职责:负责通过 Spring Boot properties 把组件组起来

LangChain4j 官方文档其实就是按这个思路提供能力的:AI Services 处理输入输出转换,并支持 chat memory、tools、RAG;Spring Boot starter 则负责把模型、向量库和 AI Service 自动装配起来。(GitHub)

所以你这套分层,本质上是在做:

上层按业务语义组织,下层按 LangChain4j 能力边界实现。


二、为什么这种分层是合理的

1)因为官方把 AI Service 定义成“高层编排入口”

官方文档明确说,AI Services 会处理最常见的操作:输入格式化、输出解析,并支持 chat memory、tools、RAG。这个定义决定了它天然适合放在你的agent 层,而不是散落到 controller 或 service 的各个角落。(GitHub)

对应到你的结构里就是:

  • VacuumAssistant:声明 AI 能力接口
  • AgentFacade / AgentOrchestrator:封装 AI Service 的实际组装与调用

这很符合官方能力模型,因为 AI Service 本来就是“把底层组件聚合成一个高层接口”。(GitHub)


2)因为官方明确区分了“系统提示词、记忆、工具、RAG”这些横向能力

在 AI Services 文档里,@SystemMessage/systemMessageProviderChatMemoryProvider@ToolContentRetriever都是独立机制。它们不是一个大而全的单体对象,而是可以分别配置的能力。(GitHub)

这直接支持你把系统拆成:

  • prompt/template层:管 prompt
  • memory/session层:管会话状态和记忆
  • tool层:管工具
  • rag层:管检索

也就是说,你这个目录结构不是“人为过度拆分”,而是把官方文档里已经分开的能力,在工程代码里继续落实成清晰边界。(GitHub)


3)因为 Spring Boot starter 本来就鼓励“配置驱动 + 自动装配”

官方 Spring Boot 文档明确写到,starter 可以通过 properties 创建和配置 language models、embedding models、embedding stores 等核心组件;同时还提供了 AI Services、RAG、Tools 的自动配置能力。(GitHub)

这正好对应你单独放一个config层:

  • @ConfigurationProperties: llm.*, rag.*, tools.*, session.*
  • Bean wiring
  • profiles

这种设计的意义是:

业务代码不直接 new 模型,不直接 new 检索器,而是通过配置与装配层统一注入。

这和 Spring Boot + LangChain4j 的推荐使用方式是一致的。(GitHub)


三、按官方能力边界,怎么理解你这几层

下面我按你的目录逐层解释,它们分别在官方文档里对应什么。


1.web/controller层:HTTP 入口层

这一层不属于 LangChain4j 的核心能力,但和 Spring Boot starter 的用法很契合。官方示例就是在@RestController里注入ChatModel或 AI Service,然后暴露/chat之类的接口。(GitHub)

所以这层的定位很清晰:

  • 接收 REST / SSE 请求
  • 做参数校验
  • 调应用层
  • 返回文本流或结构化结果

它不应该负责:

  • 选 prompt
  • 拼 RAG 上下文
  • 管 memoryId
  • 写工具副作用

因此单独保留ChatControllerAdminController是合理的。


2.application/service层:业务编排层

这一层虽然不是 LangChain4j 官方术语,但它是非常必要的工程层。原因在于:

官方的 AI Service 解决的是“如何调用 LLM + tools + memory + RAG”,

但它不负责你的业务决策,例如:

  • 这次请求是普通问答还是报告生成
  • 是否需要返回 sources
  • 是否要做统一审计和 traceId
  • 流式和非流式是否走同一业务路径

所以DialogueApplicationService的价值是:

在 LangChain4j 上面再加一层业务编排,把“AI 能力调用”变成“应用用例执行”。

这是典型的应用服务层职责。


3.agent层:智能体运行层

这是和官方文档最贴近的一层。

官方文档对 AI Service 的定义,是把 Java 接口通过代理转成一个真正可运行的 Assistant,并自动处理输入输出转换。systemMessageProviderChatMemoryProvidertools(...)contentRetriever(...)都是在这里挂进去的。(GitHub)

所以:

  • VacuumAssistant对应 AI Service interface
  • AgentFacade / AgentOrchestrator对应 AI Service 的组装与运行封装

这一层适合承担“Agent Runtime”的责任:

  • 绑定ChatModel
  • 绑定StreamingChatModel
  • 绑定 tools
  • 绑定 memory
  • 绑定 prompt strategy
  • 绑定 request interceptor

换句话说,这一层就是把官方文档里的这些配置点,收口成一个统一运行面。(GitHub)


4.tool层:可调用动作层

官方文档对 tools 的定位非常明确:AI Service 可以配置 tools,让 LLM 在需要时调用 Java 方法。(GitHub)

因此tool层最合理的职责就是:

  • 暴露给模型可调用的业务动作
  • 把外部服务适配成工具
  • 统一管理工具注册和拦截

你的设计里:

  • VacuumRobotTools:具体工具实现
  • ToolRegistry:工具注册与启停
  • ToolInterceptors:统一监控与副作用治理
  • ExternalDataTool (SPI):外部数据来源抽象

这是一种非常合理的工程化升级。

因为官方只定义了“tool calling 能力”,但没有要求你把所有工具都塞进一个类里。你把它分出 registry、interceptor、SPI,正好解决后续扩展性问题。(GitHub)


5.memory/session层:会话状态层

官方文档说明了两件非常重要的事:

  • 如果要支持多用户/多会话,就要用ChatMemoryProvider
  • 使用这种 memory 时,要注意清理不再需要的 conversation,避免 memory leak;如果要访问内部 chat memories,可以让接口扩展ChatMemoryAccess。(GitHub)

这就直接支撑了你为什么要把 memory/session 单独拆出来:

  • SessionStateStore:放业务态,比如 CHAT / REPORT
  • ChatMemoryEvictionPolicy:处理过期与清理
  • ConcurrencyGuard(by memoryId):保护同一会话并发
  • ConversationMetadata:管理 trace、userId、channel 等附加元数据

换句话说,官方文档给了“记忆机制”,你这里是在做“记忆机制的工程治理层”。这是很有必要的。(GitHub)


6.rag层:检索增强层

官方 RAG 文档里把ContentRetriever定义得很清楚:它负责从底层数据源取回有序的相关内容;底层数据源可以是 embedding store、全文检索、混合检索、web search、SQL 等。EmbeddingStoreContentRetriever则是其中一种标准实现,并支持maxResultsminScore和 filter。(GitHub)

这说明 RAG 至少应该拆成两部分:

  • 离线准备:文档加载、切分、embedding、入库
  • 在线检索:根据 query 召回 content,再交给模型生成

所以你这里把它拆成:

  • DocumentIngestionPipeline
  • ContentRetriever
  • RagSummarizeService

是很符合官方能力边界的。

尤其ContentRetriever应该单独成层,不要直接把检索逻辑写死在 Controller 或 Tool 里,因为官方本来就把它定义成一个独立接口抽象。(GitHub)


7.prompt/template层:提示词治理层

官方 AI Services 文档里既支持静态@SystemMessage,也支持动态systemMessageProvider,还支持从 resource 加载 prompt 模板。(GitHub)

这意味着 prompt 不应该只是几段硬编码字符串,而应该是一个可治理对象。

因此你单独放一层:

  • PromptRepository
  • PromptStrategy
  • TemplateRenderer

非常合理。

这层的本质作用是把三件事拆开:

  • prompt 存哪
  • prompt 怎么选
  • prompt 变量怎么渲染

而官方文档已经给了“资源文件 prompt + 动态 provider”这两个基础锚点。(GitHub)


8.model层:模型适配层

官方首页和项目介绍都强调,LangChain4j 提供统一 API 来接入主流 LLM 和向量存储,并且能和 Java 应用平滑集成。(LangChain4j)

这意味着一个很自然的工程原则是:

业务层不要直接绑死 OpenAI / DashScope / 某一个 embedding 厂商。

所以你把这一层拆成:

  • ChatModelProvider
  • StreamingChatModelProvider
  • EmbeddingModelProvider
  • Provider adapters

是正确的。

这样切模型只改 adapter 和配置,不会影响 application、agent、tool、rag 这些上层代码。这个思路和官方强调的“统一 API 接入不同模型与向量库”是一致的。(LangChain4j)


9.config层:配置与装配层

这个层和 Spring Boot 官方集成文档最直接相关。

因为文档明确写了 starter 会通过 properties 来创建和配置模型、embedding model、embedding store,以及 AI Services、RAG、Tools 等。(GitHub)

所以把配置集中到:

  • llm.*
  • rag.*
  • tools.*
  • session.*

再通过@ConfigurationProperties和 Bean wiring 装起来,是最标准的 Spring Boot 风格,也最符合 LangChain4j starter 的使用方式。(GitHub)


四、这种分层策略的真正价值

如果只看目录,这套结构像是“多加了几层”;

但从官方能力模型看,它的价值很明确:

1)避免 HTTP 层污染 AI 细节

Spring Boot 示例里 controller 可以直接调模型,但那只是最小示例,不适合复杂项目。你的分层让 HTTP 层只管接口协议,不碰 prompt、tool、RAG 细节。(GitHub)

2)让 AI Service 成为“智能体运行面”,而不是“所有逻辑的垃圾桶”

官方把 AI Service 设计成高层代理对象;你把它放在 agent 层,而不是 controller/service 到处直连,是在顺着它的本意使用。(GitHub)

3)让 RAG 能独立演进

官方把ContentRetriever单独抽象出来,这天然支持你后续从 embedding 检索升级到 hybrid、SQL、web search,而不用重写整条对话链路。(GitHub)

4)让 prompt、memory、tools 成为独立治理对象

官方已经把这些能力独立出来;你在工程里继续独立建层,后面做审计、追踪、调优会轻松很多。(GitHub)

5)让模型和向量库具备可替换性

官方强调统一 API 和对多模型/多向量存储的支持,这就是 model/config 分层成立的根本依据。(LangChain4j)


五.举例

src/main/java/com/huacai/reactagent ├─ web │ ├─ ChatController.java // SSE + REST 对话入口(可复用现有 ChatController) │ ├─ ReportController.java // 报告生成入口(可选) │ └─ dto │ ├─ ChatRequest.java │ ├─ ChatResponse.java │ ├─ ReportRequest.java │ └─ ErrorResponse.java ├─ application │ ├─ DialogueApplicationService.java // 业务编排:对话/报告/RAG 路由 │ └─ policy │ ├─ ModeDecisionPolicy.java // 可选:意图判定或显式 mode │ └─ MemoryIdPolicy.java // memoryId 生成/校验策略 ├─ agent │ ├─ VacuumAssistant.java // AI Service interface(可迁移现有 VacuumAssistant) │ ├─ AgentFacade.java // 封装 AI Service 的调用、统一异常 │ └─ interceptor │ ├─ ChatRequestInterceptor.java // 类似 log_before_model 的统一拦截点 │ └─ ToolInvocationInterceptor.java // 统一工具监控(替代散落 log) ├─ tool │ ├─ VacuumRobotTools.java // 工具集合(可迁移现有 VacuumRobotTools) │ ├─ registry │ │ ├─ ToolRegistry.java // 工具注册与分组(避免写死) │ │ └─ ToolSet.java // tool 分组(基础工具/RAG/外部数据) │ └─ external │ ├─ ExternalDataClient.java // SPI:外部数据来源适配 │ └─ CsvExternalDataClient.java // 现有 ExternalDataRepository 可迁移为实现 ├─ rag │ ├─ RagConfig.java // Bean wiring(可迁移现有 RagConfig) │ ├─ ingestion │ │ ├─ IngestionPipeline.java // scan/load/split/embed/upsert/fingerprint │ │ ├─ DocumentSource.java // classpath/filesystem │ │ └─ FingerprintStore.java // md5/mtime 去重(对齐 Python md5.txt) │ ├─ retrieval │ │ ├─ RagRetriever.java // 封装 ContentRetriever │ │ └─ RetrievedChunk.java // text + metadata (统一结构) │ └─ summarize │ ├─ RagSummarizeService.java // 可迁移现有 RagSummarizeService │ └─ RagPromptRenderer.java // {input}/{context} 渲染与校验 ├─ prompt │ ├─ PromptRepository.java // 资源/文件系统加载(可复用 VacuumPromptHolder 的思路) │ ├─ PromptKeys.java // MAIN / REPORT / RAG_SUMMARIZE │ └─ PromptStrategy.java // 根据 SessionState/场景选择系统提示词 ├─ model │ ├─ provider │ │ ├─ ChatModelProvider.java // SPI │ │ ├─ StreamingChatModelProvider.java // SPI │ │ └─ EmbeddingModelProvider.java // SPI │ └─ adapter │ ├─ DashScopeModelAdapter.java // 与 application.yml dashscope 对齐 │ └─ ... // 未来扩展 OpenAI/其他云厂商 ├─ session │ ├─ SessionStateStore.java // 替代 VacuumSessionStore:支持状态机/ttl/clear │ ├─ SessionState.java // enum Mode { CHAT, REPORT, ... } │ ├─ MemoryConcurrencyGuard.java // 同 memoryId 并发保护(文档风险项落地) │ └─ ChatMemoryEvictionService.java // eviction 策略与管理 API └─ config ├─ LlmProperties.java // yml 绑定 ├─ RagProperties.java ├─ ToolProperties.java └─ AgentAutoConfiguration.java // 统一装配:AiServices.builder(...)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 12:15:44

JPEGView:Windows上最快的图像查看器,为什么你还没用上?

JPEGView:Windows上最快的图像查看器,为什么你还没用上? 【免费下载链接】jpegview Fork of JPEGView by David Kleiner - fast and highly configurable viewer/editor for JPEG, BMP, PNG, WEBP, TGA, GIF and TIFF images with a minimal …

作者头像 李华
网站建设 2026/4/15 12:15:39

【C++】红黑树

红黑树的介绍概念红黑树是一种自平衡的二叉查找树,它通过为每个节点附加颜色属性(红色或黑色),并强制满足一组约束条件,使得树在插入、删除操作后能自动恢复平衡,从而保证最坏情况下的查找、插入、删除时间…

作者头像 李华
网站建设 2026/4/15 12:15:38

Linux性能优化之CPU利用率

写在前面 本文看下CPU使用率相关内容。 1:Linux是如何维护CPU时间的?如何查看CPU使用率? 1.1:Linux是如何维护CPU时间的? 先来看下节拍率的概念,通过HZ表示,一般是100,250,1000…

作者头像 李华
网站建设 2026/4/15 12:14:35

C++函数模板实战:如何设计一个通用的“比较器”

1. 为什么我们需要通用的比较器? 在日常开发中,经常会遇到需要比较两个值大小的情况。比如电商系统要比较商品价格,社交平台要筛选用户评分最高的内容,或者文件管理系统需要对文件名进行排序。如果为每种数据类型都单独写一个比较…

作者头像 李华
网站建设 2026/4/15 12:13:14

HCPL-2400-060E,10kV/µs高速三态输出TTL兼容逻辑门光耦合器

简介今天我要向大家介绍的是 Broadcom 的光耦合器——HCPL-2400-060E。它是一款单通道、兼容 TTL、STTL、LSTTL 和 HCMOS 逻辑的高速逻辑门光耦合器。该器件内部采用 820 nm AlGaAs 发光二极管技术,并结合了高速光探测器。其输出端为带有内置施密特触发器的三态输出…

作者头像 李华
网站建设 2026/4/15 12:10:28

【稀缺首发】多模态域适应的4层黄金评估体系:含37项量化指标、12个基准数据集对比矩阵与可复现代码包

第一章:多模态大模型域适应技术 2026奇点智能技术大会(https://ml-summit.org) 多模态大模型在跨域场景下常面临语义鸿沟、模态失配与分布偏移等核心挑战。域适应技术旨在缓解源域(如Web图像-文本对)与目标域(如医学影像报告&…

作者头像 李华