博客 / 詳情

返回

Agent設計模式學習(基於langchain4j實現)(9) - 人機協同

經過前面的一系列流程,招聘來到了最重要的1個環節,AI雖然強大,但是不能完全代替人做決定,最終還是要Boss決策這個候選人的去留。從系統設計角度來説,整個AI智能體環節中,要預留人工干預的能力,也稱為"人機協同"(human_in_the_loop)

 

示例代碼

 1 @SpringBootApplication
 2 public class _9a_HumanInTheLoop_Simple_Validator {
 3 
 4     public static void main(String[] args) throws IOException {
 5         ConfigurableApplicationContext context = SpringApplication.run(AgentDesignPatternApplication.class, args);
 6         ChatModel model = context.getBean("ollamaChatModel", ChatModel.class);
 7         RagProvider ragProvider = context.getBean("ragProvider", RagProvider.class);
 8 
 9         // 3. 創建相關智能體
10         InterviewOrganizer interviewOrganizer = AgenticServices.agentBuilder(InterviewOrganizer.class)
11                 .chatModel(model)
12                 .tools(new OrganizingTools())
13                 .contentRetriever(ragProvider.loadHouseRulesRetriever())
14                 .build();
15 
16         EmailAssistant emailAssistant = AgenticServices.agentBuilder(EmailAssistant.class)
17                 .chatModel(model)
18                 .tools(new OrganizingTools())
19                 .build();
20 
21         HiringDecisionProposer decisionProposer = AgenticServices.agentBuilder(HiringDecisionProposer.class)
22                 .chatModel(model)
23                 .outputKey("modelDecision")
24                 .build();
25 
26         // 2. 定義人工驗證環節
27         HumanInTheLoop humanValidator = AgenticServices.humanInTheLoopBuilder()
28                 .description("驗證模型提出的招聘決策")
29                 .inputKey("modelDecision")
30                 .outputKey("finalDecision") // 由人工檢查
31                 .requestWriter(request -> {
32                     System.out.println("AI招聘助手建議: " + request);
33                     System.out.println("請確認最終決定。");
34                     System.out.println("選項: 邀請現場面試 (I), 拒絕 (R), 暫緩 (H)");
35                     System.out.print("> "); // 在實際系統中需要輸入驗證和錯誤處理
36                 })
37                 .responseReader(() -> new Scanner(System.in).nextLine())
38                 .build();
39 
40         // 3. 將智能體鏈接成工作流
41         UntypedAgent hiringDecisionWorkflow = AgenticServices.sequenceBuilder()
42                 .subAgents(decisionProposer, humanValidator)
43                 .outputKey("finalDecision")
44                 .build();
45 
46         // 4. 準備輸入參數
47         Map<String, Object> input = Map.of(
48                 "cvReview", new CvReview(0.85,
49                         """
50                                 技術能力強,但缺乏所需的React經驗。
51                                 似乎是快速獨立學習者。文化契合度良好。
52                                 工作許可可能存在潛在問題,但似乎可以解決。
53                                 薪資期望略高於計劃預算。
54                                 決定繼續進行現場面試。
55                                 """)
56         );
57 
58         System.out.println(input + "\n");
59 
60         // 5. 運行工作流
61         String finalDecision = (String) hiringDecisionWorkflow.invoke(input);
62 
63         System.out.println("\n=== 人工最終決定 ===");
64         System.out.println("(邀請現場面試 (I), 拒絕 (R), 暫緩 (H))\n");
65         System.out.println(finalDecision);
66 
67         UntypedAgent candidateResponder = AgenticServices
68                 .conditionalBuilder()
69                 .subAgents(agenticScope -> finalDecision.contains("I"), interviewOrganizer)
70                 .subAgents(agenticScope -> finalDecision.contains("R"), emailAssistant)
71                 .subAgents(agenticScope -> finalDecision.contains("H"), new HoldOnAssist())
72                 .build();
73 
74         String candidateContact = StringLoader.loadFromResource("/documents/candidate_contact.txt");
75         String jobDescription = StringLoader.loadFromResource("/documents/job_description_backend.txt");
76 
77 
78         Map<String, Object> arguments = Map.of(
79                 "candidateContact", candidateContact,
80                 "jobDescription", jobDescription
81         );
82 
83         // 6. 根據人工最終決定,進行下一步操作
84         candidateResponder.invoke(arguments);
85 
86         // 注意:人工參與和人工驗證通常需要較長時間等待用户響應。
87         // 在這種情況下,建議使用異步智能體,這樣它們不會阻塞工作流的其餘部分,
88         // 這些部分可以在用户回答之前潛在執行。
89     }
90 }
_9a_HumanInTheLoop_Simple_Validator

解釋一下:

27行,這裏的 AgenticServices.humanInTheLoopBuilder() 表示這裏需要人機協助,協助的方式由29行的 new Scanner(System.in).nextLine() 指定為終端控制枱輸入(也可以根據需要,換成其它方式,比如:讀數據庫,調用接口從其它系統獲取)

67-71行,則是根據人工指令做出的響應(即前面學過過的條件工作流),如果輸入H,則執行下面的Agent 

1 public class HoldOnAssist {
2 
3     @Agent(description = "招聘流程暫緩")
4     public void abort() {
5         System.out.println("招聘流程暫緩");
6     }
7 }
HoldOnAssist

 

輸出日誌

 1 {cvReview=
 2 CvReview:  - score = 0.85
 3 - feedback = "技術能力強,但缺乏所需的React經驗。
 4 似乎是快速獨立學習者。文化契合度良好。
 5 工作許可可能存在潛在問題,但似乎可以解決。
 6 薪資期望略高於計劃預算。
 7 決定繼續進行現場面試。
 8 "
 9 }
10 
11 AI招聘助手建議: **招聘理由彙總:**
12 
13 **優勢:** 技術能力強,文化契合度良好,學習能力佳
14 
15 **風險:** 缺乏React經驗,薪資略超預算,潛在工作許可問題  
16 
17 **建議:** 繼續現場面試評估,面試後綜合決定
18 請確認最終決定。
19 選項: 邀請現場面試 (I), 拒絕 (R), 暫緩 (H)
20 > H
21 
22 === 人工最終決定 ===
23 (邀請現場面試 (I), 拒絕 (R), 暫緩 (H))
24 
25 H
26 招聘流程暫緩
View Code

image

 

時序圖(簡化版) - AI生成

09_human_diagram_simple

時序圖(詳細版) - AI生成
09_human_diagram_detail

 

文中示例代碼:

https://github.com/yjmyzz/agentic_turoial_with_langchain4j

 

參考:

Building Effective AI Agents \ Anthropic

[譯] AI Workflow & AI Agent:架構、模式與工程建議(Anthropic,2024)

Agents and Agentic AI | LangChain4j

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.