Skip to content

Latest commit

 

History

History
513 lines (401 loc) · 14.3 KB

File metadata and controls

513 lines (401 loc) · 14.3 KB
layout default
title Chapter 3: Task Planning & Goal Setting
parent AgentGPT Tutorial
nav_order 3

Chapter 3: Task Planning & Goal Setting

Welcome to Chapter 3: Task Planning & Goal Setting. In this part of AgentGPT Tutorial: Building Autonomous AI Agents, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.

This chapter covers how AgentGPT agents plan and execute complex tasks by breaking them down into manageable steps and setting achievable goals.

🎯 Goal Setting Fundamentals

Goal Decomposition

// Break complex goals into manageable tasks
class GoalDecomposer {
  async decompose(goal: string): Promise<Task[]> {
    const analysis = await this.analyzeGoal(goal)
    const subtasks = await this.createSubtasks(analysis)
    const dependencies = await this.identifyDependencies(subtasks)

    return this.optimizeTaskOrder(subtasks, dependencies)
  }

  private async analyzeGoal(goal: string) {
    // Analyze goal complexity and requirements
    return {
      complexity: this.assessComplexity(goal),
      requirements: await this.extractRequirements(goal),
      constraints: this.identifyConstraints(goal)
    }
  }
}

SMART Goal Framework

// Implement SMART goals for agents
interface SmartGoal {
  specific: string      // Clear and specific objective
  measurable: string    // Quantifiable criteria
  achievable: string    // Realistic and attainable
  relevant: string      // Aligned with overall objectives
  timeBound: string     // Time constraints and deadlines
}

const smartGoalExample: SmartGoal = {
  specific: "Research and summarize the latest developments in quantum computing",
  measurable: "Produce a 1000-word summary with 5 key findings",
  achievable: "Using available research tools and 2 hours of research time",
  relevant: "Supports the team's technology roadmap planning",
  timeBound: "Complete within 24 hours"
}

📋 Task Planning Strategies

Hierarchical Task Planning

// Hierarchical planning approach
class HierarchicalPlanner {
  async createPlan(goal: string): Promise<TaskPlan> {
    const mainTask = await this.createMainTask(goal)
    const subtasks = await this.decomposeTask(mainTask)
    const schedule = await this.createSchedule(subtasks)

    return {
      goal,
      mainTask,
      subtasks,
      schedule,
      estimatedDuration: this.calculateDuration(subtasks)
    }
  }

  private async decomposeTask(task: Task): Promise<Task[]> {
    if (task.complexity < 3) {
      return [task] // Simple task, no decomposition needed
    }

    const subtasks = []
    const decomposition = await this.generateDecomposition(task)

    for (const subtask of decomposition) {
      subtasks.push(...await this.decomposeTask(subtask))
    }

    return subtasks
  }
}

Dependency Management

// Manage task dependencies
class DependencyManager {
  private dependencies: Map<string, string[]> = new Map()

  addDependency(taskId: string, dependsOn: string[]) {
    this.dependencies.set(taskId, dependsOn)
  }

  getExecutionOrder(tasks: Task[]): Task[] {
    const visited = new Set<string>()
    const order: Task[] = []

    const visit = (task: Task) => {
      if (visited.has(task.id)) return

      // Visit dependencies first
      const deps = this.dependencies.get(task.id) || []
      for (const depId of deps) {
        const depTask = tasks.find(t => t.id === depId)
        if (depTask) visit(depTask)
      }

      visited.add(task.id)
      order.push(task)
    }

    tasks.forEach(visit)
    return order
  }
}

🧠 Planning Algorithms

A* Planning Algorithm

// A* algorithm for optimal planning
class AStarPlanner {
  async findOptimalPlan(start: State, goal: State): Promise<Action[]> {
    const openSet = new PriorityQueue()
    const cameFrom = new Map()
    const gScore = new Map()
    const fScore = new Map()

    openSet.add(start, 0)
    gScore.set(start.id, 0)
    fScore.set(start.id, this.heuristic(start, goal))

    while (!openSet.isEmpty()) {
      const current = openSet.poll()

      if (this.isGoal(current, goal)) {
        return this.reconstructPath(cameFrom, current)
      }

      for (const neighbor of this.getNeighbors(current)) {
        const tentativeGScore = gScore.get(current.id) + this.getCost(current, neighbor)

        if (tentativeGScore < (gScore.get(neighbor.id) || Infinity)) {
          cameFrom.set(neighbor.id, current)
          gScore.set(neighbor.id, tentativeGScore)
          fScore.set(neighbor.id, tentativeGScore + this.heuristic(neighbor, goal))

          if (!openSet.contains(neighbor)) {
            openSet.add(neighbor, fScore.get(neighbor.id))
          }
        }
      }
    }

    throw new Error('No path found')
  }

