【从0到1构建一个ClaudeAgent】并
有些操作很慢Agent 不能干等着。例如长时间编译/构建make,mvn compile,gradle build或大数据处理hadoop,spark-submit等的一些工作Java实现代码javapublic class BackgroundTasksSystem { // --- 配置 --- private static final Path WORKDIR Paths.get(System.getProperty(user.dir)); private static final Gson gson new GsonBuilder().setPrettyPrinting().create(); // --- 后台任务管理器 --- static class BackgroundManager { // 任务存储 private final MapString, TaskInfo tasks new ConcurrentHashMap(); // 通知队列 private final QueueTaskNotification notificationQueue new ConcurrentLinkedQueue(); // 任务 ID 生成器 private final AtomicInteger taskIdCounter new AtomicInteger(1); // 锁 private final Object lock new Object(); static class TaskInfo { String taskId; String status; // running, completed, timeout, error String result; String command; long startTime; Thread thread; // 关联的执行线程 } static class TaskNotification { String taskId; String status; String command; String result; } /** * 启动后台任务 * 立即返回任务 ID不等待命令完成 */ public String run(String command) { String taskId task_ taskIdCounter.getAndIncrement(); TaskInfo task new TaskInfo(taskId, command); tasks.put(taskId, task); // 创建并启动后台线程 Thread thread new Thread(() - executeTask(task), BackgroundTask- taskId); thread.setDaemon(true); task.thread thread; thread.start(); // 立即返回不阻塞 return String.format(Background task %s started: %s, taskId, command.substring(0, Math.min(command.length(), 80))); } /** * 线程目标执行子进程捕获输出推送结果到队列 */ private void executeTask(TaskInfo task) { String output; String status; try { ProcessBuilder pb new ProcessBuilder(bash, -c, task.command); pb.directory(WORKDIR.toFile()); pb.redirectErrorStream(true); Process process pb.start(); boolean finished process.waitFor(300, TimeUnit.SECONDS); // 5分钟超时 if (!finished) { process.destroy(); output Error: Timeout (300s); status timeout; } else { output new String(process.getInputStream().readAllBytes()).trim(); status completed; } } catch (Exception e) { output Error: e.getMessage(); status error; } // 更新任务状态 task.status status; task.result output.isEmpty() ? (no output) : output.substring(0, Math.min(output.length(), 50000)); // 添加通知到队列 synchronized (lock) { notificationQueue.offer(new TaskNotification( task.taskId, status, task.command.substring(0, Math.min(task.command.length(), 80)), task.result.substring(0, Math.min(task.result.length(), 500)) )); } } /** * 检查任务状态 * 如果指定 taskId检查单个任务否则列出所有任务 */ public String check(String taskId) { if (taskId ! null !taskId.isEmpty()) { TaskInfo task tasks.get(taskId); if (task null) { return Error: Unknown task taskId; } return String.format([%s] %s\n%s, task.status, task.command.substring(0, Math.min(task.command.length(), 60)), task.result ! null ? task.result : (running)); } else { StringBuilder sb new StringBuilder(); for (Map.EntryString, TaskInfo entry : tasks.entrySet()) { TaskInfo task entry.getValue(); sb.append(String.format(%s: [%s] %s\n, task.taskId, task.status, task.command.substring(0, Math.min(task.command.length(), 60)))); } return sb.length() 0 ? sb.toString().trim() : No background tasks.; } } /** * 清空通知队列并返回所有待处理的通知 */ public ListTaskNotification drainNotifications() { synchronized (lock) { ListTaskNotification notifications new ArrayList(); while (!notificationQueue.isEmpty()) { notifications.add(notificationQueue.poll()); } return notifications; } } /** * 获取所有任务 */ public MapString, TaskInfo getAllTasks() { return new HashMap(tasks); } } // 初始化后台管理器 private static final BackgroundManager BG_MANAGER new BackgroundManager(); // --- 工具枚举 --- public enum ToolType { BASH(bash, Run a shell command (blocking).), READ_FILE(read_file, Read file contents.), WRITE_FILE(write_file, Write content to file.), EDIT_FILE(edit_file, Replace exact text in file.), BACKGROUND_RUN(background_run, Run command in background thread. Returns task_id immediately.), // 新增 CHECK_BACKGROUND(check_background, Check background task status. Omit task_id to list all.); // 新增 public final String name; public final String description; ToolType(String name, String description) { this.name name; this.description description; } } // --- 工具处理器映射 --- private static final MapString, ToolExecutor TOOL_HANDLERS new HashMap(); static { // ... 省略基础工具注册 // 后台任务工具 TOOL_HANDLERS.put(ToolType.BACKGROUND_RUN.name, args - { String command (String) args.get(command); return BG_MANAGER.run(command); }); TOOL_HANDLERS.put(ToolType.CHECK_BACKGROUND.name, args - { String taskId (String) args.get(task_id); return BG_MANAGER.check(taskId); }); } // ... 省略相同的工具实现 // --- Agent 主循环集成后台任务通知--- public static void agentLoop(ListMapString, Object messages) { while (true) { try { // 在 LLM 调用前检查后台通知 ListBackgroundManager.TaskNotification notifications BG_MANAGER.drainNotifications(); if (!notifications.isEmpty() !messages.isEmpty()) { StringBuilder notifText new StringBuilder(); notifText.append(background-results\n); for (BackgroundManager.TaskNotification notif : notifications) { notifText.append(String.format([bg:%s] %s: %s\n, notif.taskId, notif.status, notif.result)); } notifText.append(/background-results); messages.add(Map.of( role, user, content, notifText.toString() )); messages.add(Map.of( role, assistant, content, Noted background results. )); // 异步结果注入将后台任务结果插入到对话中 // 结构化格式用XML标签包裹便于LLM解析 } // 显示当前活动任务 MapString, BackgroundManager.TaskInfo activeTasks BG_MANAGER.getAllTasks(); int runningTasks (int) activeTasks.values().stream() .filter(t - running.equals(t.status)) .count(); if (runningTasks 0) { System.out.printf([Active background tasks: %d]\n, runningTasks); } // ... 省略相同的 LLM 调用和工具执行逻辑 } catch (Exception e) { System.err.println(Error in agent loop: e.getMessage()); e.printStackTrace(); return; } } } }这段代码引入了后台任务系统解决了 Agent 在执行长时间任务时的阻塞问题关键洞察Agent 可以在命令执行时继续工作而不是被阻塞。异步任务处理架构核心思想从同步阻塞的任务执行升级为异步非阻塞的并发处理让Agent能够同时处理多个耗时任务实现并行计算能力大幅提升效率和响应性。java// 后台任务管理器 - 异步执行引擎 static class BackgroundManager { // 任务存储 private final MapString, TaskInfo tasks new ConcurrentHashMap(); // 通知队列 private final QueueTaskNotification notificationQueue new ConcurrentLinkedQueue(); // 任务 ID 生成器 private final AtomicInteger taskIdCounter new AtomicInteger(1); // 并发安全使用线程安全集合 // 异步通信通过队列传递任务结果 // 唯一标识自动生成任务ID }解耦执行任务提交和执行分离立即返回控制权并发管理多个后台任务可以同时运行结果异步收集通过队列机制收集完成的任务结果线程安全使用并发集合确保多线程安全任务信息结构设计java// 任务信息实体 static class TaskInfo { String taskId; // 唯一标识 String status; // 状态running, completed, timeout, error String result; // 执行结果 String command; // 执行的命令 long startTime; // 开始时间 Thread thread; // 关联的执行线程 // 完整状态跟踪从启动到完成的全生命周期 // 线程关联可以控制或监控执行线程 // 时间戳支持超时和性能分析 } // 任务通知实体 static class TaskNotification { String taskId; String status; String command; String result; // 轻量传输只包含必要信息 // 结构化易于解析和处理 // 结果截断避免过大的通知消息 }状态驱动明确的任务状态生命周期结果持久任务结果可以多次查询线程管理可以跟踪和控制执行线程事件驱动通过通知机制传递完成事件异步任务启动机制java/** * 启动后台任务 * 立即返回任务 ID不等待命令完成 */ public String run(String command) { String taskId task_ taskIdCounter.getAndIncrement(); TaskInfo task new TaskInfo(taskId, command); tasks.put(taskId, task); // 创建并启动后台线程 Thread thread new Thread(() - executeTask(task), BackgroundTask- taskId); thread.setDaemon(true); // 守护线程不会阻止JVM退出 task.thread thread; thread.start(); // 立即返回不阻塞调用者 return String.format(Background task %s started: %s, taskId, command.substring(0, Math.min(command.length(), 80))); // 异步启动立即返回任务ID不等待命令完成 // 守护线程不会阻止程序正常退出 // 线程命名便于调试和监控 }立即返回不阻塞主线程立即返回控制权守护线程后台任务不会阻止JVM退出资源管理线程自动清理避免内存泄漏友好反馈返回任务ID和简化的命令描述任务执行与结果收集java/** * 线程目标执行子进程捕获输出推送结果到队列 */ private void executeTask(TaskInfo task) { String output; String status; try { ProcessBuilder pb new ProcessBuilder(bash, -c, task.command); pb.directory(WORKDIR.toFile()); pb.redirectErrorStream(true); Process process pb.start(); boolean finished process.waitFor(300, TimeUnit.SECONDS); // 5分钟超时 if (!finished) { process.destroy(); output Error: Timeout (300s); status timeout; } else { output new String(process.getInputStream().readAllBytes()).trim(); status completed; } } catch (Exception e) { output Error: e.getMessage(); status error; } // 更新任务状态 task.status status; task.result output.isEmpty() ? (no output) : output.substring(0, Math.min(output.length(), 50000)); // 添加通知到队列 synchronized (lock) { notificationQueue.offer(new TaskNotification( task.taskId, status, task.command.substring(0, Math.min(task.command.length(), 80)), task.result.substring(0, Math.min(task.result.length(), 500)) )); } }超时保护防止长时间运行的任务阻塞异常安全全面捕获执行异常内存管理截断大结果避免内存溢出事件驱动完成后立即通知主线程智能通知注入机制java// 在 LLM 调用前检查后台通知 ListBackgroundManager.TaskNotification notifications BG_MANAGER.drainNotifications(); if (!notifications.isEmpty() !messages.isEmpty()) { StringBuilder notifText new StringBuilder(); notifText.append(background-results\n); for (BackgroundManager.TaskNotification notif : notifications) { notifText.append(String.format([bg:%s] %s: %s\n, notif.taskId, notif.status, notif.result)); } notifText.append(/background-results); messages.add(Map.of( role, user, content, notifText.toString() )); messages.add(Map.of( role, assistant, content, Noted background results. )); // 自动注入自动将后台结果插入到对话中 // 结构化格式XML标签明确标识内容类型 // 对话完整添加assistant确认保持对话结构 // 时机智能在LLM调用前插入确保LLM能看到最新结果 }自动同步后台结果自动同步到主对话结构化格式便于LLM识别和解析对话集成无缝集成到现有对话流时机优化在决策前注入确保信息及时性工具集成架构java// 后台任务工具集 public enum ToolType { BACKGROUND_RUN(background_run, Run command in background thread. Returns task_id immediately.), CHECK_BACKGROUND(check_background, Check background task status. Omit task_id to list all.); // 异步执行立即返回不阻塞 // 状态查询支持单个和批量查询 // 语义清晰工具名明确表示异步特性 } // 工具处理器映射 TOOL_HANDLERS.put(ToolType.BACKGROUND_RUN.name, args - { String command (String) args.get(command); return BG_MANAGER.run(command); // 委托执行将命令转交给后台管理器 // 立即返回不等待任务完成 }); TOOL_HANDLERS.put(ToolType.CHECK_BACKGROUND.name, args - { String taskId (String) args.get(task_id); return BG_MANAGER.check(taskId); // 灵活查询支持单任务详查和列表概览 });接口统一与同步工具相同的调用方式异步语义工具名明确区分同步/异步灵活查询支持多种查询方式无缝集成与现有工具系统完全兼容架构演进与价值从 ContextCompactSystem 到 BackgroundTasksSystem 的升级维度ContextCompactSystemBackgroundTasksSystem执行模式同步串行异步并行吞吐量一次一个任务并发多个任务响应性阻塞等待立即响应资源利用单线程多线程并发任务类型短任务为主长短任务混合

相关新闻

腾讯会议领衔语音转写工具推荐

腾讯会议领衔语音转写工具推荐

腾讯会议领衔语音转写工具推荐 上周的部门周会,我一边记笔记一边录了音,结果会后整理纪要花了很久,关键内容还漏了几处;客户访谈时想专注沟通,回头转写录音却发现有部分内容因为口音重完全识别错误——相信不少朋友都遇…

2026/6/24 4:02:54阅读更多 →
Appwrite:一个平台搞定后端、数据库和部署

Appwrite:一个平台搞定后端、数据库和部署

文章目录Appwrite:一个平台搞定后端、数据库和部署Appwrite:一个平台搞定后端、数据库和部署 Appwrite 是一个开源的后端即服务平台,目前在 GitHub 上拿到了 56,292 个 Star。 做 Web 或移动应用开发,后端部分通常需要自己拼凑多…

2026/6/24 4:02:54阅读更多 →
适合中小工厂的设备数据采集方案怎么选

适合中小工厂的设备数据采集方案怎么选

适合中小工厂的设备数据采集方案怎么选对于预算有限、IT 人员稀缺的中小制造企业,最适合的数据采集方案通常具备“轻量化部署”、“非侵入式接入”和“开箱即用”的特点。这类方案专注于解决冲压、注塑、CNC 等核心设备的状态可视与效率分析,避免传统重型…

2026/6/24 4:02:54阅读更多 →
基于U2-Net与深度度量学习的自动化花粉显微图像分析系统实践

基于U2-Net与深度度量学习的自动化花粉显微图像分析系统实践

1. 项目概述与核心价值最近在做一个挺有意思的项目,核心目标是想办法让计算机能自动识别和统计显微镜下的花粉。这听起来好像是个小众需求,但其实在植物学、农业、环境监测甚至法医鉴定领域,这都是个让人头疼的体力活。想象一下,研…

2026/6/24 5:18:01阅读更多 →
立体视觉与深度学习融合:无人机如何智能识别与定位待修剪树枝

立体视觉与深度学习融合:无人机如何智能识别与定位待修剪树枝

1. 项目概述:当无人机“看懂”了树在林业管理,尤其是像辐射松这类经济价值高、需要精细化养护的树种作业中,人工巡检和修剪一直是个老大难问题。林区地形复杂、树木高大,工人爬上爬下不仅效率低下,安全风险也高。更头疼…

2026/6/24 5:18:01阅读更多 →
恶劣天气下自动驾驶多模态感知:URVIS挑战赛揭示的鲁棒性突破

恶劣天气下自动驾驶多模态感知:URVIS挑战赛揭示的鲁棒性突破

1. 从URVIS 2026看自动驾驶的“视力”瓶颈最近和几个做自动驾驶感知的朋友聊天,大家不约而同地提到了一个词:“天气焦虑”。这可不是说我们担心明天会不会下雨,而是指在实验室里跑分跑得飞起的模型,一到雨雪雾霾天,性能…

2026/6/24 5:18:01阅读更多 →
CI/CD中技术债务管理的工具集成与实践

CI/CD中技术债务管理的工具集成与实践

1. 技术债务管理在CI/CD中的实践现状技术债务(Technical Debt)是软件开发过程中不可避免的现象,它反映了快速交付与代码质量之间的权衡。随着DevOps和敏捷开发的普及,如何在持续集成/持续交付(CI/CD)流水线…

2026/6/24 5:18:01阅读更多 →
Dagger依赖注入与Spring的对比:集合注入的艺术

Dagger依赖注入与Spring的对比:集合注入的艺术

在现代Java开发中,依赖注入(Dependency Injection)是提高代码模块化和可测试性的关键技术之一。无论是Spring还是Dagger,都提供了强大的依赖注入框架,但是它们的实现方式和特性有所不同。本文将通过一个实际的实例,探讨Dagger中的集合注入,并将其与Spring的集合注入方式…

2026/6/24 5:18:01阅读更多 →
智能体进化与上下文管理:GA如何通过失败升级与内存压缩实现高效学习

智能体进化与上下文管理:GA如何通过失败升级与内存压缩实现高效学习

1. 项目概述:智能体如何“吃一堑,长一智”最近和几个做AI应用开发的朋友聊天,大家不约而同地提到了一个痛点:我们花大力气调教出来的智能体,比如用来处理客服工单、分析数据报告或者生成营销文案的,刚开始用…

2026/6/24 5:13:00阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/23 7:04:52阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/24 2:12:09阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/23 5:55:37阅读更多 →
TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理 【免费下载链接】TaskJuggler TaskJuggler - Project Management beyond Gantt chart drawing 项目地址: https://gitcode.com/gh_mirrors/ta/TaskJuggler TaskJuggler是一款强大的开源项目管理工具&#…

2026/6/24 0:02:41阅读更多 →
终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果

终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果

终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果 【免费下载链接】angular-mobile-nav An angular navigation service for mobile applications 项目地址: https://gitcode.com/gh_mirrors/an/angular-mobile-nav angular-mobile-nav是一款专为…

2026/6/24 0:02:41阅读更多 →
Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作

Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作

Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作 【免费下载链接】Wan2.1-Fun-V1.1-1.3B-InP 项目地址: https://ai.gitcode.com/hf_mirrors/PAI/Wan2.1-Fun-V1.1-1.3B-InP Wan2.1-Fun-V1.1-1.3B-InP是一款强大的AI视频创作工具,…

2026/6/24 0:02:41阅读更多 →