ai-coaching

Multi-turn conversational AI for intent extraction, clarification, and generation readiness detection. Guides users through articulating creative intent with structured parameter extraction.

16 stars

Best use case

ai-coaching is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Multi-turn conversational AI for intent extraction, clarification, and generation readiness detection. Guides users through articulating creative intent with structured parameter extraction.

Teams using ai-coaching should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/ai-coaching/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/machine-learning/ai-coaching/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/ai-coaching/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How ai-coaching Compares

Feature / Agentai-coachingStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Multi-turn conversational AI for intent extraction, clarification, and generation readiness detection. Guides users through articulating creative intent with structured parameter extraction.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# AI Coaching System

Multi-turn conversational AI that guides users through articulating intent.

## When to Use This Skill

- Building AI assistants that need to understand complex user intent
- Need structured parameter extraction from conversation
- Want to detect when user intent is ready for action
- Implementing clarification flows for ambiguous input

## Core Concepts

The coach helps users articulate WHAT they want, not HOW to achieve it. It extracts structured intent through conversation, tracks ambiguities, and signals readiness only after user confirmation.

```
User Input → Intent Parser → Schema Update → Readiness Check → Coach Response
```

## Implementation

### Python

```python
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional, List, Dict, Any
from enum import Enum
import re


class ReadinessState(str, Enum):
    NOT_READY = "not_ready"
    NEEDS_CLARIFICATION = "needs_clarification"
    AWAITING_CONFIRMATION = "awaiting_confirmation"
    READY = "ready"


@dataclass
class AmbiguousAnnotation:
    text: str
    possible_intents: List[str]
    resolved: bool = False
    resolution: Optional[str] = None


@dataclass
class CreativeIntentSchema:
    """Structured representation of user's creative intent."""
    asset_type: str
    mood: Optional[str] = None
    scene_elements: List[Dict] = field(default_factory=list)
    display_texts: List[Dict] = field(default_factory=list)
    ambiguous_annotations: List[AmbiguousAnnotation] = field(default_factory=list)
    turn_count: int = 0
    user_confirmed_vision: bool = False
    last_coach_summary: Optional[str] = None

    def get_readiness(self) -> ReadinessState:
        if self.turn_count == 0:
            return ReadinessState.NOT_READY
        
        unresolved = [a for a in self.ambiguous_annotations if not a.resolved]
        if unresolved:
            return ReadinessState.NEEDS_CLARIFICATION
        
        if not self.user_confirmed_vision:
            return ReadinessState.AWAITING_CONFIRMATION
        
        return ReadinessState.READY

    def is_ready(self) -> bool:
        return self.get_readiness() == ReadinessState.READY

    def get_clarification_questions(self) -> List[str]:
        return [
            f'Should "{a.text}" be rendered as an image or displayed as text?'
            for a in self.ambiguous_annotations if not a.resolved
        ]


class IntentParser:
    """Parses messages to extract and update intent."""
    
    CONFIRMATION_PATTERNS = [
        r"\b(yes|yeah|sure|ok|perfect|great|looks good|exactly)\b",
        r"\b(let's go|do it|generate|create it)\b",
    ]

    def parse_initial_request(
        self,
        description: str,
        asset_type: str,
        mood: Optional[str] = None,
    ) -> CreativeIntentSchema:
        schema = CreativeIntentSchema(asset_type=asset_type, mood=mood)
        
        # Extract quoted text as display text
        quoted = re.findall(r'"([^"]+)"', description)
        for text in quoted:
            schema.display_texts.append({"text": text})
        
        if description and not quoted:
            schema.scene_elements.append({"description": description})
        
        return schema

    def parse_user_message(
        self,
        message: str,
        schema: CreativeIntentSchema,
    ) -> tuple[CreativeIntentSchema, bool]:
        schema.turn_count += 1
        
        is_confirmation = self._is_confirmation(message)
        if is_confirmation:
            schema.user_confirmed_vision = True
        
        # Resolve ambiguities from user response
        message_lower = message.lower()
        for amb in schema.ambiguous_annotations:
            if not amb.resolved:
                if "text" in message_lower or "display" in message_lower:
                    amb.resolved = True
                    amb.resolution = "display_text"
                elif "render" in message_lower or "image" in message_lower:
                    amb.resolved = True
                    amb.resolution = "render"
        
        return schema, is_confirmation

    def _is_confirmation(self, message: str) -> bool:
        message_lower = message.lower().strip()
        return any(re.search(p, message_lower) for p in self.CONFIRMATION_PATTERNS)


@dataclass
class StreamChunk:
    type: str  # "token", "intent_ready", "done", "error"
    content: str = ""
    metadata: Optional[Dict[str, Any]] = None


class CoachService:
    """Orchestrates coaching conversations."""
    
    MAX_TURNS = 10

    def __init__(self, llm_client, session_store):
        self.llm = llm_client
        self.sessions = session_store
        self.parser = IntentParser()

    async def start_session(
        self,
        user_id: str,
        asset_type: str,
        description: str,
        mood: Optional[str] = None,
    ):
        # Initialize intent schema
        schema = self.parser.parse_initial_request(description, asset_type, mood)
        
        # Build system prompt
        system_prompt = f"""You are a creative coach helping users design {asset_type} assets.

RULES:
1. Ask clarifying questions to understand their vision
2. Summarize what you understand after each exchange
3. When vision is clear, say [INTENT_READY]
4. Never say [INTENT_READY] on first turn
5. Focus on WHAT they want, not HOW"""

        first_message = f'User wants to create a {asset_type}. Description: "{description}"'
        
        # Stream LLM response
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": first_message},
        ]
        
        full_response = ""
        async for token in self.llm.stream_chat(messages):
            full_response += token
            yield StreamChunk(type="token", content=token)
        
        # First turn is NEVER ready
        yield StreamChunk(
            type="intent_ready",
            metadata={
                "is_ready": False,
                "readiness_state": ReadinessState.NOT_READY.value,
                "clarification_questions": schema.get_clarification_questions(),
            },
        )
        
        yield StreamChunk(type="done", metadata={"turns_remaining": self.MAX_TURNS - 1})

    async def continue_chat(
        self,
        session_id: str,
        message: str,
        schema: CreativeIntentSchema,
    ):
        if schema.turn_count >= self.MAX_TURNS:
            yield StreamChunk(type="error", content="Turn limit reached")
            return
        
        schema, is_confirmation = self.parser.parse_user_message(message, schema)
        
        # Stream response...
        full_response = ""
        async for token in self.llm.stream_chat([...]):
            full_response += token
            yield StreamChunk(type="token", content=token)
        
        readiness = schema.get_readiness()
        
        yield StreamChunk(
            type="intent_ready",
            metadata={
                "is_ready": schema.is_ready(),
                "readiness_state": readiness.value,
                "is_confirmation": is_confirmation,
            },
        )
```