  private heuristic(state: State, goal: State): number {
    // Estimate cost from state to goal
    return this.calculateDistance(state, goal)
  }
}

Monte Carlo Tree Search

// Monte Carlo Tree Search for planning
class MCTSPlanner {
  private root: MCTSNode

  async search(initialState: State, iterations: number = 1000): Promise<Action[]> {
    this.root = new MCTSNode(initialState)

    for (let i = 0; i < iterations; i++) {
      const node = this.select(this.root)
      const result = await this.simulate(node)
      this.backpropagate(node, result)
    }

    return this.getBestPath(this.root)
  }

  private select(node: MCTSNode): MCTSNode {
    while (!node.isLeaf()) {
      if (!node.isFullyExpanded()) {
        return this.expand(node)
      }
      node = this.bestChild(node)
    }
    return node
  }

  private async simulate(node: MCTSNode): Promise<number> {
    let state = node.state
    let depth = 0

    while (!this.isTerminal(state) && depth < this.maxDepth) {
      const action = this.randomAction(state)
      state = this.applyAction(state, action)
      depth++
    }

    return this.evaluateState(state)
  }
}

📊 Task Execution Monitoring

Progress Tracking

// Track task execution progress
class TaskMonitor {
  private tasks = new Map<string, TaskProgress>()

  startTask(taskId: string, task: Task) {
    this.tasks.set(taskId, {
      id: taskId,
      name: task.name,
      status: 'running',
      progress: 0,
      startTime: Date.now(),
      subtasks: task.subtasks?.map(st => ({ ...st, status: 'pending' }))
    })
  }

  updateProgress(taskId: string, progress: number, status?: string) {
    const task = this.tasks.get(taskId)
    if (task) {
      task.progress = progress
      if (status) task.status = status
    }
  }

  getProgress(taskId: string): TaskProgress | undefined {
    return this.tasks.get(taskId)
  }

  getAllProgress(): TaskProgress[] {
    return Array.from(this.tasks.values())
  }
}

Performance Metrics

// Track planning and execution performance
const performanceMetrics = {
  planning: {
    averageTime: 0,
    successRate: 0,
    planQuality: 0
  },

  execution: {
    averageTime: 0,
    successRate: 0,
    taskCompletion: 0
  },

  updatePlanningMetrics(planTime: number, success: boolean, quality: number) {
    this.planning.averageTime = (this.planning.averageTime + planTime) / 2
    this.planning.successRate = success ?
      (this.planning.successRate + 1) / 2 :
      this.planning.successRate / 2
    this.planning.planQuality = (this.planning.planQuality + quality) / 2
  }
}

🎯 Adaptive Planning

Dynamic Replanning

// Adapt plans based on execution feedback
class AdaptivePlanner {
  async replan(originalPlan: TaskPlan, feedback: ExecutionFeedback): Promise<TaskPlan> {
    const issues = this.analyzeFeedback(feedback)
    const adjustments = await this.generateAdjustments(issues)

    return {
      ...originalPlan,
      adjustments,
      updatedAt: new Date(),
      version: originalPlan.version + 1
    }
  }

  private analyzeFeedback(feedback: ExecutionFeedback) {
    const issues = []

    if (feedback.executionTime > feedback.expectedTime * 1.5) {
      issues.push({ type: 'performance', severity: 'high' })
    }

    if (feedback.errorRate > 0.1) {
      issues.push({ type: 'reliability', severity: 'medium' })
    }

    return issues
  }

  private async generateAdjustments(issues: any[]) {
    const adjustments = []

    for (const issue of issues) {
      const adjustment = await this.createAdjustment(issue)
      adjustments.push(adjustment)
    }

    return adjustments
  }
}

Learning from Experience

// Learn from past planning experiences
class PlanningLearner {
  private experiences: PlanningExperience[] = []

  recordExperience(experience: PlanningExperience) {
    this.experiences.push(experience)

    // Keep only recent experiences
    if (this.experiences.length > 1000) {
      this.experiences.shift()
    }
  }

  async learnFromExperiences() {
    // Analyze patterns in successful vs failed plans
    const patterns = this.extractPatterns(this.experiences)

    // Update planning strategies
    await this.updateStrategies(patterns)

    // Improve future planning
    this.refinePlanningAlgorithm(patterns)
  }

