ReActAgent 源码分析

概述 ReActAgent 是 AgentScope Java 的核心推理引擎,位于 agentscope-core 模块。它实现了 ReAct (Reasoning and Acting) 设计模式——在推理(想下一步做什么)和执行(调工具)之间交替循环。 源码位置:agentscope-core/src/main/java/io/agentscope/core/ReActAgent.java(1925 行) 核心依赖 public class ReActAgent extends StructuredOutputCapableAgent { private final Memory memory; // 对话历史(InMemoryMemory) private final String sysPrompt; // 系统提示词 private final Model model; // LLM 模型 private final int maxIters; // 最大迭代次数(默认 10) private final Toolkit toolkit; // 可用工具集 private final PlanNotebook planNotebook; // 计划本 private final StatePersistence statePersistence; // 状态持久化策略 } 核心循环:reason → act → reason → act → … 整个 ReAct 循环的入口: private Mono<Msg> executeIteration(int iter) { return reasoning(iter, false); // 先推理 } reasoning 阶段(第 560-650 行) ① 检查 maxIters → 超限则走 summarizing() ② notifyPreReasoningEvent() ← Hook 注入点:CompactionHook、SubagentsHook、WorkspaceContextHook ③ model.stream(messages + tool schemas) ← 调 LLM ④ 逐 chunk 处理 + notifyReasoningChunk() ← 流式输出 ⑤ notifyPostReasoning() ← Hook 注入点 ⑥ 判断: - stopRequested → 返回(HITL 打断) - gotoReasoning → 继续推理(结构化输出重试) - isFinished(msg) → 没有 tool call → 返回结果 - 有 tool call → going to acting(iter) 关键判断 isFinished(第 969 行): ...

May 22, 2026 · 3 min · 531 words · WY

把你的Java后端经验重新编译一次:当Netty/Epoll/JVM映射到AI Infra

翻译:你的Java后端经验,就是AI Infra最好的预习材料。 一、你先要理解一件事 AI Infra 不是什么全新的知识体系。它是一个同构系统,只是运行在 GPU 上。 你的舒适区 AI Infra 的真相 ─────────────────────────────────────────────────────── Netty EventLoop 接收请求 SM(Streaming Multiprocessor)接收 Warp ByteBuf 池化管理内存 PagedAttention 分块管理显存 epoll 事件驱动 IO CUDA Stream 异步执行 JVM 的 GC 分代回收 KV Cache 的 Block Eviction Kafka 的分区与批量 NCCL 的 Ring AllReduce Tomcat 的连接池 Triton Server 的 Request Queue Spring 的 AOP 代理 CUDA Graph 的 Kernel 捕获 CompletableFuture 异步编排 CUDA Stream 的依赖管理 JMX / Metrics 监控 Nsight Systems 性能分析 一模一样的问题,一模一样的抽象层次,区别只在 Scale 和物理介质。 ...

May 22, 2026 · 11 min · 2328 words · WY

系列01:内存管理——当你在管理 ByteBuf 时,你已经在管理 KV Cache 了

这篇讲什么 这是个系列的第一篇。我选"内存管理"作为开篇,因为: 你最熟——Netty ByteBuf、JVM 堆、堆外内存,你每天都在打交道 映射最直接——ByteBuf 池化 = KV Cache Block 管理 = GPU 显存池 代码最少——核心逻辑 100 行就能说清原理 读完这篇,你会理解: ByteBuf 的引用计数为什么等于 vLLM Block 的 refcount JVM 的 G1 Region 为什么等于 PagedAttention 的 Block GPU 显存池为什么是你的 PooledByteBufAllocator 在另一个地址空间的翻版 并且,你可以亲手写一个"Java 版显存管理器" 一、问题本质 内存管理要解决的只有三个问题: 1. 分配——如何快速找到一块可用的内存 2. 回收——用完后如何归还,确保不漏 3. 碎片——如何避免小块空隙越积越多 你在 Java 后端看到过这些方案的演进: JVM 堆管理: Serial GC → 标记-整理(压缩碎片) CMS → 标记-清除(不压缩,碎片多) G1 → Region 分区(固定大小,消除碎片) ZGC → 染色指针 + 读屏障(几乎无停顿) Netty 堆外内存管理: UnpooledByteBufAllocator → 每次分配新 DirectBuffer PooledByteBufAllocator → 预分配 Arena + Chunk + Page 分三级管理 AI Infra 的显存管理(正在发生和你一模一样的事情): PyTorch 默认(CUDACachingAllocator)→ 有缓存但碎片严重 vLLM PagedAttention → Region 分块(和 G1 一样的思路) 这不是类比,这是同一个问题在不同约束下的工程演化。 ...

May 22, 2026 · 8 min · 1693 words · WY

AgentScope Java Harness 架构与实战指南

前言 AgentScope Java 的 Harness 模块是一个面向生产环境的多智能体运行时框架。本文基于官方文档,从其设计理念到具体代码实践,完整梳理 Harness 的核心架构与使用方式。 一、Harness 是什么 agentscope-harness 在 agentscope-core 的 ReActAgent 之上,通过 Hook 和 Toolkit 两个扩展点,装配出一套面向长期稳定运行的工程化基础设施。它的入口只有一个类:HarnessAgent。 裸的 ReActAgent 只有"请求 — 推理 — 工具 — 回复"一轮循环。而 Harness 要回答的是一组更贴近生产的问题: 下一轮怎么办? 下一天怎么办? 上下文爆了怎么办? 状态丢了怎么办? 任务太重怎么办? 它不替换推理循环,而是在循环的关键时机插入 hook、为模型补上一组基础工具,把这些问题的默认工程答案打包好。 快速开始 <dependency> <groupId>io.agentscope</groupId> <artifactId>agentscope-harness</artifactId> <version>${agentscope.version}</version> </dependency> public class QuickstartExample { public static void main(String[] args) throws Exception { // 1. 准备工作区 Path workspace = Paths.get(".agentscope/workspace"); initWorkspaceIfAbsent(workspace); // 2. 构建模型 Model model = DashScopeChatModel.builder() .apiKey(System.getenv("DASHSCOPE_API_KEY")) .modelName("qwen-max") .stream(true) .build(); // 3. 构建 HarnessAgent HarnessAgent agent = HarnessAgent.builder() .name("quickstart-agent") .sysPrompt("你是一个帮助用户做笔记的助手。") .model(model) .workspace(workspace) .compaction(CompactionConfig.builder() .triggerMessages(30) .keepMessages(10) .flushBeforeCompact(true) .build()) .build(); // 4. 两轮对话,同一 sessionId RuntimeContext ctx = RuntimeContext.builder() .sessionId("demo-session") .userId("alice") .build(); Msg turn1 = agent.call( Msg.builder().role(MsgRole.USER) .textContent("我叫天宇,今天准备做一个关于 ReAct 的技术分享。") .build(), ctx).block(); Msg turn2 = agent.call( Msg.builder().role(MsgRole.USER) .textContent("我叫什么?我今天要干什么?") .build(), ctx).block(); } private static void initWorkspaceIfAbsent(Path workspace) throws Exception { Files.createDirectories(workspace); Path agentsMd = workspace.resolve("AGENTS.md"); if (Files.exists(agentsMd)) return; Files.writeString(agentsMd, """ # 笔记助手 你是一个帮助用户整理笔记和知识的助手。 ## 行为约定 - 主动记录用户提到的关键事实(姓名、计划、偏好等) - 回答用简洁中文,必要时给出要点列表 - 对不确定的内容要主动说明,不要臆造 """); } } 上述代码展示了 Harness 的三个核心价值:工作区驱动的人格、会话持久化(同一 sessionId 的第二轮对话记得第一轮的内容)、显式启用对话压缩。 ...

May 20, 2026 · 13 min · 2670 words · WY