V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
serverKnignt
V2EX  ›  推广

基于 SpringAi 的模块化设计 Agent 框架,像搭积木一样搭建 Agent。

  •  
  •   serverKnignt · 23 小时 42 分钟前 · 323 次点击

    写在前面

      项目的起因是,在使用 SpringAi 1.0 的时候想要使用 Qwen 作为 ChatModel ,但发现 SpringAi 没有写对应的依赖,而且要用某一个 LLM 还要引用对应的依赖。后面就想自己抽象一层,能让 LLM 无缝接入,就开始看源码和 debug ,这样就有了初版。
      后面看来几篇博文,表达的意思大概是现有的几款框架( LangChain 等)能够解决 80%的问题,但是剩下 20%是无法逾越的鸿沟,最终还是要深入底层修改 Prompt 等。所以要使用“搭积木”的方式搭建属于企业自身业务的框架。受此启发在 SpingAi 的基础上,搞了这么个项目。
    

    地址:AgentBrick

    ✨ 核心亮点

    1. LLM 的通用适配能力
      • 基于 Spring AI 的 OpenAI 核心代码进行二次抽象,使得框架能够轻松适配不同厂商的 LLM (如 Qwen 、Kimi 、MiniMax 、ZhiPu 等)。
      • 提供统一的 ChatModel 接口,屏蔽底层实现差异,降低开发复杂度。
        @Bean(ChatModelConstants.KIMI_K2_CHAT_MODEL)
        public KimiChatModel kimiK2ChatModel(@Qualifier("kimiApi") AiCommonApi kimiApi){
        return (KimiChatModel) LLMEnum.KIMI.genChatModel(
            KimiOptions.builder()
                .model(ChatModelEnum.KIMI_K2)
                .temperature(0.7)
                .maxTokens(8048)
                .build(),
            kimiApi
            );
        }
        
    2. 积木式 Agent 构建
      • 支持模块化搭建 Agent ,用户可以自由组合 Prompt 、Context 和 Tools 。
      • 各个环节灵活搭配
        • 上下层分离。项目中使用 Dify 的知识库检索,作为底层 RAG 检索能力。上层编写符合业务的 RAG 策略。各个层次可随时更换搭配。
        • LLM 分离。可根据不同的 Agent 搭配不同的 LLM ,若出现更加符合 Agent 能力的 LLM 可随时更换,不影响业务代码。
        • Prompt 分离。测试不同 Prompt 以寻找最符合 Agent 要求的 Prompt 。
      • 编写符合业务逻辑的 Agent 架构
        • 项目中使用开源项目OWL为例,使用 Agent 快速搭建。
        @Bean(AgentConstants.RAG_AGENT)
        public RagAgent ragAgent(@Qualifier(ChatModelConstants.QWEN_3_PLUS_CHAT_MODEL) QwenChatModel qwenChatModel,
        RagTools ragTools){
        return  RagAgent.builder()
          .chatModel(qwenChatModel)
          .prompt(AgentPromptConstants.RAG_AGEMNT_SYSTEM_PROMPT)
          .tools(ragTools)
         .build();
        }
      
    3. 高效的数据查询与处理
      • 基于 MyBatis-Plus 进行二次封装,提供更简洁、高效的数据库查询接口。
      @Override
      public Map<Long,ChatRecordMsgJsonDto> queryMsg(List<Long> ids) {
          if (CollectionUtils.isEmpty(ids)){
              return Map.of();
          }
          return where(aiChatRecordMsgMapper)
                  .in(BaseDO::getId, ids)
                  .hasMap(
                          BaseDO::getId,
                          v-> JSONObject.parseObject(v.getMsgDetail().toString(),ChatRecordMsgJsonDto.class)
                  );
          }
      

    🛠️ 技术架构

    JDK21+Spring Ai 1.0+Spring Boot 3.4+PostgreSql+Redis7.x

    4 条回复    2025-08-01 11:23:20 +08:00
    snow0
        1
    snow0  
       11 小时 5 分钟前
    Agent 有类似 LangChain 里面的高阶功能 loop 、策略配置吗
    我看上面代码构建的 Agent 只循环一次
    serverKnignt
        2
    serverKnignt  
    OP
       10 小时 19 分钟前
    @snow0 可以看下项目里面使用 Agent 快速搭建 OWL 的那个例子,在这个 OwlAgentStrategy 类中。项目主要是想要快速构建单个 Agent ,然后如何搭配使用要看自己具体的需求。未来会对 Prompt 进行优化,更加系统化和规范化。
    serverKnignt
        3
    serverKnignt  
    OP
       10 小时 17 分钟前
    @snow0 单个 Agent 的话,可以看下 RagAgent 这个是在单个 Agent 中增加逻辑,不是简单的调用 LLM 。
    snow0
        4
    snow0  
       8 小时 9 分钟前
    @serverKnignt #2 🤝我学习下
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2584 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 11:32 · PVG 19:32 · LAX 04:32 · JFK 07:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.