Agent Zero

一句话定位

Agent Zero 是一个”薄内核 + 满场扩展点”的通用个人 agent 框架:主循环极简(单工具 JSON 协议驱动、唯一停机靠 response 工具),几乎所有行为(系统提示、工具集、记忆、行为准则)都下沉到可运行时覆盖的 prompt 文件和插件里,靠递归子 agent 派生做任务分解,靠 FAISS 向量记忆 + 可写回的 behaviour.md 做 in-context 自进化,靠 Docker 双 Python runtime + 别名 secret 注入做安全。不含任何模型训练/RL 闭环。

核心架构总览(目录结构关键路径 + 引用的 commit)

分析基于 commit 3bb40576affb41e0ce5180e38751e211f5f210362026-07-09 17:59:27 +0200,depth=1 克隆于 2026-07-11)。注意 frdel/agent-zero(旧个人仓库)已迁到组织账号 agent0ai/agent-zero(18k+ star)。

技术栈:Python 3.12(框架)/ Python 3.13(agent 执行代码)· Flask + Alpine.js WebUI · LiteLLM · FAISS · Socket.io · Docker。

架构文档已外包给 DeepWiki(仓库内 docs/developer/architecture.md 只是一个指针),权威一手材料是根目录 AGENTS.md(19KB)+ 各插件的 AGENTS.md/README.md。关键路径:

  • agent.py — 核心 Agent/AgentContext/LoopData/主循环(60KB)
  • tools/ — 内置工具(response.pycall_subordinate.pyparallel.pyscheduler.pya2a_chat.py 等)
  • plugins/ — 36 个内置重量级插件(_memory_code_execution_skills_orchestrator_chat_compaction_browser_oauth 等),另有 usr/plugins/ 用户插件
  • skills/ — Anthropic SKILL.md 标准的轻量 skill
  • extensions/python/<hook>/ — 生命周期扩展点脚本
  • prompts/ — 根级 prompt 库(agent.system.*.mdfw.*.md 框架消息)
  • helpers/history.pymemory.pyskills.pysecrets.pyruntime.pylog.pypersist_chat.py

设计基调:@extension.extensible 装饰器把内核每一步都开成可插拔挂点,“加个 prompt 文件 + 同名 .py”就等于加了一个工具。

Agent Loop(主循环 / 何时继续何时停)

入口 Agent.monologue()agent.py:387),结构是双层 while True:外层每轮建一个新的 LoopData(iteration=-1,agent.py:335 定义),内层 message_loop 每步 iteration += 1 → 调 LLM → 解析工具 → 执行工具。

  • 协议是 JSON 单工具:LLM 每轮输出一个 JSON,字段 thoughts/headline/tool_name/tool_args。用 extract_tools.json_parse_dirty 容错解析(agent.py:1411),再 normalize_tool_request
  • 唯一停机机制:工具返回 Response(break_loop=True)。终结工具是 response/ResponseTooltools/response.pyexecute 直接 return Response(..., break_loop=True),且不写 history、不写 output)。call_subordinatecode_execution_tool 等都 break_loop=False,循环继续。process_tools()agent.py:1409)里 if response.break_loop: return response.messageagent.py:1491)才跳出内层循环。
  • 流式提前停机(stream cut-off)stream_callbackagent.py:442)在 LLM 生成中途就用 json_parse_dirty(snapshot)agent.py:454)嗅探已完整的 JSON 工具块,validate_tool_request 通过后直接截断本轮生成 —— 省 token。
  • 无固定 max_iterations:不靠步数上限停机,而是靠 response 工具 + 用户干预 + 后台历史压缩控上下文。若某轮 LLM 输出没有有效工具 JSON(misformat),追加 fw.msg_misformat.md warning 后继续循环(agent.py:1504 附近)。
  • 用户干预(intervention)handle_intervention() 在循环里被密集调用(每个流 chunk、每步工具前后),用户可随时注入消息,作为 fw.intervention.md 插入 history 打断当前动作。
  • 扩展点挂满全程monologue_start / message_loop_start / before_main_llm_call / reasoning_stream* / response_stream* / tool_execute_before / tool_execute_after / message_loop_end / monologue_end,几乎每个行为都能被 extension/plugin 覆写。

