nullpointexception-i/agent-sphere

GitHub: nullpointexception-i/agent-sphere

一个基于 ReAct 循环与多级记忆系统的 AI Agent 编排平台,支持通过 LLM 驱动浏览器、命令行及 MCP 工具实现感知到执行的自动化闭环。

Stars: 312 | Forks: 8

本项目是一个 AI Agent 编排平台。由基于 LLM 的决策引擎驱动,并结合多种能力(内置工具、MCP 协议、CLI 执行、浏览器自动化等),实现了 **感知 → 规划 → 执行 → 反馈** 的核心闭环。 ## 支持配置不同的模型提供商:OpenAI、DeepSeek、QuickRouter(中转站)、BigModel(智谱 AI)、LiteLLM。 截图 ![ui-register.png](https://static.pigsec.cn/wp-content/uploads/repos/cas/49/49f12a10b6afaed610e48265a37dd6aa4a15de05fe2190ed1d934bac3eba9eea.png) ![ui-chat.png](https://static.pigsec.cn/wp-content/uploads/repos/cas/32/32ca991fea3253a330b08bf43eb0170df3e8ba8a503792ec71bffd69699151ff.png) ![ui-chat-toolcalls.png](https://static.pigsec.cn/wp-content/uploads/repos/cas/94/944b369b5e45d3bedfe3009993f5d585eaf47c36e3c8b30d245ffc3526512c0a.png) ![ui-artifact-document.png](https://static.pigsec.cn/wp-content/uploads/repos/cas/bf/bfcf60a2bd7a66106a53c94eab4070f184ed5844329d6cf84891076eb78892ba.png) ▶ [点击观看视频演示](https://www.bilibili.com/video/BV1WqTT62Efq/) [![Video preview](https://static.pigsec.cn/wp-content/uploads/repos/cas/2e/2eb173354b5d2c0a335ddd8f1bdb75cd728c16c1d223262592feceb67c5e86b8.gif)](https://www.bilibili.com/video/BV1WqTT62Efq/) ## 1. 开发快速入门 详见:[QUICK_START.md](QUICK_START.md) ## 2. 架构 ### 2.1 整体结构 ![agentsphere-architecture.png](https://static.pigsec.cn/wp-content/uploads/repos/cas/5e/5edf2305bff066c666eb39c75f4a2d2d7d86846638f6f10b3f66dddd66383376.png) ### 2.2 核心组件 #### 2.2.1 SessionRunner (ReAct 引擎) 管理 AI 会话的完整执行生命周期,实现了 **规划 → 执行 → 观察 → 学习** 循环: ![SessionRunner.run 执行生命周期](https://static.pigsec.cn/wp-content/uploads/repos/cas/26/26752e4363221ecd555630657a1043bd8b70af0de5a4ae8c8e02d39964d770f6.png) **与 ReAct 模式的对应关系:** ![ReAct 模式对应关系](https://static.pigsec.cn/wp-content/uploads/repos/cas/fe/fee42426311ab37269f2523d570767f12939be67338e4bb0219d88a8b65ceeb4.png) #### 2.2.2 能力层 | 能力类型 | 实现方式 | 描述 | 示例 | |-----------------|----------------|-------------|----------| | **MCP (Model Context Protocol)** | MCP Server 客户端 | 标准协议,连接到任何 MCP Server | Jira, GitHub, Slack, 数据库 | | **Builtin (内置工具)** | SPI: `CapabilityBuiltinToolSpi` | Java SPI 扩展 | WebFetch, WebRead, Chrome, Todowrite, DocWrite | | **Chrome 浏览器** | Chrome 扩展桥接 | DOM 操作 + 实时视觉反馈 | 导航、点击、填写表单、截图 | | **CLI (命令行)** | `ProcessBuilder` 执行 | 本地或远程 shell | Git 操作、构建/部署、系统管理 | | **Skill (复合技能)** | 多步骤任务编排 | LLM 驱动的任务分解 | 跨系统工作流 | #### 2.2.3 Chrome 扩展 (浏览器桥接) ![Chrome 扩展浏览器桥接结构](https://static.pigsec.cn/wp-content/uploads/repos/cas/8b/8b636d776d65f17bd27a647e2f9640add13cc8443370913e3f15277d279f1f56.png) ## 3. 算法 — 核心算法 ### 3.1 ReAct 执行循环 AgentSphere 的核心循环遵循 **ReAct (Reasoning + Acting)** 模式,结合了 LLM 的推理能力与工具执行能力: ![ReAct 执行循环](https://static.pigsec.cn/wp-content/uploads/repos/cas/e4/e491635eba680e99c08ef4f0492a85bf9ebf57f29e0c3e2712c73f2492b44cbd.png) **消息结构:** ``` [ {role: "system", content: "You are a browser assistant..."}, {role: "user", content: "Help me check the weather in Guangzhou"}, {role: "assistant", tool_calls: [{id: "call_1", name: "navigate", args: "..."}}]}, {role: "tool", tool_call_id: "call_1", content: '{"tabId": 42, "url": "..."}'}, {role: "assistant", content: "The weather in Guangzhou tomorrow is..."}, {role: "user", content: "What should I prepare for going out tomorrow"}, ... ] ``` **多轮工具调用示例:** ![多轮工具调用示例](https://static.pigsec.cn/wp-content/uploads/repos/cas/8a/8a1152fc415f9234b4c737d5c366b0533556d485a71de04714b1992537a86f6e.png) ### 3.2 多级记忆系统 AgentSphere 实现了多级记忆系统,覆盖了从持久化到运行时缓存的全链路: ![多级记忆系统](https://static.pigsec.cn/wp-content/uploads/repos/cas/6e/6ec834c0f6c421e743f72f45f28cb3239d5c26fe9c61be2ffec96c0e0da892d4.png) #### 记忆层级详情 | 层级 | 存储方式 | 生命周期 | 容量 | 用途 | |-------|---------|-----------|----------|---------| | L1: KernelContext | ConcurrentHashMap | 运行期间 (TTL 30分钟) | 每个会话 1 个 | 工具列表、模型路由 | | L2: Messages | ArrayList | 运行期间 | 数十轮 | LLM 输入/输出 | | L3: LLM 交互 | PostgreSQL | 永久 | 可配置 | 调试与审计 | | L4: 工具调用 | PostgreSQL | 永久 | 无限 | 重放、观察 | | L5: 压缩记录 | PostgreSQL | 永久 | 累积 | 上下文压缩 | | L6: Session | PostgreSQL | 永久 | 每个会话 1 个 | 元数据 | #### 3.2.1 上下文组装 `HistoryLoader` 负责从持久化存储中加载历史消息,并将其组装为 LLM 上下文: ![HistoryLoader 上下文组装](https://static.pigsec.cn/wp-content/uploads/repos/cas/04/0494cabfbd3fb87c82ad426c7792afa9dcbb6b5d46273c1800703b5de3671fb2.png) **工具结果压缩流程:** ![工具结果写入时压缩流程](https://static.pigsec.cn/wp-content/uploads/repos/cas/20/203ae3671505dab59b7e6c769e2f2aaf830d4680dd9dbc9b7ff6868ab97c7479.png) #### 3.2.2 上下文压缩 当消息估算的 token 数超过 `maxInputTokens × budget-ratio` 时触发: ![上下文压缩](https://static.pigsec.cn/wp-content/uploads/repos/cas/12/12372c54e425309516276d5abbec470cbc00cd1ec8070517bab5e2aa8e7c137e.png) **完整压缩链流程:** ![完整压缩链流程](https://static.pigsec.cn/wp-content/uploads/repos/cas/0a/0aa23eb1d03e5f168a64228982c982ab8ffe31c31898151b1803538491f583d1.png) #### 3.2.3 工具调用记录状态机 ![工具调用记录状态机](https://static.pigsec.cn/wp-content/uploads/repos/cas/ba/ba03749a05d9602db482899948bde0eafc31205d3c0cccd38a72a55e6e75cb37.png) 每条记录包含: - `callId` — LLM 生成的工具调用 ID(例如 `call_abc123`) - `argumentsJson` — 原始输入参数 - `compressedArguments` — 输入 JSON 的压缩版本(写入时压缩) - `artifact` — 原始返回结果 - `compressedArtifact` — 结果 JSON 的压缩版本(写入时压缩) - 供 HistoryLoader 用于重放、观察面板展示以及审计 #### 3.2.4 工具结果压缩策略 ``` jsonCompress(node, depth, maxValueChars) { if (depth > 5) return "[deep nested]"; if (node instanceof Map) { // Recursively compress each value return map.mapValues(v -> jsonCompress(v, depth+1, maxValueChars)) } if (node instanceof List) { if (list.size() <= 5) return list.map(v -> jsonCompress(v, depth+1)) // Large array: keep first 3 + total count return { _count: 13, _showing: 3, items: [...] } } if (node instanceof String) { if (text.length() <= maxValueChars) return text // Long string: first 100 + ellipsis + last 50 return text[0..100] + "...[+ N chars]...\n" + text[-50..-1] } return node // Number, Boolean pass-through } ``` ### 3.3 模型路由与降级 AgentSphere 提供了多级模型容错机制,以确保 LLM 调用的高可用性。 #### 路由配置 ![模型路由配置](https://static.pigsec.cn/wp-content/uploads/repos/cas/ec/ec995cef8dd36c40d9a38222b68ae57a0653fb106abb0a02204865c96b8a002f.png) #### 降级执行流程 ![降级执行流程](https://static.pigsec.cn/wp-content/uploads/repos/cas/be/be76fc8cae499e3fceae673d50e14d42fbe9253cafcf717d22ace3249feb4a5c.png) #### 压缩预算计算 ``` budget = maxInputTokens × budget-ratio (default 0.7) Example: Route: GLM-4.1V-Thinking-Flash, maxInputTokens=1_000_000 → budget = 1_000_000 × 0.7 = 700_000 tokens → When messages exceed 700K tokens → trigger compaction Dynamic adjustment: budget-ratio: 0.5 → Triggers earlier (preserves more context quality) budget-ratio: 0.8 → Triggers later (saves compression overhead) ``` #### 超时参数 | 参数 | 默认值 | 描述 | |-----------|---------|-------------| | `llm.connect-timeout` | 30s | 连接 LLM API 的超时时间 | | `llm.read-timeout` | 60s | 读取响应的超时时间 | | `llm.stream-read-timeout` | 120s | 流式读取超时时间 | | `llm.stream-timeout` | 120s | 流式调用的总超时时间 | | `runner.turn-timeout` | 180s | 单次 LLM 轮次的总超时时间 | ### 3.4 浏览器操作流程 ![浏览器操作流程](https://static.pigsec.cn/wp-content/uploads/repos/cas/1e/1ecf75ed1e8b46c964af27c7e776c65e4b8400087112847bf9ce958de102e598.png) ### 3.5 多标签页管理 ![多标签页管理](https://static.pigsec.cn/wp-content/uploads/repos/cas/9c/9ca0e95bfc95f6d6d75c43dffc1f5d1ff93e96f5c2207331141e675908164443.png) ### 3.6 超时与取消链路 ![超时与取消链路](https://static.pigsec.cn/wp-content/uploads/repos/cas/a1/a1baead7b84daaa7992d3ff27f2defc2b8844891b66cd42669a00a8490f40a7a.png) ### 3.7 会话追踪 ![会话追踪](https://static.pigsec.cn/wp-content/uploads/repos/cas/93/93deffd8cf86884acf3cdf56419d82a7a2a441d1308c7c745c976b6ed0a4d58b.png) ## 4. 管理 — 运维与管理 ### 4.1 配置参考 | 配置项 | 默认值 | 描述 | |-------------|---------|-------------| | `session.idle-timeout` | 30m | 会话空闲超时时间 | | `session.max-concurrent-runs` | 10 | 最大并发执行数 | | `runner.max-loop-count` | 128 | 每次运行的最大循环次数 | | `runner.turn-timeout` | 180s | 单次 LLM 轮次超时时间 | | `runner.compaction.budget-ratio` | 0.7 | 压缩触发阈值(占 maxInputTokens 的比例) | | `llm.connect-timeout` | 30s | LLM API 连接超时时间 | | `llm.read-timeout` | 60s | LLM API 读取超时时间 | | `llm.stream-timeout` | 120s | 流式调用总超时时间 | | `tool.max-parallel` | 3 | 最大并行工具执行数 | | `tool.execution-timeout` | 60s | 单批次工具执行超时时间 | | `tool.submit-timeout` | 30s | 工具提交超时时间 | ### 4.2 可观测性 AgentSphere 提供了三层观测系统: #### 4.2.1 实时事件 (SSE 事件) ``` Real-time push of LLM call chain: content_token → "The weather in Guangzhou tomorrow..." reasoning_token → "🤔 The user is asking about weather, I need to open a weather website" → "⚙️ navigate: calling..." → "⚙️ navigate: succeeded ✅" → "⚙️ getContent: calling..." → "⚙️ getContent: succeeded ✅" → "⏹️ Run cancelled" or "✅ Run completed" ``` | SSE 事件 | 触发条件 | 前端效果 | |-----------|---------|-----------------| | `content_token` | LLM 文本生成 | 打字机效果 | | `reasoning_token` | LLM 推理、工具状态 | 推理面板 | | `browser_operation` | Chrome 操作指令 | 扩展执行 | | `run_running` | 运行开始 | 状态指示器 | | `run_completed` | 运行完成 | 完成通知 | | `run_failed` | 运行失败 | 错误提示 | | `tool_call_started` | 工具 PENDING(待处理) | 工具调用列表 | | `tool_call_succeeded` | 工具完成 | ✅ 图标 | | `tool_call_failed` | 工具失败 | ❌ 图标 | | `compaction_running` | 压缩开始 | 推理面板 | | `compaction_completed` | 压缩完成 | 推理面板 | #### 4.2.2 运行活动 API 提供完整的工具调用历史查询: ``` GET /api/v1/instance/runs/{runId}/activities?offset=0&limit=20 Response: { "total": 20, "records": [ { "activityType": "llm_interaction", "modelName": "deepseek-v4-flash", "interactionType": "CHAT_REPLY", "durationMs": 2588, "requestBody": "{...}", "responseBody": "{...}", "success": true }, { "activityType": "tool_call", "toolName": "builtin_5", "displayName": "builtin.CapabilityBuiltinToolChrome", "argumentsJson": "{...}", "artifact": "{...}", "status": "SUCCEEDED" } ] } ``` #### 4.2.3 会话面板 | 视图 | 内容 | |------|---------| | **运行列表** | 按会话查看历史运行,显示 userMessage + assistantReply | | **工具调用列表** | 当前会话的最新工具调用记录(按创建时间降序排列) | | **Todo 列表** | 当前会话的 Todo 清单,包含状态追踪 | | **操作日志** | Chrome 扩展弹窗中的历史操作记录 | ### 4.3 日志系统 | Logger | 级别 | 用途 | |--------|-------|---------| | `ControllerLogAspect` | INFO | API 请求/响应日志 | | `ChromeCallbackController` | WARN | 浏览器操作失败 | | `FiberSet` | WARN | 工具超时/失败 | | `SessionRunner` | INFO | 执行轮次与状态 | | `LlmInteractionPersistListener` | DEBUG | LLM 交互记录持久化 | | `RuntimeEventListener` | DEBUG | 工具调用生命周期事件 | ### 4.4 关键部署步骤 ``` # 构建后端 cd agent-sphere mvn compile -pl agent-sphere-bootstrap -am # 启动后端 mvn spring-boot:run -pl agent-sphere-bootstrap # 启动前端 cd agent-sphere-ui npm run dev # 加载 Chrome Extension # Chrome → chrome://extensions → Developer mode → Load unpacked # 选择 agent-sphere-chrome-extension 目录 # 配置 URL # 点击扩展图标 → Settings Tab # Frontend URL: http://localhost:8000 # Backend URL: http://localhost:8080 ``` ### 4.5 架构决策记录 (ADR) | 决策 | 方案 | 原因 | |----------|----------|--------| | **SSE vs WebSocket** | Server-Sent Events | 单向推送无需客户端确认,浏览器原生支持 | | **fetch+ReadableStream vs EventSource** | fetch + ReadableStream | EventSource 在 MV3 Service Worker 中无法携带 Authorization 头 | | **Virtual Threads** | Java 21 虚拟线程 | 简化并发模型,每个工具分配一个虚拟线程 | | **Chrome 扩展独立部署** | 独立项目 | 与 Web UI 解耦,权限隔离 | | **多发射器 SSE** | 每个会话 `List` | Web UI 与扩展共享同一 SSE 通道 | | **FiberSet cancel(true)** | `CompletableFuture.cancel(true)` | 在超时时有效中断阻塞的虚拟线程 | | **工具结果写入时压缩** | `RuntimeEventListener` 压缩后写入 `compressed_artifact` | HistoryLoader 读取时无需重新压缩,减少冗余计算 | | **基于 Token 预算的压缩触发** | `runTurn` 的 execute 回调中的 `shouldCompact` | 使用实际调用的模型路由的 maxInputTokens 以确保准确性 | | **压缩游标** | `compactedUptoRunId` 标记已压缩的运行 | HistoryLoader 跳过已压缩的运行,仅加载后续运行 | | **压缩保护循环** | 最大重试 3 次 | 防止因网络波动导致压缩失败时出现死循环 | ### 4.6 能力扩展 #### 添加新的内置工具 ``` @Component public class CapabilityBuiltinToolMyTool implements CapabilityBuiltinToolSpi { @Override public BuiltinToolEnum getToolType() { return BuiltinToolEnum.MY_TOOL; } @Override public ToolInfoVO getInfo() { ToolInfoVO info = new ToolInfoVO(); info.setName(BuiltinToolConstants.NAME_PREFIX + "MyTool"); info.setDescription("Description for LLM"); info.setParamSchema(ToolSchemaUtil.generateParamSchema(MyToolDTO.class)); info.setResponseSchema(ToolSchemaUtil.generateParamSchema(MyToolResultVO.class)); return info; } @Override public ExecuteResult execute(ExecuteContext ctx) { MyToolDTO dto = (MyToolDTO) ctx; // Implementation logic return new MyToolResultVO(/* result */); } } ``` ## 5. 项目结构 ![项目结构](https://static.pigsec.cn/wp-content/uploads/repos/cas/4a/4a66eb1eadb940f6cdad522a55c0b285529a165490da8acb0dfde339cb059404.png) ## 6. 技术栈 | 领域 | 技术 | |--------|------------| | **后端运行时** | Java 21, Spring Boot 3.4, Virtual Threads | | **数据库** | PostgreSQL, Flyway 数据迁移 | | **缓存/分布式锁** | Redis (Redisson) | | **前端** | React, UmiJS, Ant Design Pro | | **Chrome 扩展** | Manifest V3, Service Worker, Content Script | | **实时通信** | SSE (Server-Sent Events), 多器广播 | | **工具协议** | MCP (Model Context Protocol, Streamable HTTP) | | **API 安全** | Bearer Token, @WithTenant 多租户 | | **LLM 集成** | SPI provider 抽象,自动降级路由 | ## 7. MCP 集成示例 AgentSphere 支持通过 MCP 协议连接到任何外部服务。以 Jira 为例: ``` # 部署 Jira MCP Server npx @roovet/jira-mcp --port 3100 # 在 AgentSphere 管理控制台中添加 MCP capability curl -X POST /api/v1/capability/mcp \ -d '{"name":"Jira MCP","serverUrl":"http://localhost:3100","serverType":"streamable-http"}' # 将其绑定到一个 Agent instance curl -X POST /api/v1/instance/instance-capabilities \ -d '{"instanceId":1,"capabilityType":"mcp","capabilityId":1}' # 用户只需在聊天中发送指令 # “帮我在 Jira 上查看我未完成的任务” # → LLM 调用 MCP tool → Jira API → 返回结果 ``` ![MCP 配置 UI](https://static.pigsec.cn/wp-content/uploads/repos/cas/75/75bc0c91d540ec2bfee7e708d00ba713527f0fc86921bd1fb69bb6adffb6bbd0.png) ## 8. 许可证 MIT License Copyright (c) 2026 Buukle
标签:DLL 劫持, JS文件枚举, LLM编排, MCP协议, ReAct模式, 域名枚举, 大语言模型, 测试用例, 浏览器自动化