前言:当AI学会“团队协作”

在2026年的今天,大语言模型(LLM)早已不是新鲜事物。但如何让LLM真正像人类一样“思考-行动-协作”,完成复杂任务,依然是AI领域的核心挑战。LangChain4j的langchain4j-agentic模块(实验性特性)为我们提供了一套优雅的解决方案——Agentic AI

本文将带你从零开始,深入理解LangChain4j中的Agent概念,并通过丰富的代码示例,掌握从简单工作流到纯Agentic系统的完整构建过程。无论你是Java开发者还是AI应用架构师,这篇文章都将为你打开一扇新的大门。


一、Agentic系统:Workflow与Pure Agent

根据Anthropic研究者的分类,Agentic系统架构主要分为两大类:

类型 特点 适用场景
Workflow 通过预定义代码路径和LLM编排工具 任务步骤明确、流程固定
Pure Agent LLM动态控制自身流程和工具使用 任务复杂、路径不确定

LangChain4j的langchain4j-agentic模块同时支持这两种模式,并且允许你灵活组合。


二、快速上手:定义你的第一个Agent

在LangChain4j中,Agent本质上是一个增强版的AI Service。你只需要定义一个接口,并用@Agent注解标记方法即可。

public interface CreativeWriter {
    @UserMessage("""
            你是一位创意作家。
            根据给定主题生成一个不超过3句话的故事草稿。
            只返回故事本身,不要其他内容。
            主题是:{{topic}}。
            """)
    @Agent("根据主题生成故事")
    String generateStory(@V("topic") String topic);
}

最佳实践:在@Agent注解中添加description描述Agent的用途,这在纯Agentic模式中尤为重要——其他Agent需要根据描述来决定何时调用它。

构建Agent实例:

CreativeWriter creativeWriter = AgenticServices
        .agentBuilder(CreativeWriter.class)
        .chatModel(myChatModel)
        .outputKey("story")  // 指定输出在共享变量中的名称
        .build();

三、核心概念:AgenticScope共享变量

Agentic系统中的多个Agent需要协作,它们通过AgenticScope共享数据。你可以把Scope想象成一个内存中的共享数据池

  • Agent通过outputKey将结果写入Scope
  • Agent通过@V注解从Scope读取所需参数
  • Scope自动记录所有Agent的调用序列和响应
// Agent写入数据
.outputKey("story")

// Agent读取数据
@UserMessage("故事是:{{story}}")
String editStory(@V("story") String story);

四、工作流模式实战

4.1 顺序工作流(Sequential Workflow)

最简单的模式:Agent依次执行,前一个的输出作为后一个的输入。

// 定义三个Agent
CreativeWriter creativeWriter = AgenticServices
        .agentBuilder(CreativeWriter.class)
        .chatModel(BASE_MODEL)
        .outputKey("story")
        .build();

AudienceEditor audienceEditor = AgenticServices
        .agentBuilder(AudienceEditor.class)
        .chatModel(BASE_MODEL)
        .outputKey("story")
        .build();

StyleEditor styleEditor = AgenticServices
        .agentBuilder(StyleEditor.class)
        .chatModel(BASE_MODEL)
        .outputKey("story")
        .build();

// 组合成顺序工作流
UntypedAgent novelCreator = AgenticServices
        .sequenceBuilder()
        .subAgents(creativeWriter, audienceEditor, styleEditor)
        .outputKey("story")
        .build();

// 执行
Map<String, Object> input = Map.of(
        "topic", "龙与巫师",
        "style", "奇幻",
        "audience", "年轻人"
);
String story = (String) novelCreator.invoke(input);

4.2 循环工作流(Loop Workflow)

通过循环迭代,逐步优化结果,直到满足条件。

// 评分Agent
StyleScorer styleScorer = AgenticServices
        .agentBuilder(StyleScorer.class)
        .chatModel(BASE_MODEL)
        .outputKey("score")
        .build();

// 循环工作流:评分 -> 编辑 -> 再评分,直到分数>=0.8或达到最大迭代次数
UntypedAgent styleReviewLoop = AgenticServices
        .loopBuilder()
        .subAgents(styleScorer, styleEditor)
        .maxIterations(5)
        .exitCondition(scope -> scope.readState("score", 0.0) >= 0.8)
        .build();

4.3 并行工作流(Parallel Workflow)

多个独立任务同时执行,提高效率。

FoodExpert foodExpert = AgenticServices
        .agentBuilder(FoodExpert.class)
        .chatModel(BASE_MODEL)
        .outputKey("meals")
        .build();

MovieExpert movieExpert = AgenticServices
        .agentBuilder(MovieExpert.class)
        .chatModel(BASE_MODEL)
        .outputKey("movies")
        .build();

EveningPlannerAgent planner = AgenticServices
        .parallelBuilder(EveningPlannerAgent.class)
        .subAgents(foodExpert, movieExpert)
        .executor(Executors.newFixedThreadPool(2))
        .output(scope -> {
            // 组合两个Agent的输出
            List<String> movies = scope.readState("movies", List.of());
            List<String> meals = scope.readState("meals", List.of());
            return combinePlans(movies, meals);
        })
        .build();

4.4 条件工作流(Conditional Workflow)

根据条件动态选择执行哪个Agent。

// 路由Agent:分类用户请求
CategoryRouter router = // ...

// 条件工作流
UntypedAgent expertsAgent = AgenticServices.conditionalBuilder()
        .subAgents(
            scope -> scope.readState("category") == MEDICAL, 
            medicalExpert
        )
        .subAgents(
            scope -> scope.readState("category") == LEGAL, 
            legalExpert
        )
        .subAgents(
            scope -> scope.readState("category") == TECHNICAL, 
            technicalExpert
        )
        .build();

五、高级特性