### TypeScript

```typescript
enum ReadinessState {
  NOT_READY = 'not_ready',
  NEEDS_CLARIFICATION = 'needs_clarification',
  AWAITING_CONFIRMATION = 'awaiting_confirmation',
  READY = 'ready',
}

interface AmbiguousAnnotation {
  text: string;
  possibleIntents: string[];
  resolved: boolean;
  resolution?: string;
}

interface CreativeIntentSchema {
  assetType: string;
  mood?: string;
  sceneElements: Array<{ description: string }>;
  displayTexts: Array<{ text: string }>;
  ambiguousAnnotations: AmbiguousAnnotation[];
  turnCount: number;
  userConfirmedVision: boolean;
}

function getReadiness(schema: CreativeIntentSchema): ReadinessState {
  if (schema.turnCount === 0) return ReadinessState.NOT_READY;
  
  const unresolved = schema.ambiguousAnnotations.filter(a => !a.resolved);
  if (unresolved.length > 0) return ReadinessState.NEEDS_CLARIFICATION;
  
  if (!schema.userConfirmedVision) return ReadinessState.AWAITING_CONFIRMATION;
  
  return ReadinessState.READY;
}

const CONFIRMATION_PATTERNS = [
  /\b(yes|yeah|sure|ok|perfect|great|looks good)\b/i,
  /\b(let's go|do it|generate|create it)\b/i,
];

function isConfirmation(message: string): boolean {
  return CONFIRMATION_PATTERNS.some(p => p.test(message));
}
```

