接上节继续,前面讨论的这个AI招聘示例,并非所有环节都需要AI参与,比如:HR、经理、团队对简历分别做出评价后,【计算平均分】以及【根据平均分更新状态(比如:平均分低于0.8则拒绝)】,这2个环节完全可以用代码实现,以节省大模型算力成本。 这时候,就不需要使用类似下面的AgentServices来构建
AgenticServices.agentBuilder(XXX)
.chatModel(model)
.outputKey("xxx")
.build();先定义2个不需要AI参与的处理环节(也称非AI智能体)
1 /**
2 * 非AI智能体,将多个简历评审聚合成一个综合评审。
3 * 这演示了普通Java操作符如何作为一等智能体用于智能体工作流,
4 * 使它们能够与AI驱动的智能体互换使用。
5 */
6 public class ScoreAggregator {
7
8 @Agent(description = "将HR/经理/团队评审聚合成综合评审", outputKey = "combinedCvReview")
9 public CvReview aggregate(@V("hrReview") CvReview hr,
10 @V("managerReview") CvReview mgr,
11 @V("teamMemberReview") CvReview team) {
12
13 System.out.println("ScoreAggregator被调用,参数:hrReview=" + hr +
14 ", managerReview=" + mgr +
15 ", teamMemberReview=" + team);
16
17 double avgScore = (hr.score + mgr.score + team.score) / 3.0;
18
19 String combinedFeedback = String.join("\n\n",
20 "HR评审: " + hr.feedback,
21 "经理评审: " + mgr.feedback,
22 "团队成员评审: " + team.feedback
23 );
24
25 return new CvReview(avgScore, combinedFeedback);
26 }
27 }虽然这个类也加了@Agent,表示这是1个智能体,但是并不需要LLM直接参与,所以得名”非AI智能体“。
1 /**
2 * 非AI智能体,根据评分更新申请状态。
3 * 这演示了普通Java操作符如何作为一等智能体用于智能体工作流,
4 * 使它们能够与AI驱动的智能体互换使用。
5 */
6 public class StatusUpdate {
7
8 @Agent(description = "根据评分更新申请状态")
9 public void update(@V("combinedCvReview") CvReview aggregateCvReview) {
10 double score = aggregateCvReview.score;
11 System.out.println("StatusUpdate被调用,评分: " + score);
12
13 if (score >= 8.0) {
14 // 示例用的模拟数据库更新
15 System.out.println("申请状态更新为: 已邀请面试");
16 } else {
17 // 示例用的模拟数据库更新
18 System.out.println("申请状态更新为: 已拒绝");
19 }
20 }
21 }完整的串起来,示例如下:
1 /**
2 * 这里展示如何在智能体工作流中使用非AI智能体(普通Java操作符)。
3 * 非AI智能体只是普通的方法,但可以像其他类型的智能体一样使用。
4 * 它们非常适合确定性的操作,如计算、数据转换和聚合,这些操作不需要LLM参与。
5 * 将更多步骤外包给非AI智能体,你的工作流将更快、更准确、更经济。
6 * 对于需要强制确定性执行的步骤,非AI智能体比工具更受青睐。
7 * 在这个例子中,我们希望评审者的综合评分是确定性计算的,而不是由LLM计算。
8 * 我们同样基于综合评分确定性地更新数据库中的申请状态。
9 * by 菩提树下的杨过(yjmyzz.cnblogs.com)
10 */
11 @SpringBootApplication
12 public class _8_Non_AI_Agents {
13
14 public static void main(String[] args) throws IOException {
15
16 ConfigurableApplicationContext context = SpringApplication.run(AgentDesignPatternApplication.class, args);
17 ChatModel model = context.getBean("ollamaChatModel", ChatModel.class);
18
19 // 2. 构建并行评审步骤的AI子智能体
20 HrCvReviewer hrReviewer = AgenticServices.agentBuilder(HrCvReviewer.class)
21 .chatModel(model)
22 .outputKey("hrReview")
23 .build();
24
25 ManagerCvReviewer managerReviewer = AgenticServices.agentBuilder(ManagerCvReviewer.class)
26 .chatModel(model)
27 .outputKey("managerReview")
28 .build();
29
30 TeamMemberCvReviewer teamReviewer = AgenticServices.agentBuilder(TeamMemberCvReviewer.class)
31 .chatModel(model)
32 .outputKey("teamMemberReview")
33 .build();
34
35 // 3. 构建组合的并行智能体
36 var executor = Executors.newFixedThreadPool(3); // 保留引用以便后续关闭
37
38 UntypedAgent parallelReviewWorkflow = AgenticServices
39 .parallelBuilder()
40 .subAgents(hrReviewer, managerReviewer, teamReviewer)
41 .executor(executor)
42 .build();
43
44 // 4. 构建包含非AI智能体的完整工作流
45 UntypedAgent collectFeedback = AgenticServices
46 .sequenceBuilder()
47 .subAgents(
48 parallelReviewWorkflow,
49 new ScoreAggregator(), // 非AI智能体不需要AgenticServices构建器。outputKey 'combinedCvReview' 已在类中定义
50 new StatusUpdate(), // 以'combinedCvReview'作为输入,不需要输出
51 AgenticServices.agentAction(agenticScope -> { // 添加非AI智能体的另一种方式,可以操作AgenticScope
52 CvReview review = (CvReview) agenticScope.readState("combinedCvReview");
53 agenticScope.writeState("scoreAsPercentage", review.score * 100); // 当不同系统的智能体通信时,通常需要输出转换
54 })
55 )
56 .outputKey("scoreAsPercentage") // outputKey在ScoreAggregator.java中的非AI智能体注解中定义
57 .build();
58
59 // 5. 加载输入数据
60 String candidateCv = StringLoader.loadFromResource("/documents/tailored_cv.txt");
61 String candidateContact = StringLoader.loadFromResource("/documents/candidate_contact.txt");
62 String hrRequirements = StringLoader.loadFromResource("/documents/hr_requirements.txt");
63 String phoneInterviewNotes = StringLoader.loadFromResource("/documents/phone_interview_notes.txt");
64 String jobDescription = StringLoader.loadFromResource("/documents/job_description_backend.txt");
65
66 Map<String, Object> arguments = Map.of(
67 "candidateCv", candidateCv,
68 "candidateContact", candidateContact,
69 "hrRequirements", hrRequirements,
70 "phoneInterviewNotes", phoneInterviewNotes,
71 "jobDescription", jobDescription
72 );
73
74 // 6. 调用工作流
75 double scoreAsPercentage = (double) collectFeedback.invoke(arguments);
76 executor.shutdown();
77
78 System.out.println("=== 百分比形式的评分 ===");
79 System.out.println(scoreAsPercentage);
80 // 从日志中我们可以看到,申请状态也已经相应更新
81
82 }
83 }注意:49-54行,这里演示了2种创建”非AI智能体”的方式,一是直接new 对象,一种是直接 AgenticServices.agentAction(agenticScope -> {...});
输出:
ScoreAggregator被调用,参数:hrReview__=
CvReview: - score = 0.82
- feedback = "优点:简历清晰专业,联系方式完整。拥有比利时公民身份,合法工作许可。荷兰语母语水平,英语C1水平符合要求。工作履历稳定,无职业空白期,每段工作经历均超过1年。技术技能匹配度高,具有4年以上Java/Spring Boot开发经验,职责范围从单纯开发扩展到指导实习生,体现了成长。
不足之处:薪资期望75,000欧元略高于55,000-70,000欧元范围。可入职时间需要3个月通知,与理想的1-2个月入职时间存在差距。分布式系统经验有限,Kafka仅为基础水平。
技能评估:技术栈符合要求但深度不够,特别是分布式系统和现代微服务架构经验不足。指导他人的经验是加分项。
综合评估:候选人基础条件良好,技能匹配度较高,但薪资和入职时间需要进一步沟通。如果能协调薪资水平或缩短入职等待时间,建议进入面试环节。"
, managerReview__=
CvReview: - score = 0.82
- feedback = "约翰·多伊是一位非常匹配的候选人。他在BrightPay Systems的工作经历特别出色,恰好满足职位的核心要求:具备Java/Spring Boot后端开发经验,成功完成SOAP到REST的API迁移,开发了定价工具系统,并取得了显著的量化成果(报价时间缩短35%)。地理位置理想,语言技能完全符合要求(荷兰语母语+英语C1)。技术栈匹配度高,包括PostgreSQL、CI/CD(GitHub Actions)、Docker等。个人项目展现了对Spring生态系统的深度理解。
主要不足包括:Kafka仅停留在概念验证阶段,缺乏生产级经验;对Kubernetes的实际应用经验不足;从金融科技角度来说,工作经验主要集中在定价工具开发,缺乏完整的支付与对账系统经验。但考虑到整体匹配度很高,这些不足完全可以通过培训和实践来弥补。建议邀请参加现场面试,重点评估其在支付系统架构设计方面的思维能力和学习潜力。"
, teamMemberReview__=
CvReview: - score = 0.75
- feedback = "简历整体质量良好,展现了扎实的后端开发基础。优点:4年经验符合岗位要求,技术栈匹配(Java, Spring Boot, PostgreSQL),有具体量化成就(报价时间缩短35%),完成API现代化迁移,建立CI/CD流程,多语言能力突出。不足:Kafka只有基础水平且只是概念验证,个人项目描述过于简单,缺少测试经验(TDD、单元测试等),没有云平台经验(AWS/GCP/Azure),技术栈相对传统。需要改进:增加具体的技术实现细节,补充测试和云平台技能,完善项目描述。风险信号:涉及前端开发可能分散后端专业性,职业转换路径(机械工程→编程)需要进一步了解深度。"
StatusUpdate被调用,评分: 0.7966666666666665
申请状态更新为: 已拒绝
=== 百分比形式的评分 ===
79.66666666666666
时序图(简化版)-AI生成

时序图(详细版)-AI生成

文中示例代码:
https://github.com/yjmyzz/agentic_turoial_with_langchain4j
参考:
Building Effective AI Agents \ Anthropic
[译] AI Workflow & AI Agent:架构、模式与工程建议(Anthropic,2024)