【从0到1构建一个ClaudeAgent】规划与协调-任务系统
多个任务之间有依赖关系怎么搞?
Java实现代码
public class TaskSystem {
// --- 配置 ---
private static final Path WORKDIR = Paths.get(System.getProperty("user.dir"));
private static final Path TASKS_DIR = WORKDIR.resolve(".tasks"); // 任务存储目录
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
// --- 工具枚举---
public enum ToolType {
BASH("bash", "Run a shell command."),
READ_FILE("read_file", "Read file contents."),
WRITE_FILE("write_file", "Write content to file."),
EDIT_FILE("edit_file", "Replace exact text in file."),
TASK_CREATE("task_create", "Create a new task."), // 新增:创建任务
TASK_GET("task_get", "Get full details of a task by ID."), // 新增:获取任务详情
TASK_UPDATE("task_update", "Update a task's status or dependencies."), // 新增:更新任务
TASK_LIST("task_list", "List all tasks with status summary."); // 新增:列出任务
public final String name;
public final String description;
ToolType(String name, String description) { this.name = name; this.description = description; }
}
// ... 省略相同的 ToolExecutor 接口
// --- 任务管理器 ---
static class TaskManager {
private final Path tasksDir;
private int nextId = 1;
public TaskManager(Path tasksDir) throws IOException {
this.tasksDir = tasksDir;
Files.createDirectories(tasksDir);
this.nextId = getMaxId() + 1; // 自动计算下一个ID
}
private int getMaxId() {
// 扫描已有任务文件,找到最大ID
try {
return Files.list(tasksDir)
.filter(p -> p.getFileName().toString().startsWith("task_"))
.map(p -> {
try {
String name = p.getFileName().toString();
return Integer.parseInt(name.substring(5, name.length() - 5)); // task_xxx.json
} catch (NumberFormatException e) {
return 0;
}
})
.max(Integer::compare)
.orElse(0);
} catch (IOException e) {
return 0;
}
}
private Map loadTask(int taskId) throws IOException {
Path path = tasksDir.resolve("task_" + taskId + ".json");
if (!Files.exists(path)) {
throw new IllegalArgumentException("Task " + taskId + " not found");
}
String content = Files.readString(path);
Type type = new TypeToken
核心思想:利用基于文件的任务图,Agent 开始理解任务间的先后顺序与并行逻辑,成为真正的项目协调者。
企业级任务管理系统架构
核心思想:从简单的内存中Todo管理器升级为持久化、结构化的企业级任务管理系统,支持复杂依赖关系、多任务协同、状态持久化,适用于真实的项目管理和协作场景。
// 任务管理器 - 持久化存储架构
static class TaskManager {
private final Path tasksDir; // 任务存储目录
private int nextId = 1; // 自增ID
public TaskManager(Path tasksDir) throws IOException {
this.tasksDir = tasksDir;
Files.createDirectories(tasksDir);
this.nextId = getMaxId() + 1; // 启动时自动计算下一个ID
}
// 文件系统存储:每个任务存储为独立的JSON文件
// 自动ID管理:启动时扫描现有文件,避免ID冲突
// 持久化:重启后任务状态不丢失
}
- 企业级存储:从内存中Todo升级为文件系统持久化存储
- 原子操作:每个任务独立文件,避免并发问题
- 增量ID:自动管理任务ID,支持大规模任务
- 灾备恢复:文件存储支持手动备份和恢复
任务数据结构与依赖管理
// 创建任务时初始化完整数据结构
public String createTask(String subject, String description) throws IOException {
Map task = new LinkedHashMap<>();
task.put("id", nextId);
task.put("subject", subject); // 任务主题
task.put("description", description != null ? description : ""); // 详细描述
task.put("status", "pending"); // 状态:pending/in_progress/completed
task.put("blockedBy", new ArrayList()); // 被哪些任务阻塞
task.put("blocks", new ArrayList()); // 阻塞哪些任务
task.put("owner", ""); // 任务负责人,支持分派
// 结构化任务:包含完整元数据和关系
// 依赖管理:blockedBy和blocks双向记录依赖关系
// 权限控制:owner字段支持任务分派
saveTask(task);
nextId++;
return gson.toJson(task);
}
- 结构化元数据:任务包含丰富的信息字段
- 依赖管理:支持任务间的阻塞/被阻塞关系
- 扩展性:预留owner字段支持团队协作
- JSON格式:人类可读,便于调试和手动修改
双向依赖同步机制
// 更新任务时自动同步依赖关系
public String updateTask(int taskId, String status,
List addBlockedBy, List addBlocks) throws IOException {
Map task = loadTask(taskId);
if (status != null) {
task.put("status", status);
// 任务完成时,从其他任务的 blockedBy 中移除
if ("completed".equals(status)) {
clearDependency(taskId);
}
}
if (addBlocks != null && !addBlocks.isEmpty()) {
// 双向更新:更新被阻塞任务的 blockedBy 列表
for (int blockedId : distinctBlocks) {
try {
Map blockedTask = loadTask(blockedId);
@SuppressWarnings("unchecked")
List blockedByList = (List) blockedTask.get("blockedBy");
if (!blockedByList.contains(taskId)) {
blockedByList.add(taskId);
saveTask(blockedTask);
}
} catch (Exception e) {
// 忽略不存在的任务
}
}
}
// 依赖自动化:更新一个任务时,自动更新相关任务的依赖关系
// 完成清理:任务完成后自动清理对它的阻塞依赖
// 容错处理:忽略不存在的任务ID
}
- 关系自动维护:更新一个任务的依赖时,自动更新相关任务
- 完成时清理:任务完成后自动清理阻塞关系
- 容错设计:忽略不存在任务的引用
- 数据一致性:确保依赖关系的双向一致性
复杂查询与可视化展示
// 列出所有任务的摘要信息
public String listAllTasks() throws IOException {
List> tasks = new ArrayList<>();
Files.list(tasksDir)
.filter(p -> p.getFileName().toString().endsWith(".json"))
.sorted() // 按文件名排序,通常是ID顺序
.forEach(p -> {
// 逐个加载任务文件
});
StringBuilder sb = new StringBuilder();
for (Map task : tasks) {
String status = (String) task.get("status");
String marker = switch(status) {
case "pending" -> "[ ]";
case "in_progress" -> "[>]";
case "completed" -> "[x]";
default -> "[?]";
};
int id = ((Double) task.get("id")).intValue();
String subject = (String) task.get("subject");
@SuppressWarnings("unchecked")
List blockedBy = (List) task.get("blockedBy");
String blockedStr = (blockedBy != null && !blockedBy.isEmpty())
? " (blocked by: " + blockedBy + ")"
: "";
// 状态可视化:[ ]待办 [>]进行中 [x]已完成
// 依赖提示:显示哪些任务阻塞了当前任务
// 简洁摘要:只显示关键信息
sb.append(String.format("%s #%d: %s%s\n", marker, id, subject, blockedStr));
}
return sb.toString().trim();
}
- 状态可视化:用图标清晰展示任务状态
- 依赖提示:明确显示阻塞关系
- 批量加载:高效加载所有任务
- 人性化格式:便于人类阅读和理解
任务工具生态系统
// 完整的任务工具集定义
public enum ToolType {
TASK_CREATE("task_create", "Create a new task."), // CRUD: Create
TASK_GET("task_get", "Get full details of a task by ID."), // CRUD: Read
TASK_UPDATE("task_update", "Update a task's status or dependencies."), // CRUD: Update
TASK_LIST("task_list", "List all tasks with status summary."); // CRUD: List
// 完整CRUD:创建、读取、更新、删除(通过更新状态为完成)
// 语义清晰:每个工具单一职责
// 与基础工具分离:任务管理工具独立于文件操作工具
}
- 完整CRUD:提供完整的任务管理操作
- 单一职责:每个工具功能明确
- 语义接口:名称明确,便于LLM理解
- 分离关注:任务工具与基础文件工具分离
JSON存储格式
// 任务存储格式示例
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private void saveTask(Map task) throws IOException {
int id = ((Double) task.get("id")).intValue();
Path path = tasksDir.resolve("task_" + id + ".json");
Files.writeString(path, gson.toJson(task)); // 美化的JSON格式
}
// 标准化格式:每个任务存储为格式化的JSON文件
// 命名规范:task_.json
// 人类可读:美化的JSON便于手动查看和编辑
// 可互操作:标准JSON格式支持外部工具处理
- 标准化存储:JSON是通用的数据交换格式
- 可读性:美化格式便于调试
- 可扩展:随时可以添加新字段
- 互操作性:其他工具可以读取任务文件
架构演进与价值
从 AgentWithTodo 到 TaskSystem 的升级:
| 维度 | AgentWithTodo | TaskSystem |
|---|---|---|
| 存储方式 | 内存存储 | 文件系统持久化 |
| 依赖管理 | 无依赖关系 | 双向依赖管理 |
| 数据持久性 | 重启丢失 | 永久保存 |
| 任务复杂性 | 简单待办 | 复杂项目管理 |
| 协同能力 | 单人使用 | 支持团队协作 |
| 可扩展性 | 有限 | 强大 |
原文地址: http://www.cveoy.top/t/topic/qGqT 著作权归作者所有。请勿转载和采集!