經過前面的一系列流程,招聘來到了最重要的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 }
解釋一下:
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 }
輸出日誌:
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 招聘流程暫緩
時序圖(簡化版) - AI生成
時序圖(詳細版) - AI生成
文中示例代碼:
https://github.com/yjmyzz/agentic_turoial_with_langchain4j
參考:
Building Effective AI Agents \ Anthropic
[譯] AI Workflow & AI Agent:架構、模式與工程建議(Anthropic,2024)
Agents and Agentic AI | LangChain4j