5.1 异步Agent(Asynchronous)

通过async(true)让Agent异步执行,不阻塞主流程。

FoodExpert foodExpert = AgenticServices
        .agentBuilder(FoodExpert.class)
        .async(true)  // 异步执行
        .outputKey("meals")
        .build();

5.2 流式Agent(Streaming)

支持TokenStream返回类型,实现流式输出。

public interface StreamingCreativeWriter {
    @Agent
    TokenStream generateStory(@V("topic") String topic);
}

StreamingCreativeWriter writer = AgenticServices
        .agentBuilder(StreamingCreativeWriter.class)
        .streamingChatModel(streamingModel)
        .outputKey("story")
        .build();

TokenStream stream = writer.generateStory("龙与巫师");

注意:流式Agent只有在工作流中作为最后一个Agent时,才会将流式响应传播给调用方。

5.3 动态模型选择

根据Scope状态动态选择使用哪个模型(如:简单任务用廉价模型,复杂任务用高级模型)。

StoryEditor editor = AgenticServices
        .agentBuilder(StoryEditor.class)
        .chatModel(scope -> {
            CritiqueResult critique = scope.readState("critique");
            return critique.score() > 7.8 ? enhancedModel() : baseModel();
        })
        .build();

5.4 错误处理(Error Handling)

通过errorHandler优雅处理Agent执行中的异常。

UntypedAgent agent = AgenticServices.sequenceBuilder()
        .errorHandler(ctx -> {
            if (ctx.exception() instanceof MissingArgumentException) {
                // 补全缺失参数并重试
                ctx.agenticScope().writeState("topic", "默认主题");
                return ErrorRecoveryResult.retry();
            }
            return ErrorRecoveryResult.throwException();
        })
        .build();

六、可观测性:监控与调试

6.1 AgentListener监听器

注册监听器,跟踪Agent调用全过程。

CreativeWriter writer = AgenticServices
        .agentBuilder(CreativeWriter.class)
        .listener(new AgentListener() {
            @Override
            public void beforeAgentInvocation(AgentRequest req) {
                System.out.println("开始调用: " + req.agentName());
            }
            @Override
            public void afterAgentInvocation(AgentResponse resp) {
                System.out.println("调用完成,输出: " + resp.output());
            }
        })
        .build();

6.2 AgentMonitor监控器

内置的AgentMonitor可以记录所有Agent调用,并生成可视化HTML报告。

AgentMonitor monitor = new AgentMonitor();

// 注册到根Agent
StyledWriter writer = AgenticServices.sequenceBuilder()
        .listener(monitor)  // 自动继承给所有子Agent
        .build();

// 执行任务...
String result = writer.invoke(input);

// 生成HTML报告
HtmlReportGenerator.generateReport(monitor, Path.of("report.html"));

生成的报告包含:

  • Agent系统拓扑图
  • 每次调用的耗时、Token数、输入输出
  • 嵌套调用树形结构

七、声明式API:更简洁的Agent定义

LangChain4j提供了一套注解,让你用更声明式的方式定义Agent系统。

public interface EveningPlannerAgent {
    
    @ParallelAgent(
        outputKey = "plans",
        subAgents = {FoodExpert.class, MovieExpert.class}
    )
    List<EveningPlan> plan(@V("mood") String mood);
    
    @Output
    static List<EveningPlan> combine(
            @V("movies") List<String> movies,
            @V("meals") List<String> meals) {
        // 组合逻辑
        return combined;
    }
}

// 创建Agent系统
EveningPlannerAgent agent = AgenticServices
        .createAgenticSystem(EveningPlannerAgent.class, BASE_MODEL);

支持的注解包括:

  • @ChatModelSupplier / @StreamingChatModelSupplier
  • @ChatMemorySupplier
  • @ToolsSupplier
  • @SystemMessageProviderSupplier
  • 等等

八、纯Agentic AI:Supervisor模式

当任务路径不确定时,可以使用Supervisor Agent。它会自主规划,决定调用哪个子Agent、何时完成任务。

// 定义子Agent(取款、存款、货币兑换)
WithdrawAgent withdraw = // ...
CreditAgent credit = // ...
ExchangeAgent exchange = // ...

// 创建Supervisor
SupervisorAgent bankSupervisor = AgenticServices
        .supervisorBuilder()
        .chatModel(PLANNER_MODEL)
        .subAgents(withdraw, credit, exchange)
        .responseStrategy(SupervisorResponseStrategy.SUMMARY)
        .build();

// 用户自由输入指令
String response = bankSupervisor.invoke(
    "从Mario账户取100美元,然后兑换成欧元"
);

Supervisor会自主决定:

  1. 先调用WithdrawAgent
  2. 再调用ExchangeAgent
  3. 最后总结结果并返回

九、最佳实践与注意事项

  1. 描述清晰:为每个Agent添加详细description,帮助Supervisor或其他Agent理解其用途。
  2. 合理使用异步:IO密集型或耗时操作设为异步,提高吞吐量。
  3. 监控先行:开发阶段务必启用AgentMonitor,便于调试和优化。
  4. 错误兜底:为关键Agent配置errorHandler,避免整个系统崩溃。
  5. 模型匹配:根据任务复杂度动态选择模型,平衡成本与质量。
  6. 实验性质langchain4j-agentic模块目前是实验性的,API可能在未来版本发生变化。

结语

LangChain4j的Agentic模块为Java开发者提供了一套强大、类型安全、可观测的AI Agent构建框架。从固定的Workflow到自主的Pure Agent,你可以根据业务需求灵活选择。随着LLM能力的增强,Agentic AI必将成为下一代智能应用的核心范式。

希望这篇文章能帮助你快速上手LangChain4j Agentic开发。如果你有任何问题或心得,欢迎在评论区交流讨论!


参考资料

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