【learn-claude-code】S08BackgroundTasks - 后台任务:慢操作放后台,Agent 继续思考
核心理念“慢操作放后台Agent 继续思考” – 后台线程执行命令完成后通知模型。源码https://github.com/xiayongchao/learn-claude-code-4j/blob/main/src/main/java/org/jc/agents/S08BackgroundTasks.java原版https://github.com/shareAI-lab/learn-claude-code上篇S07TaskSystem - 任务系统上篇回顾上篇文章我们实现了持久化的 TaskManager支持任务依赖管理和文件存储。问题同步执行命令时Agent 必须等待命令完成才能继续sleep 10会阻塞 10 秒大文件编译、测试套件可能耗时几分钟Agent 无法并行处理其他任务解决方案后台线程执行结果完成后通知。解决方案Agent Loop BackgroundManager | | | backgroundRun(sleep 10) | |----------------------------------| | return taskId: xxx | | | | (继续处理其他任务) | [异步执行中...] | | | drainNotifications() | |----------------------------------| | [bg:xxx] completed: done |Java 实现详解1. BackgroundManager后台任务管理器publicclassBackgroundManager{privatefinalConcurrentHashMapString,TaskInfotasksnewConcurrentHashMap();privatefinalQueueTaskNotificationnotificationQueuenewLinkedList();privatefinalReentrantLocklocknewReentrantLock();}2. 启动后台任务publicStringrun(Stringargs){StringcommandJSON.parseObject(args).getString(command);StringtaskIdUUID.randomUUID().toString().substring(0,8);TaskInfotasknewTaskInfo(running,null,command);tasks.put(taskId,task);Commands.execAsync(command,300_000,false,newCommands.CommandCallback(){OverridepublicvoidonSuccess(Commands.CommandResultresult){updateTask(taskId,completed,result.getOutput());}OverridepublicvoidonFail(Commands.CommandResultresult){Stringstatusresult.isTimeout()?timeout:error;updateTask(taskId,status,result.getOutput());}});return后台任务 taskId 开始: truncate(command,80);}3. 任务状态更新privatevoidupdateTask(StringtaskId,Stringstatus,Stringoutput){TaskInfotasktasks.get(taskId);if(tasknull)return;outputtruncate(outputnull?:output.trim(),50000);if(output.isEmpty())output(无输出);task.setStatus(status);task.setResult(output);// 加入通知队列lock.lock();try{TaskNotificationnotifnewTaskNotification(taskId,status,truncate(task.getCommand(),80),truncate(output,500));notificationQueue.offer(notif);}finally{lock.unlock();}}4. 查询任务状态publicStringcheck(Stringargs){StringtaskIdJSON.parseObject(args).getString(taskId);if(taskId!null!taskId.isBlank()){TaskInfotasktasks.get(taskId);if(tasknull){return错误: 未知任务 taskId;}return[task.getStatus()] truncate(task.getCommand(),60)\n(task.getResult()null?(运行中):task.getResult());}// 列出所有任务ListStringlinesnewArrayList();for(Map.EntryString,TaskInfoentry:tasks.entrySet()){Stringtidentry.getKey();TaskInfotaskentry.getValue();lines.add(tid: [task.getStatus()] truncate(task.getCommand(),60));}returnlines.isEmpty()?没有后台任务:String.join(\n,lines);}5. 清空通知队列publicStringdrainNotifications(){lock.lock();try{ListTaskNotificationlistnewArrayList(notificationQueue);notificationQueue.clear();returnlist.stream().map(n-String.format([bg:%s] %s: %s,n.getTaskId(),n.getStatus(),n.getResult())).reduce((a,b)-a\nb).orElse();}finally{lock.unlock();}}6. agentLoop 集成后台通知privatestaticfinalStringSYSTEM你是运行在 Commons.CWD 工作目录下的编码智能体长时间运行的命令请使用 backgroundRun 执行;publicstaticvoidagentLoop(ListChatCompletionMessageParammessages){while(true){// 每次调用前清空通知队列注入后台结果StringnotifsBG.drainNotifications();if(notifs!null!notifs.isBlank()){messages.add(ChatCompletionMessageParam.ofUser(ChatCompletionUserMessageParam.builder().content(String.format(background-results\n%s\n/background-results,notifs)).build()));messages.add(ChatCompletionMessageParam.ofAssistant(ChatCompletionAssistantMessageParam.builder().content(已记录后台执行结果).build()));}// 正常 LLM 调用...ListChatCompletionMessageParamfullMessagesnewArrayList();fullMessages.add(ChatCompletionMessageParam.ofSystem(ChatCompletionSystemMessageParam.builder().content(SYSTEM).build()));fullMessages.addAll(messages);ChatCompletionCreateParamsparamsChatCompletionCreateParams.builder().model(qwen3.5-plus).messages(fullMessages).tools(tools).build();ChatCompletionchatCompletionCommons.getClient().chat().completions().create(params);// ...}}7. 工具注册privatestaticfinalBackgroundManagerBGnewBackgroundManager();privatestaticfinalMapString,FunctionString,StringTOOL_HANDLERSnewHashMap();static{TOOL_HANDLERS.put(bash,Tools::runBash);TOOL_HANDLERS.put(readFile,Tools::runReadFile);TOOL_HANDLERS.put(writeFile,Tools::runWriteFile);TOOL_HANDLERS.put(editFile,Tools::runEditFile);TOOL_HANDLERS.put(backgroundRun,BG::run);TOOL_HANDLERS.put(checkBackground,BG::check);}privatestaticfinalListChatCompletionTooltoolsList.of(Tools.bashTool(),Tools.readFileTool(),Tools.writeFileTool(),Tools.editFileTool(),Tools.backgroundRunTool(),Tools.checkBackgroundTool());执行流程图1. Agent 调用 backgroundRun(sleep 10) | v 2. BackgroundManager 启动异步任务立即返回 taskId | v 3. Agent 继续处理其他任务不阻塞 | v 4. 后台任务完成通知写入队列 | v 5. 下次 LLM 调用前drainNotifications() 注入结果 | v 6. Agent 收到 background-results 标签处理结果任务状态状态说明running运行中completed成功完成timeout超时默认 5 分钟error执行失败相对 s07 的变更组件s07s08任务管理持久化任务文件持久化 后台执行执行方式同步阻塞异步非阻塞通知机制无drainNotifications 注入新增工具-backgroundRun / checkBackground试试看在后台运行 sleep 5 echo done并在其执行期间创建一个文件启动 3 个后台任务sleep 2s、sleep 4s、sleep 6s并查看它们的状态核心要义“Run slow operations in the background; the agent keeps thinking”慢操作不阻塞Agent 并行工作设计原则异步执行命令立即返回任务后台运行通知注入下次 LLM 调用前注入结果线程安全ConcurrentHashMap ReentrantLock
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2492053.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!