## Usage Examples

```python
# Start coaching session
async for chunk in coach.start_session(
    user_id="user_123",
    asset_type="thumbnail",
    description="gaming video thumbnail",
    mood="energetic",
):
    if chunk.type == "token":
        print(chunk.content, end="")
    elif chunk.type == "intent_ready":
        if chunk.metadata["is_ready"]:
            # Proceed to generation
            pass
        else:
            # Show clarification questions
            for q in chunk.metadata.get("clarification_questions", []):
                print(f"Coach asks: {q}")
```

## Best Practices

1. Never mark intent as ready on first turn - always ask questions
2. Require explicit user confirmation before proceeding
3. Track and resolve ambiguities explicitly
4. Summarize understanding after each exchange
5. Limit total turns to prevent infinite conversations
6. Stream responses for better UX

## Common Mistakes

- Auto-confirming intent without user acknowledgment
- Not tracking ambiguous terms that need clarification
- Allowing ready state on first turn
- Not persisting session state for reconnections
- Forgetting turn limits

## Related Patterns

- prompt-engine (prompt construction)
- ai-generation-client (generation execution)
- sse-streaming (response streaming)

Related Skills

bgo

10
from diegosouzapw/awesome-omni-skill

Automates the complete Blender build-go workflow, from building and packaging your extension/add-on to removing old versions, installing, enabling, and launching Blender for quick testing and iteration.

Coding & Development

agile-product-owner

16
from diegosouzapw/awesome-omni-skill

Agile product ownership toolkit for Senior Product Owner including INVEST-compliant user story generation, sprint planning, backlog management, and velocity tracking. Use for story writing, sprint planning, stakeholder communication, and agile ceremonies.

agile-planning

16
from diegosouzapw/awesome-omni-skill

Generate agile release plans with sprints and roadmaps using unique sprint codes. Use when creating sprint schedules, product roadmaps, release planning, or when user mentions agile planning, sprints, roadmap, or release plans.

agent-product-manager

16
from diegosouzapw/awesome-omni-skill

Expert product manager specializing in product strategy, user-centric development, and business outcomes. Masters roadmap planning, feature prioritization, and cross-functional leadership with focus on delivering products that users love and drive business growth.

ae-sdd-discovery

16
from diegosouzapw/awesome-omni-skill

Discover high-level architectural requirements for change-set specs

advanced-text-search-matching

16
from diegosouzapw/awesome-omni-skill

Production-grade text search algorithms for finding and matching text in large documents with millisecond performance. Includes Boyer-Moore search, n-gram similarity, fuzzy matching, and intelligent indexing. Use when building search features for large documents, finding quotes with imperfect matches, implementing fuzzy search, or need character-level precision.

adr-roadmap

16
from diegosouzapw/awesome-omni-skill

Generate phased implementation roadmaps from Architecture Decision Records

adhd-productivity

16
from diegosouzapw/awesome-omni-skill

ADHD-optimized productivity techniques and interventions. Invoke when user shows signs of task abandonment, context switching, or needs focus assistance.

add-new-feature

16
from diegosouzapw/awesome-omni-skill

No description provided.

account-plan

16
from diegosouzapw/awesome-omni-skill

Create or update strategic account plan

account-executive

16
from diegosouzapw/awesome-omni-skill

Эксперт по B2B продажам. Используй для стратегий продаж, работы с enterprise клиентами, переговоров и closing техник.

aboutme-index

16
from diegosouzapw/awesome-omni-skill

Index-based file discovery using ABOUTME headers. Use INSTEAD of grep or Explore agent when searching for files by purpose or feature. Faster and more accurate than scanning code. Invoke this skill when user asks "which files handle X", "where is Y implemented", or when you need to find files related to a feature or task.