源码级分析 · 2026-08-12

DojoAgents 主动式 Agent
源码级深度分析

深涌智能(Alpha-Dojo)开源的面向个人投资的全市场 AI Agent 框架。
完整 Clone 源码,逐文件阅读,1523 行核心引擎逐行分析。

1,523行
核心 AgentLoop
6层
主动式机制叠加
41个
Agent 引擎文件
12分钟
完成 2 小时投研工作
~100文件
源码模块

📦 一、项目概览

一句话:DojoAgents 不是"回答问题"的金融 AI,而是自主完成全链路投研的 Agent 引擎——市场扫描、财报拆解、产业链分析、风险测算,Agent 自己判断"下一步该查什么、如何验证"。
Apache 2.0
开源许可
1000+ ⭐
一周内 GitHub Stars
Python 3.11+
运行环境
LLM 无关
OpenAI / Claude / Gemini / DeepSeek / Ollama

实际源码目录结构

dojoagents/
├── agent/                    # ★ 核心 Agent 引擎 (41 个文件)
│   ├── loop.py               # ★ AgentLoop — 核心编排器 (1523行)
│   ├── runtime.py            # ★ Runtime — 全局依赖注入组装 (361行)
│   ├── harness.py            # ★ Harness 基类 — 自动验证框架
│   ├── harnesses/            # 3 个具体 Harness (portfolio/tool_orchestrated/artifact_synthesis)
│   ├── hooks/                # Agent 生命周期 Hook 系统
│   ├── guardrails.py         # 工具调用安全护栏
│   ├── compressor.py         # LLM 辅助上下文压缩
│   └── session_manager.py    # 会话持久化 (27KB)
├── tasks/                    # ★ 任务系统 — YAML 合约 + TASK.md 提示词
├── planning/                 # ★ 自动规划 — LLM 生成计划 → DAG 执行
├── multi_agent/              # ★ 多 Agent — 池化管理 + 事件驱动分发
├── cron/                     # ★ 定时调度 — APScheduler + Gateway 推送
├── memory/                   # 记忆系统 — Hook 自动同步
├── skills/                   # 技能系统 — 可复用工作流
├── plugins/                  # 插件系统 — PluginRegistry (34KB)
├── tools/                    # 工具系统 (24 个文件)
├── gateway/                  # 多通道聊天网关
├── dashboard/                # FastAPI + React 前端
└── utils/event_bus.py        # ★ 事件总线 (仅23行!) — 主动式 Agent 的神经中枢

技术栈

组件技术选型作用
Agent 运行时strands-agents + strands-agents-toolsAgent 生命周期管理、工具注册调度
工具协议mcp>=1.26.0标准化工具接入(Model Context Protocol)
LLM 接口openai>=1.20.0 兼容协议模型无关 — 支持 OpenAI / Claude / Gemini / DeepSeek / GLM / Ollama
自主调度apscheduler>=3.10.0Cron 定时任务 — 驱动后台自主推送
后端FastAPI + Uvicorn (SSE 推送)实时 Agent 状态流式推送
数据处理pandas + pyarrow多市场数据 ETL
前端React SPA (Vite)机构级仪表盘
自研 SDKdojosdk>=0.1.8Alpha-Dojo 金融数据接口

🏗 二、七层架构全景图

交互层 — 多通道入口 💻 CLI 终端 🌐 Web Dashboard 💬 Chat Gateways ⚙ ★ Agent 循环 — 核心推理引擎 任务自主拆解 Decompose 多轮工具编排 Multi-turn Tools 上下文压缩 LLM Compressor 安全护栏 Guardrails Harness 验证 Auto Self-Correction Memory 同步 Hook Auto-Sync Plan 引擎 Auto Plan & Execute Multi-Agent Orchestrator ⚡ EventBus — 事件驱动自动化 (仅23行代码!) 工具层 — 24个独立可调用工具 市场扫描 · 新闻检索 · 公司分析 · 产业链映射 · 组合构建 · 风险分析 · 代码执行 · MCP协议 · Web搜索 · 可视化 每个工具原子化、可组合、终端状态明确 — Agent 自主判断调用顺序 数据层 — 多市场数据接入 A股 · 美股 · 港股 · K线 · 财报 · 新闻 · 交易所日历 — 全部通过 dojosdk 统一接口 基础设施层 — 本地安全沙箱 Python 执行沙箱 · API 密钥本地加密 · 会话持久化 · 上下文压缩 · 令牌计费追踪 🔹 每个 Agent 实例是独立的 Strands Agent,拥有独立的上下文和状态 🔹 工具调用前/后双重 Hook 检查 (Pre-tool + Post-tool Guardrails) 🔹 最大迭代次数: 100 轮 (Limits.turns=100),防止无限循环

