design.md 8.8 KB

Reson Agent 设计文档

设计目标:可扩展、可学习的 Agent 框架,支持执行追踪和持久记忆。


1. 核心洞察

单次调用是 Agent 的特例

特性 单次调用 Agent 模式
循环次数 1 N (可配置)
工具调用 可选 常用
状态管理 有 (Task State)
记忆检索 有 (Experience/Skill)
执行图 1 个节点 N 个节点的 DAG

统一抽象:用同一套数据结构描述两者。


2. 三层记忆模型

┌─────────────────────────────────────────────────────────────┐
│ Layer 3: Skills(技能库)                                     │
│ - 从 Experience 归纳的高层策略                                │
│ - 层次化组织,按领域/任务类型分类                              │
│ - 执行前注入到 System Prompt                                 │
└─────────────────────────────────────────────────────────────┘
                              ▲
                              │ 归纳
┌─────────────────────────────────────────────────────────────┐
│ Layer 2: Experience(经验库)                                 │
│ - 条件 + 规则 + 证据                                         │
│ - 来源:执行反馈、人工标注                                    │
│ - 持久存储,跨任务复用                                        │
└─────────────────────────────────────────────────────────────┘
                              ▲
                              │ 提取
┌─────────────────────────────────────────────────────────────┐
│ Layer 1: Task State(任务状态)                               │
│ - 当前任务的工作记忆                                          │
│ - 计划、进度、中间结论                                        │
│ - 任务结束时重置                                              │
└─────────────────────────────────────────────────────────────┘

3. 执行图(Execution Graph)

每次任务执行产生一张 DAG:

TaskNode(任务根节点)
    │
    ├─▶ LLMCallNode(第1次推理)
    │       │
    │       ├─▶ ToolCallNode(搜索工具)
    │       │       │
    │       │       └─▶ ToolResultNode(搜索结果)
    │       │
    │       └─▶ ConclusionNode(中间结论)
    │
    ├─▶ LLMCallNode(第2次推理)
    │       │
    │       └─▶ ConclusionNode(最终结论)
    │
    └─▶ FeedbackNode(人工反馈)
            │
            └─▶ ExperienceNode(提取的经验)

节点类型

类型 说明 数据
llm_call LLM 调用 messages, response, model, tokens, cost
tool_call 工具调用 tool_name, arguments
tool_result 工具结果 result, duration_ms
conclusion 中间/最终结论 content, is_final
feedback 人工反馈 feedback_type, content, target_step_id
memory_read 读取记忆 skills, experiences
memory_write 写入记忆 experience_id

4. 数据模型

4.1 Trace(执行轨迹)

@dataclass
class Trace:
    trace_id: str
    mode: Literal["call", "agent"]
    prompt_name: Optional[str] = None

    # Agent 模式特有
    task: Optional[str] = None
    agent_type: Optional[str] = None

    # 状态
    status: Literal["running", "completed", "failed"] = "running"

    # 统计
    total_steps: int = 0
    total_tokens: int = 0
    total_cost: float = 0.0

    # 上下文
    uid: Optional[str] = None
    context: Dict[str, Any] = field(default_factory=dict)

    # 时间
    created_at: datetime
    completed_at: Optional[datetime] = None

4.2 Step(执行步骤)

@dataclass
class Step:
    step_id: str
    trace_id: str
    step_type: StepType
    sequence: int

    # DAG 结构
    parent_ids: List[str] = field(default_factory=list)

    # 类型相关数据
    data: Dict[str, Any] = field(default_factory=dict)

    created_at: datetime

4.3 Experience(经验)

@dataclass
class Experience:
    exp_id: str
    scope: str  # "agent:{type}" 或 "user:{uid}"

    # 核心三元组
    condition: str
    rule: str
    evidence: List[str]  # step_ids

    # 元数据
    source: Literal["execution", "feedback", "manual"]
    confidence: float = 0.5
    usage_count: int = 0
    success_rate: float = 0.0

    created_at: datetime
    updated_at: datetime

4.4 Skill(技能)

@dataclass
class Skill:
    skill_id: str
    scope: str

    name: str
    description: str
    category: str

    # 层次结构
    parent_id: Optional[str] = None

    # 内容
    guidelines: List[str]
    derived_from: List[str]  # experience_ids

    version: int = 1
    created_at: datetime
    updated_at: datetime

5. 存储抽象

Protocol 定义

class TraceStore(Protocol):
    async def create_trace(self, trace: Trace) -> str: ...
    async def get_trace(self, trace_id: str) -> Optional[Trace]: ...
    async def update_trace(self, trace_id: str, **updates) -> None: ...
    async def add_step(self, step: Step) -> str: ...
    async def get_trace_steps(self, trace_id: str) -> List[Step]: ...

class MemoryStore(Protocol):
    async def add_experience(self, exp: Experience) -> str: ...
    async def search_experiences(self, scope: str, context: str, limit: int) -> List[Experience]: ...
    async def add_skill(self, skill: Skill) -> str: ...
    async def search_skills(self, scope: str, context: str, limit: int) -> List[Skill]: ...

6. 事件系统

@dataclass
class AgentEvent:
    type: Literal[
        "trace_started",
        "memory_loaded",
        "step_started",
        "llm_delta",
        "tool_executing",
        "tool_result",
        "conclusion",
        "feedback_received",
        "experience_extracted",
        "trace_completed",
        "trace_failed"
    ]
    data: Dict[str, Any]

7. 与 LLM 提供商的集成

Agent 模块不绑定特定 LLM 提供商。通过 LLMProvider Protocol 抽象:

class LLMProvider(Protocol):
    async def chat(
        self,
        messages: List[Dict],
        model: str,
        tools: Optional[List[Dict]] = None,
        **kwargs
    ) -> AsyncIterator[LLMEvent]: ...

宿主项目实现具体的 Provider(OpenAI、Anthropic、Azure 等)。


8. 模块结构

reson_agent/
├── __init__.py
├── runner.py              # AgentRunner
├── events.py              # AgentEvent
├── models/
│   ├── __init__.py
│   ├── trace.py           # Trace, Step
│   └── memory.py          # Experience, Skill
├── storage/
│   ├── __init__.py
│   ├── protocols.py       # TraceStore, MemoryStore
│   └── memory_impl.py     # 内存实现
└── tools/
    ├── __init__.py
    ├── registry.py        # ToolRegistry, @tool
    └── schema.py          # SchemaGenerator

9. 设计决策

为什么 Trace/Step 而不是复用 llm_call_history?

  • llm_call_history 是扁平的调用日志
  • Trace/Step 是带因果关系的执行图
  • Step 支持多种类型(llm_call, tool_call, conclusion, feedback)
  • Step 之间可以形成 DAG(不只是链表)

为什么存储可插拔?

  • 不同项目有不同的存储需求(PostgreSQL、Neo4j、MongoDB)
  • MVP 阶段用内存实现,快速验证
  • 生产环境再接入持久化存储

为什么工具系统要独立?

  • 工具注册和 Schema 生成是通用能力
  • 可以在没有 Agent 的场景单独使用
  • 与 LLM Provider 解耦

10. 后续计划

Phase 1(当前):MVP

  • 数据模型
  • 存储接口 + 内存实现
  • 工具系统
  • AgentRunner 基础循环
  • 测试

Phase 2:完善

  • Experience 提取
  • Skill 归纳
  • PostgreSQL 存储实现
  • 与 Resonote 集成

Phase 3:重构 LLM 模块

  • 将验证过的设计合并回 Resonote/llm
  • 统一 call/stream/run