yao/agent/autonomous/DESIGN.md
Max 46d815affc Refactor Autonomous Agent Design Document for Improved Clarity and Structure
- Revised the document to enhance clarity by updating section titles and terminology, such as changing "Overview" to "What is it?" and "Key Characteristics" to "Key points."
- Streamlined the architecture section, renaming components for consistency and clarity, including changes to trigger sources and agent management terminology.
- Updated execution flow diagrams and descriptions to reflect the new structure, improving understanding of the agent's operational phases.
- Enhanced the configuration section to provide a clearer overview of triggers, scheduling, and resource management, ensuring better organization throughout the document.
2026-01-13 08:58:19 +08:00

20 KiB

Autonomous Agent

1. What is it?

An Autonomous Agent is an AI team member. It works on its own, makes decisions, and runs tasks without waiting for user input.

Key points:

  • Belongs to a Team, managed like human members
  • Has clear job duties (e.g., "Sales Manager: track KPIs, make reports")
  • Created and deleted via Team API
  • Runs on schedule, or when triggered by humans or events
  • Learns from each run, stores knowledge in private KB

2. Architecture

2.1 System Flow

flowchart TB
    subgraph Triggers["Triggers"]
        WC[/"⏰ Schedule"/]
        HI[/"👤 Human"/]
        EV[/"📡 Event"/]
    end

    subgraph Manager["Manager"]
        TC{"Enabled?"}
        Cache[("Cache")]
        Dedup{"Dedup?"}
        Queue["Queue"]
    end

    subgraph Pool["Workers"]
        W1["Worker"]
        W2["Worker"]
        W3["Worker"]
    end

    subgraph Executor["Executor"]
        P0["P0: Inspiration"]
        P1["P1: Goals"]
        P2["P2: Tasks"]
        P3["P3: Run"]
        P4["P4: Deliver"]
        P5["P5: Learn"]
    end

    subgraph Storage["Storage"]
        KB[("KB")]
        DB[("DB")]
        Job[("Job")]
    end

    WC & HI & EV --> TC
    TC -->|Yes| Cache
    TC -->|No| X[/Skip/]
    Cache --> Dedup
    Dedup -->|OK| Queue
    Dedup -->|Dup| Cache
    Queue --> W1 & W2 & W3
    W1 & W2 & W3 --> P0
    P0 --> P1 --> P2 --> P3 --> P4 --> P5
    P5 --> KB & DB & Job
    KB -.->|History| P0

2.2 Team Structure

AI members live in team_members table with member_type = "ai":

┌─────────────────────────────────────────────────────────────────┐
│                            Team                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                    AI Members                            │    │
│  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐        │    │
│  │  │Sales Manager│ │Data Analyst │ │CS Specialist│        │    │
│  │  │ • Track KPIs│ │ • Analyze   │ │ • Tickets   │        │    │
│  │  │ • Reports   │ │ • Reports   │ │ • Inquiries │        │    │
│  │  └─────────────┘ └─────────────┘ └─────────────┘        │    │
│  └─────────────────────────────────────────────────────────┘    │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                   Human Members                          │    │
│  │  ┌─────────────┐ ┌─────────────┐                        │    │
│  │  │ John (Owner)│ │ Jane (Admin)│                        │    │
│  │  └─────────────┘ └─────────────┘                        │    │
│  └─────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘
CREATE TABLE team_members (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    team_id VARCHAR(64) NOT NULL,
    user_id VARCHAR(64),              -- for humans
    member_type VARCHAR(32) NOT NULL, -- "user" | "ai"
    agent_id VARCHAR(64),             -- for AI only
    agent_config JSON,                -- AI config
    status VARCHAR(32) DEFAULT 'active',
    INDEX idx_team_id (team_id),
    INDEX idx_agent_id (agent_id)
);

3. How It Works

3.1 Flow: Trigger → Schedule → Run

sequenceDiagram
    autonumber
    participant T as Trigger
    participant M as Manager
    participant S as Scheduler
    participant W as Worker
    participant E as Executor
    participant A as Phase Agents
    participant KB as KB

    T->>M: Event
    M->>M: Check enabled
    M->>M: Get from cache
    M->>M: Check dedup
    M->>S: Submit

    S->>S: Check quota
    S->>S: Sort by priority
    S->>W: Dispatch

    W->>E: Run

    loop P0 to P5
        E->>A: Call agent
        A-->>E: Result
    end

    E->>KB: Save learning
    E-->>W: Done