⚙ 三、主动式 Agent 的六大核心机制

DojoAgents 的"主动性"不是单一特性,而是由六层机制叠加而成的系统行为。

🔄
机制 1: Agent 循环 — 循环认知引擎
agent/loop.py · 1523行
Strands Agent 驱动的多轮推理循环:推理→行动→观察→再推理,直到达到目标或达到迭代上限。
✅
机制 2: Harness 系统 — 自动验证与纠错
agent/harness.py · 167行 (+ 3个实现)
Agent 产出后自动验证是否满足任务要求,不满足则自动注入引导提示并继续,最多恢复8轮。
⚡
机制 3: 事件驱动自动化
utils/event_bus.py · 仅23行!
发布/订阅模式解耦。工具失败→自动修复,大数据量→自动分析,复杂任务→自动规划。
📋
机制 4: Auto Plan — 自动规划执行
planning/automation.py · 149行
LLM 自动将复杂请求拆解为多步骤计划,DAG 依赖排序后逐步执行,并综合所有步骤生成最终回答。
👥
机制 5: Multi-Agent 自动调度
multi_agent/ · 9个文件
正则检测用户消息复杂度,自动激活多 Agent 模式(analyst / implementer / reviewer)。工具失败自动 spawn Reviewer 修复。
⏰
机制 6: Cron Scheduler — 定时自主运行
cron/ · 2个文件 · 169行
APScheduler 驱动,Agent 在后台按计划自主执行并推送到 Slack/Telegram/微信/邮件。"在你睡觉时也在工作"。

🔍 四、Agent 循环 — 核心引擎源码追踪

dojoagents/agent/loop.py 是整个系统最核心的文件,1523 行实现完整的 Agent 编排逻辑。

4.1 AgentLoop.run() 执行流程

第一步📝 构建 System Prompt
→
第二步⚙ Plan 激活检查
→
第三步🌐 建 Model Bridge
→
第四步🔧 收集+桥接工具
→
第五步🛡 设置 Hooks 链
→
第六步▶ Strands Agent.invoke()
→
STEP 7🔄 Harness Recovery Loop

4.2 关键代码:Agent 创建与执行

# loop.py:1134-1144 — 创建 Strands Agent 实例
agent = Agent(
    model=model,              # DojoStrandsModelBridge (桥接 LLM)
    messages=agent_messages,  # 历史会话
    tools=strands_tools,      # 桥接后的工具列表
    system_prompt=system,     # 动态构建的系统提示
    hooks=hooks,              # 5 个 Hook Provider
    plugins=plugins,          # 插件
    callback_handler=...,     # 流式输出回调
    agent_id=strands_agent_id,
    session_manager=strands_session_manager,
)

# loop.py:1170-1177 — 执行 Agent (多轮 Tool Calling)
result = await agent.invoke_async(
    prompt=user_prompt,
    invocation_state=invocation_state,
    limits=limits,  # Limits(turns=100) — 防止无限循环
)

4.3 关键代码:Guardrails — 多层工具护栏

# loop.py:830-995 — Before Tool Call Hook (简化版)
async def check_guardrails_before(event: BeforeToolCallEvent) -> None:
    tool_name = event.tool_use.get("name")
    args = event.tool_use.get("input") or {}

    # 1. 图片模式 → 阻止代码执行工具
    if tool_name in IMAGE_TURN_EXCLUDED_工具:
        event.cancel_tool = blocked_res["content"]

    # 2. 动态创建工具 (延迟绑定 — 支持运行时注册)
    if not event.selected_tool:
        event.selected_tool = DojoBridgedTool(...)

    # 3. execute_code 护栏 → LLM 辅助分类判断是否允许
    if tool_name in EXECUTE_CODE_TOOL_NAMES:
        classification = await classify_execute_code(code, ...)
        if blocked: event.cancel_tool = ...

    # 4. write_session_file 护栏 → LLM 判断写入安全性
    if tool_name == "write_session_file":
        classification = await classify_write_session_file(...)
        if blocked: event.cancel_tool = ...

    # 5. 通用护栏 → 规则引擎检测
    decision = self.guardrails.before_call(tool_name, args)
    if decision.should_halt:
        raise GuardrailHaltException(...)  # 彻底终止
    elif not decision.allows_execution:
        event.cancel_tool = ...  # 阻止此工具

    # 6. Harness 工具修复 → 任务模式下限制工具使用
    if active_harness:
        repaired = active_harness.repair_tool_calls(calls, state)
        blocked = active_harness.block_tool_call(call, state)