记忆与上下文管理(压缩、长期记忆、会话持久化)

三层机制并存,均已在源码中确认:

(a) 自动分层历史压缩helpers/history.py)。history 由若干 Topichistory.py:165)组成,每 Topic 含 Messagehistory.py:87);更老的 topic 合并成 Bulkhistory.py:299)。关键常量:CURRENT_TOPIC_ATTENTION_COMPRESSION=0.65HISTORY_TOPIC_ATTENTION_COMPRESSION=0HISTORY_BULK_RATIO=0.2BULK_MERGE_COUNT=3TOPICS_MERGE_COUNT=3COMPRESSION_TARGET_RATIO=0.8history.py:15-25)。压缩优先级 Topic.compress()history.py:249):先 compress_large_messages(把超大单条消息截断成 summary),否则 compress_attentionhistory.py:255,调 utility model 用 fw.topic_summary.sys/msg.md 摘要旧消息)。历史 topic 用 HISTORY_TOPIC_ATTENTION_COMPRESSION=0 最终压到只剩首尾 request/response(history.py:577)。整个 compress()history.py:517)以 COMPRESSION_TARGET_RATIO=0.8 为目标在后台线程跑:extensions/python/message_loop_end/_10_organize_history.pyDeferredTask(THREAD_BACKGROUND)agent.history.compress(),不阻塞主循环。

(b) 长期向量记忆plugins/_memory)。MyFaiss(FAISS)memory.py:41)+ CacheBackedEmbeddingsmemory.py:3,169),embedding 缓存落 tmp/memory/embeddings。三个 Area:MAIN/FRAGMENTS/SOLUTIONSmemory.py:56-59)。自动记忆extensions/python/monologue_end/_50_memorize_fragments.py 在每次 monologue 结束后台调 utility model 从 history 抽取”durable”事实 → filter_auto_memory_fragments 过滤 → memory consolidation(相似度阈值去重/合并)或直接 insert。工具侧提供 memory_save/memory_load/memory_delete/memory_forget;召回由 message_loop_prompts_after/_50_recall_memories.py 把相关记忆注入 extras

(c) 手动整会话压实plugins/_chat_compaction/helpers/compactor.py)。用户触发。run_compaction 提取全文 → 估 token → 超 ctx_length*0.7 就分块迭代摘要(_compact_large_history),否则单次(compact.sys/msg.md)→ 用一条 AI summary 消息替换整个 history。压实前会备份原始 JSON+txt 到 <chat>/backups/pre-compact-*

会话持久化helpers/persist_chat.py):save_tmp_chat 序列化 context/agent/history/log 到磁盘 JSON;load_tmp_chats 恢复;export_json_chat 导出。支持 chat 分支(_chat_branching 插件)和 time-travel(_time_travel 插件)。

工具体系(定义/调用协议/注册/权限)

  • 定义:工具 = helpers.tool.Tool 子类,实现 async execute(**kwargs) -> Response,可选 before_execution/after_executionResponse(message, break_loop, additional)
  • 注册/发现 = 约定文件路径,无中央注册表get_tool()agent.py:1548)按 agent profile 目录层级(subagents.get_paths(self, "tools", name+".py"))查找 <tool_name>.pyload_classes_from_file 动态加载首个 Tool 子类;找不到 fallback 到 tools/unknown.py:Unknown
  • 调用协议:LLM JSON 里的 tool_name + tool_args dict。分发顺序是先查 MCP 后查本地mcp_helper.MCPConfig.get_instance().get_tool(...)agent.py:1436,另 agent.py:1149 有流式路径的同类判断)命中就走 MCP,否则本地 get_tool
  • 工具提示动态拼装extensions/python/system_prompt/_11_tools_prompt.py 扫所有 prompt 目录里的 agent.system.tool.*.md,逐个 read 拼进 agent.system.tools.md;vision 模型额外加 agent.system.tools_vision.md。即”加个 prompt 文件 + 同名 .py”就等于加了工具。
  • 核心内置工具(tools/ 及各插件 tools/):responsecall_subordinatecode_execution_tool(在 _code_execution 插件)、search_enginedocument_queryknowledge_toolvision_loadschedulernotify_userwaitparallela2a_chatskills_toolunknown。每个附 .dox.md 契约文档。
  • 权限:工具层无 per-tool 审批门,默认直接执行(安全模型见后文)。