3.2 Triggers

Type What Config
Schedule Timer (cron or interval) triggers.schedule
Human Manual action triggers.intervene
Event Webhook, DB change triggers.event

All on by default. Turn off per agent:

triggers:
  schedule: { enabled: true }
  intervene: { enabled: true, actions: ["add_task", "pause"] }
  event: { enabled: false }

3.3 Concurrency

Two levels to prevent one agent from using all resources:

┌─────────────────────────────────────────────────────────────────┐
│                    Global Pool (10 workers)                      │
└─────────────────────────────────────────────────────────────────┘
          │                   │                   │
          ▼                   ▼                   ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Sales Manager   │ │ Data Analyst    │ │ CS Specialist   │
│ Limit: 3        │ │ Limit: 2        │ │ Limit: 3        │
│ Now: 2 ✓        │ │ Now: 2 (full)   │ │ Now: 1 ✓        │
└─────────────────┘ └─────────────────┘ └─────────────────┘

3.4 Dedup

Fast check (in memory):

key := agentID + ":" + triggerType + ":" + window
if has(key) { skip }

Smart check (for goals/tasks):

  • Dedup Agent looks at history
  • Returns: skip | merge | proceed

3.5 Cache

Keeps agents in memory. No DB query on each tick:

type AgentCache struct {
    agents map[string]*Agent   // agent_id -> agent
    byTeam map[string][]string // team_id -> agent_ids
}
// Refresh: on start, on change, every hour

4. Phases

4.1 Overview

P0: Inspiration → P1: Goals → P2: Tasks → P3: Run → P4: Deliver → P5: Learn
Phase Agent In Out
P0 Inspiration Data, news, time Report
P1 Goal Gen Report + history Goals
P2 Task Plan Goals + tools Tasks
P3 Validator Results Checked results
P4 Delivery All results Email/File
P5 Learning Summary KB entries

4.2 P0: Inspiration

Gathers info to help make good goals:

type InspirationReport struct {
    Summary       string         // What's happening
    Highlights    []Highlight    // Key changes
    Opportunities []Opportunity  // Chances to act
    Risks         []Risk         // Things to watch
    WorldInsights []WorldInsight // News from outside
    Suggestions   []string       // What to focus on
}

Sources:

  • Internal: Data changes, events, feedback, pending work
  • External: Web search (news, competitors)
  • Time: Day of week, deadlines

4.3 P1: Goals

Uses inspiration to make goals:

Prompt:
You are [Sales Manager]. Your job: [track KPIs, make reports].

## Report
### Key Items
- [High] Data: 15 new sales (+50%)
- [High] Deadline: Friday report due
- [High] News: Competitor launched product

### Chances
- Sales up 20% vs last week
- Market growing

Make today's goals.

4.4 P2: Tasks

Breaks goals into steps:

type Task struct {
    ID           string
    GoalID       string
    Description  string
    ExecutorType string // "assistant" | "mcp"
    ExecutorID   string
}

4.5 P3: Run

For each task:

  1. Call Assistant or MCP Tool
  2. Get result
  3. Validate
  4. Update status

4.6 P4: Deliver

Send output:

delivery:
  type: email # email | file | webhook | notify
  opts:
    to: ["manager@company.com"]

4.7 P5: Learn

Save to KB:

Type Examples
execution What worked, what failed
feedback Errors, fixes
insight Patterns, tips

5. Config

5.1 Structure

type Config struct {
    Triggers  *Triggers  `json:"triggers,omitempty"`
    Schedule  *Schedule  `json:"schedule,omitempty"`
    Identity  *Identity  `json:"identity"`
    Quota     *Quota     `json:"quota"`
    PrivateKB *KB        `json:"private_kb"`
    SharedKB  *KB        `json:"shared_kb,omitempty"`
    Resources *Resources `json:"resources"`
    Delivery  *Delivery  `json:"delivery"`
    Input     *Input     `json:"input,omitempty"`
    Events    []Event    `json:"events,omitempty"`
    Monitor   *Monitor   `json:"monitor,omitempty"`
}

5.2 Types

// Triggers - all on by default
type Triggers struct {
    Schedule  *Trigger `json:"schedule,omitempty"`
    Intervene *Trigger `json:"intervene,omitempty"`
    Event     *Trigger `json:"event,omitempty"`
}