4.4 关键代码:After Hook — 事件驱动自动修复

# loop.py:1002-1045 — After Tool Call Hook (简化版)
async def check_guardrails_after(event: AfterToolCallEvent) -> None:
    # ★ 工具执行失败 → 发布事件,MultiAgentAutoDispatcher 自动修复
    if is_failed:
        failure_results = await event_bus.publish(
            "ToolExecutionFailed",
            {"tool_name": tool_name, "args": args, "error": raw_result}
        )
        if failure_results:
            event.result["content"] = [{"text": failure_results[0]}]
            # ↑ Reviewer Agent 的修复结果自动注入!

    # ★ 大数据量 (>5000字符) → 发布事件,Analyst Agent 自动分析
    if len(raw_result) > 5000:
        data_results = await event_bus.publish(
            "DataVolumeLarge",
            {"data_summary": raw_result[:2000] + "..." + raw_result[-1000:]}
        )
        if data_results:
            event.result["content"] = [{"text": data_results[0]}]
            # ↑ Analyst Agent 的洞察自动替换原始数据!

✅ 五、Harness 系统 — 自动验证与自我纠错

这是 DojoAgents 最独特的设计——Agent 不是一次性生成输出就结束,而是通过 Harness 系统持续自我验证,不满足条件就自动继续。

5.1 Harness 继承体系

TaskHarness (抽象基类)                    # agent/harness.py
├── matches(request, state) → bool        #   是否匹配当前任务
├── block_tool_call(call, state) → str    #   阻止不适合的工具调用
├── repair_tool_calls(calls, state) → []  #   修复/限制工具调用
├── validate_progress(state) → Decision   #   ★ 验证任务是否完成
└── build_recovery_prompt(dec, locale)    #   ★ 构建恢复引导

具体实现:
├── PortfolioTaskHarness        (21KB)    #   验证投资组合任务
├── ToolOrchestratedHarness              #   引导工具编排步骤
└── ArtifactSynthesisHarness             #   验证产物 Schema

5.2 核心逻辑:Harness Recovery Loop

# loop.py:1280-1330 — 自动验证与纠错循环
harness_recovery_turns = 0
while True:  # ★ 自动循环直到任务完成或达到上限!
    decision = active_harness.validate_progress(harness_state)
    if decision.complete:
        break  # 任务完成,退出循环

    # 构建恢复提示 (中英文双语)
    recovery_prompt = active_harness.build_recovery_prompt(decision, locale)

    # 达到上限 → 输出当前状态并停止
    if harness_recovery_turns >= max_recovery_turns:
        response_text = recovery_prompt
        break

    harness_recovery_turns += 1
    # ★ 自动重新调用 Agent,注入引导提示!
    result = await agent.invoke_async(
        prompt=recovery_prompt,
        invocation_state=invocation_state,
        limits=limits,
    )

5.3 ToolOrchestratedHarness — 步骤引导示例

# harnesses/tool_orchestrated.py:62-96
def validate_progress(self, state) -> HarnessDecision:
    # 1. 检查输出 Schema 验证 — 如果合法则完成
    filename, issues = self._output_write_issues(state)
    if filename and not issues:
        return HarnessDecision(complete=True)

    # 2. 引导下一步操作
    if not state.tool_results:
        issues.append("Start with get_market_overview.")
    elif not has_tool(state, "get_sector_movers"):
        issues.append("Call get_sector_movers before web_search.")
    elif not has_tool(state, "write_session_file"):
        issues.append("Finish by writing output with write_session_file.")

    # 3. 返回决策 — 允许继续但指定下一步
    return HarnessDecision(
        complete=False,
        issues=issues,
        next_steps=issues[:1],
        allow_extra_steps=True,  # ★ 关键: 允许继续
    )

⚡ 六、事件驱动自动化 — 23行的神经中枢

dojoagents/utils/event_bus.py 仅 23 行代码,却驱动了整个自主响应体系。

6.1 事件总线源码

