Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Latest commit

Β 

History

History
258 lines (218 loc) Β· 12.7 KB

File metadata and controls

258 lines (218 loc) Β· 12.7 KB

smolagents logo

ML Intern

An ML intern that autonomously researches, writes, and ships good quality ML releated code using the Hugging Face ecosystem β€” with deep access to docs, papers, datasets, and cloud compute.

Deploy to AWS

Step 1: Download Template

Template Description Download
EC2 (Simple) Single instance, SSH access ml-intern-stack.yaml
Fargate (Production) Auto-scaling, Load Balancer ml-intern-fargate.yaml

Step 2: Open CloudFormation Console

Region Open Console
US East (N. Virginia) Deploy
US West (Oregon) Deploy
EU (Ireland) Deploy

Step 3: Upload & Deploy

  1. Select "Upload a template file"
  2. Upload the downloaded YAML file
  3. Enter your HuggingFace token
  4. Click "Create Stack"

Prerequisites: Enable Bedrock models in your AWS account first.

See cloudformation/README.md for detailed instructions.

Quick Start

Installation

git clone [email protected]:huggingface/ml-intern.git
cd ml-intern
uv sync
uv tool install -e .

That's it. Now ml-intern works from any directory:

ml-intern

Create a .env file in the project root (or export these in your shell):

ANTHROPIC_API_KEY=<your-anthropic-api-key> # if using anthropic models
HF_TOKEN=<your-hugging-face-token>
GITHUB_TOKEN=<github-personal-access-token> 

If no HF_TOKEN is set, the CLI will prompt you to paste one on first launch. To get a GITHUB_TOKEN follow the tutorial here.

Usage

Interactive mode (start a chat session):

ml-intern

Headless mode (single prompt, auto-approve):

ml-intern "fine-tune llama on my dataset"

Options:

ml-intern --model anthropic/claude-opus-4-6 "your prompt"
ml-intern --max-iterations 100 "your prompt"
ml-intern --no-stream "your prompt"

Architecture

Component Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         User/CLI                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ Operations                          β”‚ Events
             ↓ (user_input, exec_approval,         ↑
      submission_queue  interrupt, compact, ...)  event_queue
             β”‚                                          β”‚
             ↓                                          β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚            submission_loop (agent_loop.py)         β”‚  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚  1. Receive Operation from queue             β”‚  β”‚  β”‚
β”‚  β”‚  2. Route to handler (run_agent/compact/...) β”‚  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚                      ↓                             β”‚  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚         Handlers.run_agent()                 β”‚  β”œβ”€β”€β”€
β”‚  β”‚                                              β”‚  β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  Agentic Loop (max 300 iterations)     β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚                                        β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚ Session                          β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚ ContextManager             β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚ β€’ Message history          β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚   (litellm.Message[])      β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚ β€’ Auto-compaction (170k)   β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚ β€’ Session upload to HF     β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚                                  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚ ToolRouter                 β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚  β”œβ”€ HF docs & research     β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚  β”œβ”€ HF repos, datasets,    β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚  β”‚  jobs, papers           β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚  β”œβ”€ GitHub code search     β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚  β”œβ”€ Sandbox & local tools  β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚  β”œβ”€ Planning               β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β”‚  └─ MCP server tools       β”‚  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚                                        β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚ Doom Loop Detector               β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚ β€’ Detects repeated tool patterns β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚ β€’ Injects corrective prompts     β”‚  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚                                        β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  Loop:                                 β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚    1. LLM call (litellm.acompletion)   β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚       ↓                                β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚    2. Parse tool_calls[]               β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚       ↓                                β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚    3. Approval check                   β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚       (jobs, sandbox, destructive ops) β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚       ↓                                β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚    4. Execute via ToolRouter           β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚       ↓                                β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚    5. Add results to ContextManager    β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚       ↓                                β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚    6. Repeat if tool_calls exist       β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”˜

Agentic Loop Flow

User Message
     ↓
[Add to ContextManager]
     ↓
     ╔═══════════════════════════════════════════╗
     β•‘      Iteration Loop (max 300)             β•‘
     β•‘                                           β•‘
     β•‘  Get messages + tool specs                β•‘
     β•‘         ↓                                 β•‘
     β•‘  litellm.acompletion()                    β•‘
     β•‘         ↓                                 β•‘
     β•‘  Has tool_calls? ──No──> Done             β•‘
     β•‘         β”‚                                 β•‘
     β•‘        Yes                                β•‘
     β•‘         ↓                                 β•‘
     β•‘  Add assistant msg (with tool_calls)      β•‘
     β•‘         ↓                                 β•‘
     β•‘  Doom loop check                          β•‘
     β•‘         ↓                                 β•‘
     β•‘  For each tool_call:                      β•‘
     β•‘    β€’ Needs approval? ──Yes──> Wait for    β•‘
     β•‘    β”‚                         user confirm β•‘
     β•‘    No                                     β•‘
     β•‘    ↓                                      β•‘
     β•‘    β€’ ToolRouter.execute_tool()            β•‘
     β•‘    β€’ Add result to ContextManager         β•‘
     β•‘         ↓                                 β•‘
     β•‘  Continue loop ─────────────────┐         β•‘
     β•‘         ↑                       β”‚         β•‘
     β•‘         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β•‘
     β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Events

The agent emits the following events via event_queue:

  • processing - Starting to process user input
  • ready - Agent is ready for input
  • assistant_chunk - Streaming token chunk
  • assistant_message - Complete LLM response text
  • assistant_stream_end - Token stream finished
  • tool_call - Tool being called with arguments
  • tool_output - Tool execution result
  • tool_log - Informational tool log message
  • tool_state_change - Tool execution state transition
  • approval_required - Requesting user approval for sensitive operations
  • turn_complete - Agent finished processing
  • error - Error occurred during processing
  • interrupted - Agent was interrupted
  • compacted - Context was compacted
  • undo_complete - Undo operation completed
  • shutdown - Agent shutting down

Development

Adding Built-in Tools

Edit agent/core/tools.py:

def create_builtin_tools() -> list[ToolSpec]:
    return [
        ToolSpec(
            name="your_tool",
            description="What your tool does",
            parameters={
                "type": "object",
                "properties": {
                    "param": {"type": "string", "description": "Parameter description"}
                },
                "required": ["param"]
            },
            handler=your_async_handler
        ),
        # ... existing tools
    ]

Adding MCP Servers

Edit configs/main_agent_config.json:

{
  "model_name": "anthropic/claude-sonnet-4-5-20250929",
  "mcpServers": {
    "your-server-name": {
      "transport": "http",
      "url": "https://example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${YOUR_TOKEN}"
      }
    }
  }
}

Note: Environment variables like ${YOUR_TOKEN} are auto-substituted from .env.