type Trigger struct {
    Enabled bool     `json:"enabled"`
    Actions []string `json:"actions,omitempty"` // for intervene
}

// Schedule
type Schedule struct {
    Type    string `json:"type"`    // cron | interval
    Expr    string `json:"expr"`    // "0 9 * * 1-5" or "1h"
    TZ      string `json:"tz"`
    Timeout string `json:"timeout"`
}

// Identity
type Identity struct {
    Role   string   `json:"role"`
    Duties []string `json:"duties"`
    Rules  []string `json:"rules"`
}

// Quota
type Quota struct {
    Max      int `json:"max"`      // max running (default: 2)
    Queue    int `json:"queue"`    // queue size (default: 10)
    Priority int `json:"priority"` // 1-10 (default: 5)
}

// KB
type KB struct {
    ID    string   `json:"id,omitempty"`
    Refs  []string `json:"refs,omitempty"`
    Learn *Learn   `json:"learn,omitempty"`
}

type Learn struct {
    On    bool     `json:"on"`
    Types []string `json:"types"` // execution, feedback, insight
    Keep  int      `json:"keep"`  // days, 0 = forever
}

// Resources
type Resources struct {
    P0     string   `json:"p0"` // Inspiration
    P1     string   `json:"p1"` // Goal Gen
    P2     string   `json:"p2"` // Task Plan
    P3     string   `json:"p3"` // Validator
    P4     string   `json:"p4"` // Delivery
    P5     string   `json:"p5"` // Learning
    Agents []string `json:"agents"`
    MCP    []MCP    `json:"mcp"`
}

type MCP struct {
    ID    string   `json:"id"`
    Tools []string `json:"tools,omitempty"` // empty = all
}

// Delivery
type Delivery struct {
    Type string                 `json:"type"` // email | file | webhook | notify
    Opts map[string]interface{} `json:"opts"`
}

// Monitor
type Monitor struct {
    On     bool    `json:"on"`
    Alerts []Alert `json:"alerts,omitempty"`
}

type Alert struct {
    Name     string   `json:"name"`
    When     string   `json:"when"`  // failed | timeout | error_rate
    Value    float64  `json:"value"`
    Window   string   `json:"window"` // 1h | 24h
    Do       []Action `json:"do"`
    Cooldown string   `json:"cooldown"`
}

type Action struct {
    Type string                 `json:"type"` // email | webhook | notify
    Opts map[string]interface{} `json:"opts"`
}

5.3 Example

{
  "member_type": "ai",
  "agent_id": "sales-bot",
  "agent_config": {
    "triggers": {
      "schedule": { "enabled": true },
      "intervene": { "enabled": true },
      "event": { "enabled": false }
    },
    "schedule": {
      "type": "cron",
      "expr": "0 9 * * 1-5",
      "tz": "Asia/Shanghai",
      "timeout": "30m"
    },
    "identity": {
      "role": "Sales Analyst",
      "duties": ["Analyze sales", "Make weekly reports"],
      "rules": ["Only access sales data"]
    },
    "quota": { "max": 2, "queue": 10, "priority": 5 },
    "private_kb": {
      "learn": {
        "on": true,
        "types": ["execution", "feedback", "insight"],
        "keep": 90
      }
    },
    "shared_kb": { "refs": ["sales-policies", "products"] },
    "resources": {
      "p0": "__yao.inspiration",
      "p1": "__yao.goal-gen",
      "p2": "__yao.task-plan",
      "p3": "__yao.validator",
      "p4": "__yao.delivery",
      "p5": "__yao.learning",
      "agents": ["data-analyst", "chart-gen"],
      "mcp": [{ "id": "database", "tools": ["query"] }]
    },
    "delivery": {
      "type": "email",
      "opts": { "to": ["manager@company.com"] }
    }
  }
}

6. Lifecycle

6.1 States

┌─────────┐  POST create   ┌─────────┐
│  None   │ ─────────────▶ │ Active  │◀─────┐
└─────────┘                └────┬────┘      │
                                │           │
                    PATCH pause │    PATCH resume
                                ▼           │
                           ┌─────────┐      │
                           │ Paused  │──────┘
                           └────┬────┘
                                │
                         DELETE │
                                ▼
                           ┌─────────┐
                           │ Deleted │
                           └─────────┘

6.2 Transitions

From To How
- active POST create
active paused PATCH status="paused"
paused active PATCH status="active"
any deleted DELETE

