【从0到1构建一个ClaudeAgent】规划与协调-任务系统
·
Java实现代码
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<String, Object> 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<Map<String, Object>>(){}.getType();
return gson.fromJson(content, type);
}
private void saveTask(Map<String, Object> task) throws IOException {
int id = ((Double) task.get("id")).intValue();
Path path = tasksDir.resolve("task_" + id + ".json");
Files.writeString(path, gson.toJson(task)); // JSON格式存储
}
public String createTask(String subject, String description) throws IOException {
Map<String, Object> task = new LinkedHashMap<>();
task.put("id", nextId);
task.put("subject", subject);
task.put("description", description != null ? description : "");
task.put("status", "pending"); // 默认状态
task.put("blockedBy", new ArrayList<Integer>()); // 被哪些任务阻塞
task.put("blocks", new ArrayList<Integer>()); // 阻塞哪些任务
task.put("owner", ""); // 任务负责人
saveTask(task);
nextId++;
return gson.toJson(task);
}
public String getTask(int taskId) throws IOException {
return gson.toJson(loadTask(taskId));
}
public String updateTask(int taskId, String status,
List<Integer> addBlockedBy, List<Integer> addBlocks) throws IOException {
Map<String, Object> task = loadTask(taskId);
if (status != null) {
if (!Arrays.asList("pending", "in_progress", "completed").contains(status)) {
throw new IllegalArgumentException("Invalid status: " + status);
}
task.put("status", status);
// 任务完成时,从其他任务的 blockedBy 中移除
if ("completed".equals(status)) {
clearDependency(taskId);
}
}
if (addBlockedBy != null && !addBlockedBy.isEmpty()) {
@SuppressWarnings("unchecked")
List<Integer> currentBlockedBy = (List<Integer>) task.get("blockedBy");
List<Integer> newList = new ArrayList<>(currentBlockedBy);
newList.addAll(addBlockedBy);
task.put("blockedBy", newList.stream().distinct().collect(Collectors.toList()));
}
if (addBlocks != null && !addBlocks.isEmpty()) {
@SuppressWarnings("unchecked")
List<Integer> currentBlocks = (List<Integer>) task.get("blocks");
List<Integer> newList = new ArrayList<>(currentBlocks);
newList.addAll(addBlocks);
List<Integer> distinctBlocks = newList.stream().distinct().collect(Collectors.toList());
task.put("blocks", distinctBlocks);
// 双向更新:更新被阻塞任务的 blockedBy 列表
for (int blockedId : distinctBlocks) {
try {
Map<String, Object> blockedTask = loadTask(blockedId);
@SuppressWarnings("unchecked")
List<Integer> blockedByList = (List<Integer>) blockedTask.get("blockedBy");
if (!blockedByList.contains(taskId)) {
blockedByList.add(taskId);
saveTask(blockedTask);
}
} catch (Exception e) {
// 忽略不存在的任务
}
}
}
saveTask(task);
return gson.toJson(task);
}
private void clearDependency(int completedId) throws IOException {
Files.list(tasksDir)
.filter(p -> p.getFileName().toString().endsWith(".json"))
.forEach(p -> {
try {
String content = Files.readString(p);
Type type = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> task = gson.fromJson(content, type);
@SuppressWarnings("unchecked")
List<Integer> blockedBy = (List<Integer>) task.get("blockedBy");
if (blockedBy != null && blockedBy.contains(completedId)) {
blockedBy.remove(Integer.valueOf(completedId));
Files.writeString(p, gson.toJson(task));
}
} catch (IOException e) {
// 忽略读取错误
}
});
}
public String listAllTasks() throws IOException {
List<Map<String, Object>> tasks = new ArrayList<>();
Files.list(tasksDir)
.filter(p -> p.getFileName().toString().endsWith(".json"))
.sorted()
.forEach(p -> {
try {
String content = Files.readString(p);
Type type = new TypeToken<Map<String, Object>>(){}.getType();
tasks.add(gson.fromJson(content, type));
} catch (IOException e) {
// 忽略错误
}
});
if (tasks.isEmpty()) {
return "No tasks.";
}
StringBuilder sb = new StringBuilder();
for (Map<String, Object> 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<Integer> blockedBy = (List<Integer>) task.get("blockedBy");
String blockedStr = (blockedBy != null && !blockedBy.isEmpty())
? " (blocked by: " + blockedBy + ")"
: "";
sb.append(String.format("%s #%d: %s%s\n", marker, id, subject, blockedStr));
}
return sb.toString().trim();
}
}
// --- 工具处理器映射 ---
private static final Map<String, ToolExecutor> TOOL_HANDLERS = new HashMap<>();
static {
// 初始化任务管理器
TaskManager taskManager;
try {
taskManager = new TaskManager(TASKS_DIR);
} catch (IOException e) {
throw new RuntimeException("Failed to initialize task manager", e);
}
// ... 省略基础工具注册
// 注册 Task Create 工具
TOOL_HANDLERS.put(ToolType.TASK_CREATE.name, args -> {
String subject = (String) args.get("subject");
String description = (String) args.get("description");
return taskManager.createTask(subject, description);
});
// 注册 Task Get 工具
TOOL_HANDLERS.put(ToolType.TASK_GET.name, args -> {
int taskId = ((Number) args.get("task_id")).intValue();
return taskManager.getTask(taskId);
});
// 注册 Task Update 工具
TOOL_HANDLERS.put(ToolType.TASK_UPDATE.name, args -> {
int taskId = ((Number) args.get("task_id")).intValue();
String status = (String) args.get("status");
@SuppressWarnings("unchecked")
List<Integer> addBlockedBy = (List<Integer>) args.get("addBlockedBy");
@SuppressWarnings("unchecked")
List<Integer> addBlocks = (List<Integer>) args.get("addBlocks");
return taskManager.updateTask(taskId, status, addBlockedBy, addBlocks);
});
// 注册 Task List 工具
TOOL_HANDLERS.put(ToolType.TASK_LIST.name, args -> {
return taskManager.listAllTasks();
});
}
// ... 省略相同的工具实现和主循环
}
核心思想:利用基于文件的任务图,Agent 开始理解任务间的先后顺序与并行逻辑,成为真正的项目协调者。
企业级任务管理系统架构
核心思想:从简单的内存中Todo管理器升级为持久化、结构化的企业级任务管理系统,支持复杂依赖关系、多任务协同、状态持久化,适用于真实的项目管理和协作场景。
java
// 任务管理器 - 持久化存储架构
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
}更多推荐




所有评论(0)