  private extractPatterns(experiences: PlanningExperience[]) {
    // Extract common patterns and correlations
    return {
      successfulPatterns: this.findSuccessfulPatterns(experiences),
      failurePatterns: this.findFailurePatterns(experiences),
      optimizationOpportunities: this.findOptimizationOpportunities(experiences)
    }
  }
}

🚀 Advanced Planning Techniques

Multi-Agent Planning

// Coordinate planning across multiple agents
class MultiAgentPlanner {
  private agents: Agent[] = []

  async createCollaborativePlan(goal: string): Promise<CollaborativePlan> {
    const agentPlans = await Promise.all(
      this.agents.map(agent => agent.createPlan(goal))
    )

    const conflicts = this.identifyConflicts(agentPlans)
    const resolutions = await this.resolveConflicts(conflicts)

    return {
      goal,
      agentPlans,
      conflicts,
      resolutions,
      coordinationStrategy: this.createCoordinationStrategy(resolutions)
    }
  }

  private identifyConflicts(plans: TaskPlan[]): Conflict[] {
    const conflicts = []

    for (let i = 0; i < plans.length; i++) {
      for (let j = i + 1; j < plans.length; j++) {
        const conflict = this.checkPlanConflict(plans[i], plans[j])
        if (conflict) conflicts.push(conflict)
      }
    }

    return conflicts
  }
}

Probabilistic Planning

// Handle uncertainty in planning
class ProbabilisticPlanner {
  async createProbabilisticPlan(goal: string, uncertainty: number): Promise<ProbabilisticPlan> {
    const scenarios = await this.generateScenarios(goal, uncertainty)
    const plans = await Promise.all(
      scenarios.map(scenario => this.createScenarioPlan(scenario))
    )

    return {
      goal,
      scenarios,
      plans,
      probabilities: this.calculateProbabilities(scenarios),
      expectedUtility: this.calculateExpectedUtility(plans)
    }
  }

  private async generateScenarios(goal: string, uncertainty: number): Promise<Scenario[]> {
    // Generate different possible scenarios based on uncertainty
    const scenarios = []
    const numScenarios = Math.max(10, Math.floor(uncertainty * 50))

    for (let i = 0; i < numScenarios; i++) {
      scenarios.push(await this.createScenario(goal, uncertainty))
    }

    return scenarios
  }
}

📝 Chapter Summary

  • ✅ Learned goal decomposition techniques
  • ✅ Implemented hierarchical task planning
  • ✅ Used A* and Monte Carlo Tree Search algorithms
  • ✅ Set up progress tracking and monitoring
  • ✅ Created adaptive planning systems
  • ✅ Built multi-agent and probabilistic planning

Key Takeaways:

  • Complex goals need systematic decomposition
  • Dependencies must be carefully managed
  • Different planning algorithms suit different scenarios
  • Progress tracking enables better control
  • Adaptive planning handles changing conditions
  • Learning from experience improves future planning

What Problem Does This Solve?

Most teams struggle here because the hard part is not writing more code, but deciding clear boundaries for goal, task, planning so behavior stays predictable as complexity grows.

In practical terms, this chapter helps you avoid three common failures:

  • coupling core logic too tightly to one implementation path
  • missing the handoff boundaries between setup, execution, and validation
  • shipping changes without clear rollback or observability strategy

After working through this chapter, you should be able to reason about Chapter 3: Task Planning & Goal Setting as an operating subsystem inside AgentGPT Tutorial: Building Autonomous AI Agents, with explicit contracts for inputs, state transitions, and outputs.

Use the implementation notes around Promise, subtasks, node as your checklist when adapting these patterns to your own repository.

How it Works Under the Hood

Under the hood, Chapter 3: Task Planning & Goal Setting usually follows a repeatable control path:

  1. Context bootstrap: initialize runtime config and prerequisites for goal.
  2. Input normalization: shape incoming data so task receives stable contracts.
  3. Core execution: run the main logic branch and propagate intermediate state through planning.
  4. Policy and safety checks: enforce limits, auth scopes, and failure boundaries.
  5. Output composition: return canonical result payloads for downstream consumers.
  6. Operational telemetry: emit logs/metrics needed for debugging and performance tuning.

When debugging, walk this sequence in order and confirm each stage has explicit success/failure conditions.

Source Walkthrough

Use the following upstream sources to verify implementation details while reading this chapter:

  • View Repo Why it matters: authoritative reference on View Repo (github.com).

Suggested trace strategy:

  • search upstream code for goal and task to map concrete implementation paths
  • compare docs claims against actual runtime/config code before reusing patterns in production

Chapter Connections