Claude Agent Loop - Java Implementation
使用 Java 原生 HTTP 客户端实现的 Claude Agent Loop,复刻 Learn Claude Code 的核心功能。
模块
说明
运行命令
S01_agent_loop
基础 Agent 循环,持续调用 LLM 直到模型停止
mvn exec:java -Dexec.mainClass=com.example.S01_agent_loop
S02_tool_use
添加 Bash/Read/Write/Edit 工具支持
mvn exec:java -Dexec.mainClass=com.example.S02_tool_use
S03_todo_write
Todo 工具 + 进度追踪 + 超时提醒机制
mvn exec:java -Dexec.mainClass=com.example.S03_todo_write
S04_subagent
子代理上下文隔离,任务委派
mvn exec:java -Dexec.mainClass=com.example.S04_subagent
S05_skill_loading
技能加载,按需注入领域知识
mvn exec:java -Dexec.mainClass=com.example.S05_skill_loading
┌─────────────────────────────────────────────────────────────────────┐
│ S01: Agent Loop │
│ ┌──────────┐ ┌───────┐ ┌─────────┐ │
│ │ User │ -> │ LLM │ -> │ Bash │ │
│ └──────────┘ └───┬───┘ └────┬────┘ │
│ ^ | │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ S02: Tool Use │
│ ┌──────────┐ ┌───────┐ ┌─────────────────────────────┐ │
│ │ User │ -> │ LLM │ -> │ Bash │ Read │ Write │ Edit │ │
│ └──────────┘ └───┬───┘ └─────────────────────────────┘ │
│ ^ │
│ └─────────────────────────────────────────────┘
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ S03: Todo Write │
│ ┌──────────┐ ┌───────┐ ┌─────────────────────────────┐ │
│ │ User │ -> │ LLM │ -> │ Bash │ Read │ Write │ Todo │ │
│ └──────────┘ └───┬───┘ └─────────────────────────────┘ │
│ ^ │
│ │ ┌─────────────────────────────────────────┐ │
│ └──│ TodoManager: [ ] [>] [x] + nag reminder│ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ S04: Subagent │
│ ┌───────────────────┐ ┌───────────────────┐ │
│ │ Parent Agent │ │ Subagent │ │
│ │ messages=[...] │ ┌────┐ │ messages=[] │ │
│ │ + task tool │──>|task│────>| (fresh context) │ │
│ │ │ └────┘ │ + bash/read/ │ │
│ │ │ <summary> │ write/edit │ │
│ │ │ │ │ │
│ └───────────────────┘ └───────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ S05: Skill Loading - Two-layer Knowledge Injection │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ System Prompt (Layer 1) │ │
│ │ Skills available: │ │
│ │ - pdf: Process PDF files [file-processing] │ │
│ │ - code-review: Review code for bugs [quality] │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────┐ ┌───────┐ ┌─────────────────────────────┐ │
│ │ User │ -> │ LLM │ -> │ load_skill("pdf") │ │
│ └──────────┘ └───┬───┘ └─────────────────────────────┘ │
│ ^ │
│ │ ┌─────────────────────────────────────────┐ │
│ └──│ <skill name="pdf"> │ │
│ │ Full PDF processing instructions... │ │
│ │ Step 1: Extract text from PDF │ │
│ │ Step 2: Process images... │ │
│ │ </skill> │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Java 17+
Maven 3.6+
Anthropic API Key
# 复制环境配置示例
cp .env.example .env
# 编辑 .env 文件
ANTHROPIC_AUTH_TOKEN=your_api_key_here
MODEL_ID=claude-sonnet-4-20250514
ANTHROPIC_BASE_URL=https://api.anthropic.com
# 运行 S01 - 基础 Agent Loop
mvn exec:java -Dexec.mainClass=com.example.S01_agent_loop
# 运行 S04 - 子代理
mvn exec:java -Dexec.mainClass=com.example.S04_subagent
src/main/java/com/example/
├── S01_agent_loop.java # 基础循环 + Bash 工具
├── S02_tool_use.java # 多工具支持 (bash/read/write/edit)
├── S03_todo_write.java # Todo 工具 + 进度追踪
├── S04_subagent.java # 子代理上下文隔离
├── S05_skill_loading.java # 技能加载,按需注入领域知识
└── model/
├── ApiRequest.java # API 请求体
├── ApiResponse.java # API 响应体
├── Message.java # 消息结构
├── MessageContent.java # 消息内容 (text/tool_use/tool_result)
├── Tool.java # 工具定义
├── ToolInputSchema.java # 工具参数 Schema
├── JsonInput.java # 工具输入参数
├── TodoItem.java # Todo 项
└── TodoInput.java # Todo 输入
private void agentLoop (List <Message > messages ) {
while (true ) {
ApiResponse response = callAnthropic (messages );
if (!"tool_use" .equals (response .getStop_reason ())) {
return ; // 模型完成,退出循环
}
// 执行工具并收集结果
List <MessageContent > results = executeTools (response .getContent ());
// 将工具结果追加到消息历史
messages .add (Message .createUserMessage (results ));
}
}
// 父代理
List <Message > parentMessages = ...; // 完整对话历史
// 子代理 - Fresh Context
List <Message > subMessages = new ArrayList <>();
subMessages .add (createUserMessage (prompt )); // 仅任务描述
// 子代理执行工具,返回摘要
String summary = runSubAgent (prompt );
// 父代理上下文保持干净
// SkillLoader 扫描 skills/<name>/SKILL.md 文件
private static final Path SKILLS_DIR = Paths .get (System .getProperty ("user.home" ), "skills" );
private static final SkillLoader SKILL_LOADER = new SkillLoader (SKILLS_DIR );
// Layer 1: 系统 prompt 中包含技能描述
systemPrompt = "You are a coding agent...\n \n " +
"Skills available:\n " +
SKILL_LOADER .getDescriptions ();
// Layer 2: 按需加载完整技能内容
handlers .put ("load_skill" , input -> SKILL_LOADER .getContent (input .getSkill_name ()));
// 返回格式:<skill name="pdf">完整技能内容</skill>
技能文件格式 (skills/pdf/SKILL.md)
---
name : pdf
description : Process PDF files
tags : file-processing
---
完整的技能内容/指示...
Step 1: Extract text from PDF
Step 2: Process images...
工具
描述
所属模块
bash
执行 shell 命令
S01+
read_file
读取文件内容
S02+
write_file
写入文件
S02+
edit_file
编辑文件 (替换文本)
S02+
todo
更新任务列表
S03+
task
委派给子代理
S04
load_skill
加载技能知识
S05
路径安全检查 : 所有文件操作限制在项目工作目录内
危险命令过滤 : 阻止 rm -rf /, sudo, shutdown 等命令
超时保护 : Bash 命令 120 秒超时
迭代限制 : 子代理最多 30 次迭代