Prompt 设计(系统提示结构、动态组装)

这是 Agent Zero “prompt 即框架”最实的证据。

  • 模块化 includeprompts/agent.system.main.md 由多个 {{ include "..." }} 组成(role / specifics / environment / communication / solving / tips)。role 极简:agent.system.main.role.md 只有寥寥数行(“agent zero autonomous json ai agent…“)。
  • 系统提示由 extension 链动态拼装get_system_prompt()agent.py:683)只返回空 list 并触发 system_prompt extension hook,每个 extension append 一段。顺序(extensions/python/system_prompt/):_10_main_prompt(主手册)→ _11_tools_prompt(工具)→ _12_mcp_prompt(MCP 工具)→ _13_secrets_prompt_13_skills_prompt_14_project_prompt。插件也能注册自己的 system_prompt extension(如 _memory_20_behaviour_prompt.py 注入行为规则)。
  • prompt 覆盖机制read_prompt/parse_promptagent.py:700/agent.py:691)走 subagents.get_paths(self,"prompts") —— 优先级 agent profile 目录 > 插件 prompts > 根 prompts/,同名就近覆盖。支持 {{if}}/{{include}}/kwargs 模板。
  • LoopData 双虚拟区protocol(history 之前)和 extras(history 之后),各有 temporary/persistent(LoopDataagent.py:335)。prepare_promptagent.py:565)组装 = SystemMessage + [protocol + history_output + extras] 转 langchain 消息。动态上下文(时间/相关技能/agent info/并行任务/workdir 结构)由 message_loop_prompts_after/* extension 塞进 extras。

Router / 编排(任务分解、多 agent、子 agent)

  • 核心卖点 = 递归子 agent 派生call_subordinate 工具(tools/call_subordinate.py)。Delegation.executecall_subordinate.py:37)用 initialize_agent(override_settings)call_subordinate.py:66)造一个新 Agent(number 递增),注册 _superior/_subordinate 双向 data 指针,hist_add_user_messageawait subordinate.monologue()call_subordinate.py:79)—— 子 agent 跑自己的完整 loop,返回结果回父。层级理论无限深。
  • profile 化:子 agent 可指定 profile(如 developer/hacker/researcher,见 agents/ 目录),_validate_subordinate_profilecall_subordinate.py:17)校验;同一 subordinate 换 profile 需显式 reset=truecall_subordinate.py:46-54)。
  • 并行/调度tools/parallel.py 支持并行子任务/jobs;message_loop_prompts_after/_72_include_parallel_jobs.py 注入并行 job 状态;scheduler 工具 + job_loop 做定时/后台任务。
  • 外部 coding agent 编排plugins/_orchestrator):不是造一个 terminal_agent 工具,而是一个 orchestrator skill + 适配器注册表(helpers/registry.pyadapters/),教 Agent Zero 通过 host CLI bridge 或容器 shell 驱动 Claude Code / Codex / Cursor / Grok / Hermes / OpenCode 等 headless CLI,默认以 yolo/bypass 权限跑非交互(如 codex exec --dangerously-bypass-approvals-and-sandbox)。见 orchestrator.README.md
  • A2Atools/a2a_chat.py + docs/guides/a2a-setup.md,agent-to-agent 协议,可与其它 Agent Zero/外部 agent 互联。

Skill / 插件体系

两套体系并存:

  • Pluginsplugins/ 内置 + usr/plugins/ 用户):重量级扩展单元。每个带 plugin.yaml(name/description/version/settings_sections/per_project_config/per_agent_config/always_enabled),按文件夹约定发现(api//tools//webui//extensions//prompts//hooks.py)。helpers/plugins.py 负责发现+配置与 call_plugin_hook;激活状态用 .toggle-1/.toggle-0(全局 + scoped)。共 36 个内置插件(memory/code_execution/skills/orchestrator/browser/goal/oauth/office/telegram/whatsapp 等)。
  • Skillsskills/helpers/skills.py):采用 Anthropic 开放 SKILL.md 标准。每 skill = 文件夹含 SKILL.md(frontmatter name/description/triggers + body,skills.py:113rglob("SKILL.md") 递归发现)+ 可选 scripts//references//assets/skills_tool 工具动作 list/search/load/read_file;脚本执行交给 code_execution_toolMAX_ACTIVE_SKILLS=20skills.py:21)。
  • Skill 语义召回message_loop_prompts_after/_63_recall_relevant_skills.py 仅在 iteration 0 用 search_skills(user_instruction, limit=6)skills.py:536)检索相关 skill,注入 extrasagent.system.skills.relevant.md);_65_include_loaded_skills.py 注入已 load 的 skill 全文。
  • 自建 skill / meta-skillskills/build-skill/SKILL.md 教 agent 自己创建/改进 skill,另有 a0-create-plugin/a0-create-agent/a0-debug-plugin 等 meta-skill 让 agent 自扩展框架。

自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)

  • 行为规则自调整(behaviour adjustment) —— 最明确的自进化点:plugins/_memory/tools/behaviour_adjustment.pyUpdateBehaviour 工具接收 adjustments,读当前规则(memory 目录 behaviour.md,缺省 agent.system.behaviour_default.md),调 utility model 用 behaviour.merge.sys/msg.md 把新调整 merge 进规则集,写回 behaviour.md。该文件由 _20_behaviour_prompt.py(system_prompt extension)注入每轮系统提示 —— agent 能在对话中永久改自己的行为准则
  • 学习型记忆(solutions memory)monologue_end/_51_memorize_solutions.py 自动把成功解法存进 SOLUTIONS area,后续类似任务由 recall 召回复用;knowledge/solutions/ 也存累积解法。
  • memory consolidation:新记忆入库时做相似度检索 + LLM 合并,避免碎片堆积,记忆随用随长。
  • eval 驱动纠错 / RL:未实现。仓库无 finetune/RLHF/reward/training-loop 代码(grep 确认);轨迹不反哺权重。“自进化”限于 prompt/memory/skill 层,不触及模型参数。

可观测性(日志 / trace 格式)

  • 结构化 LogItemhelpers/log.py):Loglist[LogItem] + guidLogItem 字段 type/heading/content/kvps/id/guid/temptype 枚举含 user/response/agent/tool/code_exe/util/subagent/warning/error/info 等;log()/update()/stream() 支持增量流式更新。
  • 实时推送output() 增量序列化 → WebSocket(Socket.io)推 WebUI,set_progress 驱动进度条。
  • 每工具自带 log 对象get_log_object()(如 call_subordinatetype="subagent" + kvps=args),前端渲染成可展开的 trace 节点。
  • 敏感信息脱敏Log._mask_recursivelog.py 内,约 419 行)递归遮蔽输出中的 secret。
  • 持久化:log 随 chat JSON 存盘(persist_chat._serialize_log),可重放。
  • 无 OpenTelemetry / 外部 trace 后端集成;observability 自成一套,面向 WebUI 实时展示。

安全与权限(审批门、密钥管理)

  • 权限模型偏”信任 + 隔离”,非细粒度审批门:默认所有工具直接执行,无 per-tool approval gate。安全靠 (a) Docker 沙箱隔离(见下)、(b) 用户随时 intervention 打断、(c) 根 AGENTS.md 的 Safety 章程(针对操作本仓库的 coding agent 的规矩:改 agent.py/删核心文件/pip install/git commit 需先问、never commit secrets)。
  • 密钥管理(helpers/secrets.py)—— 真正的亮点:secrets 存 usr/secrets.envSecretsManagersecrets.py:126)只给 LLM 暴露别名 §§secret(KEY)(正则 ALIAS_PATTERNsecrets.py:18agent.system.secrets.md 教模型用别名),运行时才把真实值注入 shell/code,LLM 永远看不到明文。StreamingSecretsFiltersecrets.py:39)做流式遮蔽:即使模型试图复述 secret,输出也被实时 mask 成 ***,且按 min_trigger=3secrets.py:48)匹配前缀部分以防泄漏。save_secrets_with_merge 保护已存值不被 masked 提交覆盖。
  • OAuthplugins/_oauth 管第三方授权;orchestrator 里外部 CLI token 存插件私有目录(mode 600),并警告不共享 refresh token。

沙箱与执行隔离

  • 双 Python runtime:框架跑 /opt/venv-a0(3.12),agent 执行的代码跑 /opt/venv(3.13),隔离任务依赖污染框架(根 AGENTS.md Docker 章节)。
  • 代码执行沙箱plugins/_code_execution/tools/code_execution_tool.py):code_execution_tool 支持 runtime=terminal/python/nodejs/output,多 session(session id),可 reset 杀会话,runtime=output 轮询长任务。
  • 两种 shell 后端prepare_statecode_execution_tool.py:105 附近)按 cfg["ssh_enabled"]SSHInteractiveSession(paramiko,连进 Docker 容器 shell)或 LocalInteractiveSession(本机 PTY)。_resolve_ssh_enabled 默认 not runtime.is_dockerized() —— 容器内直接用 local shell,容器外/dev 走 SSH 进容器。SSH 会话注入 export GIT_PAGER=cat; PAGER=cat 防 pager 挂死。
  • RFC(Remote Function Call,helpers/runtime.py:dev 模式下框架函数可 call_development_function 经 HTTP /api/rfc + rfc_password 转发到容器内执行,分离”UI/开发在宿主、真正执行在 Docker”。
  • 默认部署即 Docker,README 强调隔离运行;host 直跑是选项但风险自负。

与模型的协同设计

  • 多角色模型分工models.py + plugins/_model_config):chat model(主推理)/ utility model(摘要、记忆抽取、behaviour merge 等杂活,call_utility_model + background=True)/ embedding model / 可选 browser model。压缩/记忆/命名 chat 全走便宜的 utility model 省成本。
  • LiteLLM 统一封装models.py 经 LiteLLM 支持任意 provider,默认 drop_params=True 与用户 litellm_global_kwargs 合并,per-call 传入。
  • model presetsdocs/guides/model-presets.mdget_preset_by_name):一套配置切换不同模型组合。
  • 能力自适应:vision 模型才加 vision 工具提示(_11_tools_prompt.py);另有 local-model-tool-use.md 指南针对本地弱模型。
  • Responses API 专门状态管理DATA_NAME_RESPONSES_STATE/DATA_NAME_RESPONSES_TOOL_NAME_MAP/DATA_NAME_RESPONSES_COMPUTER_SESSIONagent.py:360-362),对 OpenAI Responses API 有专门状态管理(含 computer-use session),压缩时 clear_responses_provider_state
  • JSON 工具协议不依赖 native function-calling:靠 prompt 教模型输出 JSON + json_parse_dirty 容错解析,因此跨 provider/本地模型通用(牺牲一点可靠性换普适)。

轨迹利用(session/trajectory 是否反哺训练/评测)

  • 仅持久化 + 复用,不反哺训练:会话轨迹经 persist_chat 存 JSON(_serialize_context/agent/log),用于会话恢复(load_tmp_chats)、分支(_chat_branching)、时间旅行回退(_time_travel)、导出(export_json_chat)、压实前备份。
  • 轨迹→记忆是唯一”反哺”路径:monologue_end 从 history 抽 fragments/solutions 存进 FAISS 供未来对话召回(见”记忆”与”自进化”节)。这是 in-context 学习,不是参数训练。
  • 无 trajectory→训练/评测 pipeline:无 eval harness、无数据集导出给 RL/SFT、无 reward 标注(grep 确认无 finetune/rlhf/reward);orchestrator 有 tests/ 但只是插件单测。
  • 结论:轨迹利用停留在”个人 agent 的会话资产管理 + 向量记忆”,无训练闭环。

与同类 harness 的关键差异(1-3 条)

  1. “prompt 即框架”做到极致:内核几乎不硬编码行为,系统提示由 extension 链拼装、prompt 文件按 profile>plugin>root 就近覆盖,工具”文件即注册”、无中央注册表 —— 相比 Claude Code/Codex 这类把工具与流程写死在内核里的 harness,Agent Zero 把”改行为”从改代码降级为改 prompt/放文件。
  2. 自进化落在 prompt/memory 层而非权重层:可运行时写回的 behaviour.md + FAISS solutions 记忆让 agent “越用越懂你”,但明确没有 eval/RL/finetune 闭环 —— 与 SWE-agent 等强调 benchmark 驱动的路线相反。
  3. 别名 secret + 流式 mask 的密钥安全设计:LLM 全程只见 §§secret(KEY) 占位符、真实值运行时注入、StreamingSecretsFilter 连模型复述都实时打码 —— 在个人 agent 框架里是较少见的显式密钥隔离机制;但代价是工具层没有细粒度审批门,整体安全依赖 Docker 隔离与人工 intervention。

原始源码定位

  • repo: https://github.com/agent0ai/agent-zero
  • commit/version analyzed: 3bb40576affb41e0ce5180e38751e211f5f210362026-07-09 17:59:27 +0200 Improve README conversion flow
  • 关键文件列表(相对 repo 根):
    • agent.py — 核心 Agent/AgentContext/LoopData/主循环(精读 monologue@387、prepare_prompt@565、get_system_prompt@683、process_tools@1409、get_tool@1548)
    • tools/response.py — 停机工具 ResponseToolbreak_loop=True
    • tools/call_subordinate.py — 递归子 agent 派生(Delegation.execute@37)
    • plugins/_code_execution/tools/code_execution_tool.py — 代码执行/双 shell 后端
    • helpers/history.py — 分层历史压缩(常量 @15-25)
    • plugins/_chat_compaction/helpers/compactor.py — 整会话手动压实
    • plugins/_memory/helpers/memory.py — FAISS 向量记忆(MyFaiss@41、Area@56)
    • plugins/_memory/.../monologue_end/_50_memorize_fragments.py — 自动记忆抽取
    • plugins/_memory/tools/behaviour_adjustment.py — 行为规则自调整
    • extensions/python/system_prompt/_10_main_prompt.py_11_tools_prompt.py(+ _12_mcp/_13_secrets/_13_skills/_14_project)— 系统提示拼装链
    • extensions/python/message_loop_end/_10_organize_history.py — 后台压缩触发
    • extensions/python/message_loop_prompts_after/_63_recall_relevant_skills.py — skill 语义召回
    • helpers/skills.pyMAX_ACTIVE_SKILLS@21、search_skills@536)、helpers/secrets.pySecretsManager@126、StreamingSecretsFilter@39、ALIAS_PATTERN@18)、helpers/runtime.pyhelpers/log.pyhelpers/persist_chat.py
    • prompts/agent.system.main.mdagent.system.main.role.mdagent.system.secrets.md
    • AGENTS.md(Safety/Docker 章程)、plugins/_orchestrator/README.md

一手源存档(sources/)

保存在 /Users/zhao/projects/self-wiki/ai-research/sources/harness/agent-zero/

  • NOTES.md — 第一阶段源码级调研笔记(12 维度)
  • src/ 目录留档源文件:
    • agent.pyresponse.pycall_subordinate.pycode_execution_tool.pyhistory.pycompactor.pymemory.py_50_memorize_fragments.pybehaviour_adjustment.pyskills.pysecrets.pyruntime.py
    • _10_organize_history.py_11_tools_prompt.py
    • agent.system.main.mdagent.system.main.role.md
    • AGENTS.root.md(根 AGENTS.md)、orchestrator.README.md