ARC Lang

repository·main·Indexed 43 days ago

https://github.com/jerber/arc-lang-public

An asynchronous pipeline for solving Abstraction and Reasoning Corpus (ARC) puzzles using Large Language Models. It employs an iterative process of instruction generation, scoring via cross-validation, and instruction revision to produce high-quality candidate answers. The system utilizes a natural language evolution approach, leveraging structured generation and visual diff notation to refine transformation rules.

Tokens
10.3K
Snippets
43
Records
51
Agent score
51%

What's inside ARC Lang

  1. How RunConfig and solve steps work

    main

    A RunConfig defines the strategy for solving ARC puzzles by bundling a sequence of Step types and execution parameters.

    Step Types

    • Step: Generates times instruction candidates using an instruction_model, then scores them by executing those instructions with a follow_model.
    • StepRevision: Takes the top top_scores_used candidates and asks the LLM to revise each one times_per_top_score times, followed by a rescore.
    • StepRevisionPool: Synthesizes a brand-new instruction set by providing a prompt that includes multiple previous instruction sets and their respective scores.

    Execution Parameters

    • final_follow_model & final_follow_times: Used during the final pass to generate the actual answers for the hidden test grids.
    • max_concurrent_tasks: Bounds the number of challenges being solved simultaneously.

    Presets are available in src/configs/ including mini_config (lightweight), grok_config_prod (production Grok), gpt_config_prod, and oss_config (open-source).

  2. Understand the ARC v2 Instruction-Based Architecture

    main

    The ARC v2 solution uses a natural language evolution approach rather than Python code generation. It leverages Large Language Models (LLMs) to both generate transformation rules (instructions) and apply those rules to grids. The system operates through a multi-phase pipeline:

    1. Instruction Generation: Creating initial rules based on training examples.
    2. Instruction Following: Applying those rules to a test input.
    3. Revision: Using feedback (errors and visual diffs) to refine instructions.
    4. Scoring: Evaluating instruction quality via cross-validation and grid similarity.

    This approach prioritizes expressiveness and flexibility, allowing models to describe nuanced patterns that might be difficult to capture in rigid code.

  3. Revise instructions using REVISION_PROMPT and Visual Diffs

    main

    When instructions fail to produce correct outputs, the system triggers a revision phase. The REVISION_PROMPT provides the model with the incorrect outputs and compares them to the ground truth using Visual Diff Notation.

    Visual Diff Notation Format:

    • ✓ indicates a correct cell.
    • actual→expected indicates an error.
    • A bordered ASCII grid is used for clarity.

    To ensure structured reasoning, the model is expected to respond using the ReviseInstructionsResponse format, forcing it to analyze failures before proposing fixes.

    # Visual Diff Example
    +-------+-------+-------+
    |  ✓0   |  2→3  |  ✓5   |
    +-------+-------+-------+
    |  1→0  |  ✓4   |  ✓5   |
    +-------+-------+-------+
    
    # Expected Response Structure
    class ReviseInstructionsResponse:
        reasoning_for_why_old_instructions_are_wrong: str
        revised_instructions: str
  4. Manage instruction evolution population

    main

    The system manages a population of instruction candidates through a specific lifecycle to maximize performance within token limits:

    1. Initial Phase: Generate 30 candidates $\rightarrow$ Filter to top performers.
    2. Individual Revision: Take top 5 $\rightarrow$ Generate 5 revised versions.
    3. Pooled Revision: Take top 5 $\rightarrow$ Synthesize 5 versions from successful elements of different approaches.

    Total limit: Maximum 40 instruction attempts per task.

  5. Configure ARC Lang environment variables

    main

    ARC Lang uses a .env file for configuration. While many variables are optional, you must set MAX_CONCURRENCY to define the global API semaphore.

    Required:

    • MAX_CONCURRENCY: Sets the global API semaphore in src/llms/structured.py.
    • API Keys: Set the key for your chosen provider (e.g., OPENAI_API_KEY, XAI_API_KEY, etc.).

    Common Optional Variables:

    • NEON_DSN: Enables result persistence to a Postgres database.
    • VIZ: Set to 1 to open matplotlib previews during scoring (requires a display).
    • LOG_GRIDS: Set to 1 to log mismatched grids verbosely.
    • LOCAL_LOGS_ONLY: Set to 1 to skip sending logs to remote Logfire.
    • XAI_API_KEY: Supports multiple keys separated by commas (e.g., key1,key2) for Grok.
    OPENAI_API_KEY=sk-...
    ANTHROPIC_API_KEY=...
    GEMINI_API_KEY=...
    DEEPSEEK_API_KEY=...
    OPENROUTER_API_KEY=...
    XAI_API_KEY=key1,key2
    MAX_CONCURRENCY=20
    
    LOGFIRE_API_KEY=...
    LOCAL_LOGS_ONLY=1
    LOG_LEVEL=INFO
    
    NEON_DSN=postgresql://...
    USE_TASK_ID=0
    VIZ=0
    LOG_GRIDS=0
  6. Debug and visualize ARC grid predictions

    main

    To inspect why a model failed or to see its reasoning, use the following methods:

    1. Visual Comparisons: Set VIZ=1 in your environment to automatically open matplotlib windows comparing predicted training grids against target grids.
    2. Grid Logging: Set LOG_GRIDS=1 to dump the expected vs. actual grids directly into the logs.
    3. Manual Diffing: Use generate_grid_diff (available in src/run.py) in a notebook to generate ASCII diffs between two grids.
    4. Intermediate Inspection: Check the temp_solutions/ directory to see the model's current guesses for test grids during a run.
  7. Generate initial instructions using INTUITIVE_PROMPT

    main

    The instruction generation phase uses a prompt designed to prime the model for pattern recognition. It emphasizes role-playing as an expert, consistency across all training examples, and generalization to unseen test cases.

    Grids are provided in multiple formats to optimize comprehension:

    • ASCII Text Format: Space-separated integers.
    • Base64 Images: Visual representations for vision-capable models.
    • Structured Context: Explicit labeling of --Training Examples-- and --Test Input--.
    --Training Examples--
    Training Example 1
    Input:
    0 0 0 5 0
    0 5 0 0 0
    0 0 0 0 0
    Output:
    5 0 0 0 0
    0 0 0 0 0
    0 0 0 0 0
    --End of Training Examples--
    --Test Input--
    0 0 0 0 0
    0 0 0 0 0
    0 0 0 0 0
  8. Run an ARC solve

    main

    The main entry point is src/run.py. By default, it is configured to run the 2025 evaluation challenges using the grok_config_prod preset with a limit of 1 task for smoke-testing.

    python src/run.py

    To run a full sweep or use a different configuration, you can call run_from_json from your own Python script.

  9. How the instruction refinement loop works

    main

    The system follows an iterative process to solve ARC challenges:

    1. Generation: get_instructions_from_challenge creates initial instructions.
    2. Scoring: get_instruction_scores evaluates multiple instruction attempts on the training set.
    3. Revision: If scores aren't perfect, get_revised_instructions uses feedback from failed attempts to improve the instructions.
    4. Pooling (Optional): get_pooling_instruction_from_scores can synthesize a single set of instructions from multiple high-scoring (but potentially flawed) attempts.
    5. Final Guess: Once the best instructions are found, return_answer generates final output grids for the test set using the final_follow_model.
  10. Troubleshoot ARC Lang issues

    main

    Common issues and solutions:

    • KeyError on import: You have not defined the MAX_CONCURRENCY environment variable.
    • Authentication Errors: Occur inside get_next_structure. Verify your API keys and provider quotas.
    • Rate Limiting: If you see repeated retry_failed logs, the provider is rate-limiting you. Solution: Lower max_concurrent_tasks or MAX_CONCURRENCY.
    • Matplotlib Errors on Headless Servers: Occur if VIZ=1 is set on a server without a display. Solution: Set VIZ=0.
  11. Use `run_from_json` for custom solve execution

    main

    You can programmatically execute a solve by calling run_from_json. This allows you to specify custom JSON paths, different RunConfig presets, and control the scope of the run via limit and offset.

    await run_from_json(
        challenges_path=challenges_path,
        truth_solutions_path=None,      # disable automatic scoring
        config=mini_config,             # use the faster preset
        attempts_path=attempts_path,
        temp_attempts_dir=temp_attempts_path,
        limit=None,
        offset=0,
    )