6.3 On Create

  1. Check config
  2. Make agent_id if missing
  3. Create KB: agent_{team_id}_{agent_id}_kb
  4. Add to cache
  5. Create Job
  6. Set active

6.4 Running

┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│   Idle   │────▶│ Triggered│────▶│ Running  │────▶│ Learning │
│          │◀────│          │     │ (P0-P4)  │     │  (P5)    │
└──────────┘     └──────────┘     └──────────┘     └────┬─────┘
      ▲                                                  │
      └──────────────────────────────────────────────────┘

6.5 On Delete

  1. Stop running jobs
  2. Remove from cache
  3. Delete Job
  4. Delete or archive KB
  5. Soft delete record

7. Integrations

7.1 Job System

Each agent = 1 Job. Each run = 1 Execution.

┌─────────────────────────────────────────────────────────────────┐
│                    Activity Monitor (UI)                         │
│  • List jobs                                                     │
│  • See progress                                                  │
│  • View logs                                                     │
│  • Cancel/retry                                                  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      Job Framework                               │
│  Job → Execution → Progress → Logs                               │
└─────────────────────────────────────────────────────────────────┘

APIs:

Action API
List GET /api/jobs?category_id=autonomous_agent
History GET /api/jobs/:job_id/executions
Progress GET /api/jobs/:job_id/executions/:id
Logs GET /api/jobs/:job_id/executions/:id/logs
Cancel POST /api/jobs/:job_id/stop
Trigger POST /api/jobs/:job_id/trigger

7.2 Private KB

Made on agent create: agent_{team_id}_{agent_id}_kb

What it stores:

  • execution: What worked, what failed
  • feedback: Errors, fixes
  • insight: Patterns, tips

When:

  • Create: On agent create
  • Update: After P5
  • Clean: Based on keep days
  • Delete: On agent delete

7.3 External Input

Types:

  • schedule: Timer
  • intervene: Human action
  • event: Webhook, DB change
  • callback: Async result

Human actions:

  • adjust_goal: Change goal
  • add_task: Add task
  • cancel_task: Stop task
  • pause / resume / abort
  • plan: Do later

Plan Queue:

  • Holds tasks for later
  • Runs at next cycle start

8. API

8.1 Manager

type Manager interface {
    Start() error
    Stop() error
    LoadActiveAgents(ctx context.Context) ([]*Agent, error)
    ShouldExecute(agent *Agent, now time.Time) bool
    Execute(ctx context.Context, agent *Agent) (*State, error)
    Trigger(ctx context.Context, teamID, agentID string) (*State, error)
    GetHistory(ctx context.Context, teamID, agentID string, limit int) ([]*State, error)
}

8.2 State

type State struct {
    ID        string
    TeamID    string
    AgentID   string
    StartTime time.Time
    EndTime   *time.Time
    Status    Status // pending | running | completed | failed
    Phase     Phase  // inspiration | goal_gen | task_plan | run | deliver | learn
    Goals     []Goal
    Tasks     []Task
    Error     string
    Result    interface{}
}

8.3 Database

CREATE TABLE autonomous_executions (
    id VARCHAR(64) PRIMARY KEY,
    team_id VARCHAR(64) NOT NULL,
    agent_id VARCHAR(64) NOT NULL,
    start_time DATETIME NOT NULL,
    end_time DATETIME,
    status VARCHAR(32) NOT NULL,
    phase VARCHAR(32),
    goals JSON,
    tasks JSON,
    error TEXT,
    result JSON,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_team_agent (team_id, agent_id),
    INDEX idx_status (status)
);

9. Security

  1. Team only: Agent sees only its team's data
  2. Role rules: Uses role_id permissions
  3. Limited tools: Only what's in resources
  4. Timeout: Stops if runs too long
  5. Logs: All runs saved

10. Quick Ref

Triggers

triggers:
  schedule: { enabled: true }
  intervene: { enabled: true, actions: [...] }
  event: { enabled: false }

Phase Agents

resources:
  p0: "__yao.inspiration"
  p1: "__yao.goal-gen"
  p2: "__yao.task-plan"
  p3: "__yao.validator"
  p4: "__yao.delivery"
  p5: "__yao.learning"

Quota

quota:
  max: 2 # max running
  queue: 10 # queue size
  priority: 5 # 1-10

Schedule

schedule:
  type: cron
  expr: "0 9 * * 1-5"
  tz: Asia/Shanghai
  timeout: 30m