# utils/event_bus.py — 仅 23 行!
class EventBus:
    def __init__(self):
        self._subscribers: dict[str, list[Callable]] = {}

    def subscribe(self, event_type: str, handler: Callable) -> None:
        self._subscribers.setdefault(event_type, []).append(handler)

    async def publish(self, event_type: str, payload: dict) -> list[Any]:
        results = []
        for handler in self._subscribers.get(event_type, []):
            res = await handler(payload)
            if res is not None:
                results.append(res)
        return results

event_bus = EventBus()  # 全局单例

6.2 事件流全景

PlanActivationHook 检测复杂度 AgentLoop.after_hook 工具执行后检查 AgentLoop.after_hook 数据量检查 TaskComplexityHigh ToolExecutionFailed DataVolumeLarge AutoPlanManager generate_plan → execute → synthesize MultiAgentAutoDispatcher spawn Reviewer → auto-fix MultiAgentAutoDispatcher spawn Analyst → auto-analyze AgentPool orchestrator analyst implementer reviewer 懒加载创建 工具过滤克隆

🌊 七、完整数据流追踪

以下追踪一个典型主动式请求 "分析今天A股半导体板块" 经过的完整路径:

1. 用户输入 → ChatRequest session_id, message, channel 2. TaskActivator 关键词激活 匹配 → 注入 TASK.md 上下文 3. PlanActivationHook 检测 长消息 → 自动计划生成 ★ AgentLoop.run() 4a. 构建 System Prompt temporal + skills + memory + task 4b. 上下文压缩检查 threshold > 80% → LLM 辅助压缩 4c. 创建 Strands Agent model + tools + hooks + plugins ★ agent.invoke_async() 多轮 Tool Calling 循环 多轮 Tool Calling 详析 Turn 1: get_market_overview → Pre-hook 检查 → 执行 → Post-hook Turn 2: get_sector_movers → 失败? → EventBus → 自动修复! Turn 3: web_search("半导体") → 大量数据? → Analyst 自动分析 Turn 4: write_session_file → Pre-hook LLM 判断安全 → 执行 Empty Assistant? → 自动恢复 (empty_recovery) Harness Recovery Loop: 自动验证 → 不通过 → 自动重试 → ... → 通过! 5. Memory Hook 自动同步 sync_turn → providers 6. Plugin 后处理 post_llm_call → transform 7. 返回 AgentResponse content + metadata → 用户

⚖ 八、主动式 vs 被动式 — 技术对比

维度传统被动式 AgentDojoAgents 主动式
执行模式单次 LLM推理 → 输出✔ 多轮 推理→工具→观察→再推理 循环
完成标准模型说"完成了"✔ Harness 系统客观验证(Schema校验、数据检查)
纠错能力用户手动纠正✔ 自动检测 + 事件总线触发修复 Agent
工具调用单次或少量调用✔ 多步骤编排,每步受 Pre/Post Hook 检查
时间维度同步即时响应✔ 同步 + Cron 定时后台自主运行
复杂度适应固定流程✔ 自动检测 → LLM 生成计划 → DAG 执行
多 Agent单 Agent✔ 正则检测 + 事件触发 = 按需激活
记忆单次会话✔ 跨会话 Memory + Skill 蒸馏
质量保证依赖 Prompt✔ 护栏 + 验证 + 自动修复 + 恢复循环
上下文固定窗口✔ 动态 LLM 压缩 + 溢出自动重试

💡 九、构建主动式 Agent 的六大洞察

🔄
1. 循环 > 单次
主动式 Agent 的核心不是更聪明的模型,而是让模型进入一个持续运行的循环:推理→行动→观察→再推理。
🔧
2. 工具粒度 = 自主程度
工具越原子化,Agent 的自由度越高。每个工具应:原子化、可组合、终端状态明确。
⏰
3. 调度器 = 时间维度的主动性
apscheduler 让 Agent 有了时间感知能力——不是被提问时才工作,而是按自己的节奏持续运行。
🛡
4. 护栏 = 自主性的边界
三层防护:预防层(幻觉护栏) → 控制层(中断机制) → 终止层(循环防护)。
🧠
5. 自进化 = 长期价值
Memory + SKILL 蒸馏让 Agent 能力随使用时间增长——每次成功分析都变成可复用资产。
⚡
6. 事件解耦 = 系统可演化性
23行事件总线驱动整个自主响应体系。每个组件独立演化,通过事件松散耦合。