Skip to main content

AI-native creation organism. Create, critique, and evolve cultural art.

Project description

VULCA

PyPI version Python 3.10+ License: Apache 2.0 Tests

Make any image generator culturally accurate. VULCA scores visual works on 5 dimensions (L1-L5), tells you exactly what's wrong, and guides the next generation to fix it.

pip install vulca
export GOOGLE_API_KEY=your-key
vulca evaluate painting.jpg --tradition chinese_xieyi
VULCA Evaluation Result
========================================
Score:     95%
Tradition: chinese_xieyi

Dimensions:
  L1 Visual Perception         ███████████████████░ 95%
  L2 Technical Execution       ██████████████████░░ 90%
  L3 Cultural Context          ████████████████████ 98%
  L4 Critical Interpretation   ███████████████████░ 95%
  L5 Philosophical Aesthetics  ███████████████████░ 95%

Summary: Overall excellent (95%) under Chinese Xieyi tradition.
  Strongest: Cultural Context (98%).
  Room for growth: Technical Execution (90%).

Based on peer-reviewed research: VULCA Framework (EMNLP 2025 Findings) and VULCA-Bench (7,410 samples, 9 traditions).

What VULCA Does

Midjourney can generate a "Chinese ink wash painting" — but it uses the wrong brushstroke technique, has insufficient blank space, and applies Western perspective instead of scatter perspective. It looks like Chinese painting but isn't culturally correct.

VULCA fixes this:

Your image / Any generator's output
         ↓
    VULCA evaluates (L1-L5 + tradition-specific terminology)
         ↓
    Tells you: "L2: brushwork uses axe-cut texture (斧劈皴),
                xieyi should use hemp-fiber strokes (披麻皴)"
         ↓
    Re-generate with corrected guidance → re-evaluate
         ↓
    Scores improve: 0.34 → 0.72 → 0.89

Install

pip install vulca

Try it in 10 seconds — no API key needed:

vulca evaluate painting.jpg --mock --tradition chinese_xieyi
vulca create "水墨山水" --provider mock

For real scoring, set a Google API key (free tier works):

export GOOGLE_API_KEY=your-key-here
vulca evaluate painting.jpg --tradition chinese_xieyi

Quick Start — Python SDK

import vulca

# Evaluate any image (file path, URL, or base64)
result = vulca.evaluate("painting.jpg", tradition="chinese_xieyi")
print(result.score)          # 0.82
print(result.dimensions)     # {"L1": 0.75, "L2": 0.82, "L3": 0.86, ...}
print(result.rationales)     # {"L1": "Masterful use of blank space (留白)...", ...}
print(result.recommendations)  # ["Improve technical execution...", ...]

# Evaluate from URL
result = vulca.evaluate("https://example.com/artwork.jpg", tradition="watercolor")

# Create through the full pipeline (Generate → Evaluate → Decide)
result = vulca.create("Misty mountains in ink wash", tradition="chinese_xieyi", provider="gemini")
print(result.weighted_total) # 0.95
print(result.scores)         # {"L1": 0.95, "L2": 0.90, "L3": 0.95, ...}

# Bring your own image generator
from vulca import ImageProvider, ImageResult

class MyLocalSD:
    async def generate(self, prompt, **kwargs):
        image_bytes = my_model.generate(prompt)  # your model
        return ImageResult(image_b64=base64.b64encode(image_bytes).decode())

result = vulca.create("landscape", image_provider=MyLocalSD())

# No API key? Mock mode for testing
result = vulca.evaluate("painting.jpg", mock=True)

Quick Start — CLI

# Evaluate artwork with real Gemini VLM scoring
vulca evaluate painting.jpg --tradition chinese_xieyi

# Evaluate from URL
vulca evaluate "https://example.com/art.jpg" -t watercolor

# Create artwork via Gemini image generation + evaluation
vulca create "仿倪瓒枯木竹石,干笔淡墨" --provider gemini -t chinese_xieyi

# List all 13 available traditions
vulca traditions

# Get cultural guide (terminology, taboos, weights)
vulca tradition chinese_xieyi

# Check how weights have evolved
vulca evolution chinese_xieyi

# HITL mode with custom L1-L5 weights
vulca create "水墨山水" --hitl --weights "L1=0.3,L2=0.2,L3=0.2,L4=0.15,L5=0.15"

# JSON output for scripting
vulca evaluate painting.jpg --mock --json

Example Output — vulca traditions

Available Domains (13):
==================================================
  african_traditional       emphasis: Cultural (30%)
  brand_design              emphasis: Technical (30%)
  chinese_gongbi            emphasis: Technical (30%)
  chinese_xieyi             emphasis: Philosophical (30%)
  contemporary_art          emphasis: Cultural (30%)
  islamic_geometric         emphasis: Technical (30%)
  japanese_traditional      emphasis: Philosophical (25%)
  photography               emphasis: Visual (25%)
  south_asian               emphasis: Cultural (25%)
  ui_ux_design              emphasis: Technical (30%)
  watercolor                emphasis: Technical (25%)
  western_academic          emphasis: Technical (25%)

BYOK — Bring Your Own Key / Model

# Gemini (evaluation + image generation)
export GOOGLE_API_KEY=your-key
vulca evaluate painting.jpg -t chinese_xieyi
vulca create "landscape" --provider gemini -t watercolor

# OpenAI DALL-E 3 (image generation only)
export OPENAI_API_KEY=your-key
vulca create "Zen garden" --provider openai -t japanese_traditional

# ComfyUI / local Stable Diffusion
vulca create "Oil painting" --provider comfyui --image-base-url http://localhost:8188

# Local VLM via Ollama (evaluation only)
vulca evaluate photo.jpg --vlm-model ollama/llava --vlm-base-url http://localhost:11434

# No API key at all — mock mode
vulca evaluate painting.jpg --mock
vulca create "水墨山水" --provider mock

Claude Code Plugin

VULCA is available as a Claude Code plugin with 6 MCP tools + 3 skills + 1 agent.

# Option 1: Plugin (recommended)
claude plugin marketplace add vulca-org/vulca-plugin
claude plugin install vulca

# Option 2: MCP only
pip install vulca[mcp]
claude mcp add vulca -- vulca-mcp

Once installed, ask Claude Code naturally:

"Evaluate this painting for Chinese xieyi tradition" "Create a Japanese ink wash landscape" "What traditions are available?"

MCP Tools

Tool Description
create_artwork Create artwork through the pipeline, returns image + L1-L5 scores
evaluate_artwork Evaluate artwork on L1-L5 dimensions with rationale text
list_traditions List all 13 domains with weights and emphasis
get_tradition_guide Full cultural context: terminology, taboos, weights
resume_artwork HITL continuation: accept, refine, or reject
get_evolution_status Weight evolution history and insights per domain

Other AI Assistants

# OpenAI Codex CLI
codex mcp add vulca -- vulca-mcp

# OpenHands
[mcp]
stdio_servers = [{ name = "vulca", command = "vulca-mcp", args = [] }]

L1-L5 Evaluation Framework

Five layers of evaluation, each reinterpreted per domain:

Layer What it measures Traditional Art UI/UX Design
L1 Surface Perception Composition, ink harmony Visual discoverability
L2 Technical Execution Brushwork, medium mastery Pattern compliance, WCAG
L3 Contextual Fit Cultural tradition adherence User mental model match
L4 Critical Reading Narrative depth, symbolism Intent-behavior alignment
L5 Deeper Meaning Philosophical aesthetics Design ethics

Weights shift per domain — Chinese Xieyi weights L5 (philosophy) at 30%, Brand Design weights L2 (system adherence) at 30%.

Domain Weights (click to expand)
Domain Emphasis L1 L2 L3 L4 L5
Chinese Xieyi (写意) Philosophical .10 .15 .25 .20 .30
Chinese Gongbi (工笔) Technical .15 .30 .25 .15 .15
Japanese Traditional Philosophical .15 .20 .20 .20 .25
Islamic Geometric Technical .25 .30 .20 .15 .10
Western Academic Technical .20 .25 .15 .25 .15
African Traditional Cultural .15 .20 .30 .20 .15
South Asian Cultural .15 .20 .25 .15 .25
Watercolor Balanced .20 .25 .15 .20 .20
Contemporary Art Art-Historical .10 .15 .30 .25 .20
Photography Balanced .25 .25 .20 .20 .10
Brand Design Technical .25 .30 .25 .15 .05
UI/UX Design Technical .20 .30 .25 .20 .05

All weights evolve automatically from evaluation sessions. Run vulca tradition <name> to see domain-specific terminology and taboos.

Self-Evolution

The system learns from every evaluation session:

  1. ContextEvolver adjusts L1-L5 weights per domain based on scoring patterns
  2. FewShotUpdater selects high-scoring examples (>=0.75) as calibration benchmarks
  3. VLM prompt receives evolved weights, few-shot references, and domain insights
  4. vulca.get_weights(domain) returns evolved weights, falling back to YAML defaults

Contributing a Domain

Add a YAML file to src/vulca/cultural/data/traditions/:

name: my_domain
display_name:
  en: "My Domain"
  zh: ""
weights:
  L1: 0.20
  L2: 0.20
  L3: 0.20
  L4: 0.20
  L5: 0.20
terminology:
  - term: "key concept"
    definition: "What this means in this domain"
taboos:
  - rule: "Do not judge X as Y in this domain"
    severity: medium

See _template.yaml for the full schema. PRs welcome.

Architecture

vulca/
├── pipeline/     # Execution engine + 3 built-in nodes + 3 templates
├── providers/    # Pluggable ImageProvider + VLMProvider protocols
├── cultural/     # 13 YAML domain configs with L1-L5 weights
├── scoring/      # VLM model routing + L1-L5 types
├── storage/      # Session/Feedback protocol + JSONL backend
├── intent/       # Natural language → domain resolution
├── _vlm.py       # Gemini Vision L1-L5 scoring (core)
├── cli.py        # CLI entry point
└── mcp_server.py # MCP server (6 tools, FastMCP)

Tests

pip install vulca[dev]
pytest tests/ -v  # 276 tests

Citation

@inproceedings{yu2025vulca,
  title={VULCA: A Framework for Cultural Art Evaluation},
  author={Yu, Haorui},
  booktitle={Findings of EMNLP 2025},
  year={2025}
}

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vulca-0.3.1.tar.gz (92.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vulca-0.3.1-py3-none-any.whl (102.0 kB view details)

Uploaded Python 3

File details

Details for the file vulca-0.3.1.tar.gz.

File metadata

  • Download URL: vulca-0.3.1.tar.gz
  • Upload date:
  • Size: 92.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for vulca-0.3.1.tar.gz
Algorithm Hash digest
SHA256 e9936de5fded6740f6663164db8e483876468706ca267f2899abc137b781fbfd
MD5 a3253f4d497303c3c69bb7d9ba5562e7
BLAKE2b-256 9bd5c5e02b491d5bf1cf30dbb60c1c771c5c4825afa33cc86a8c290a5f10a4c6

See more details on using hashes here.

File details

Details for the file vulca-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: vulca-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 102.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for vulca-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 63e224ba546e6492ada0c64cf3d7b82af6b14ef4a3f33ae94cc011f61caea94e
MD5 da528ce9bd4c7db240591766c3fdc064
BLAKE2b-256 75a24c8f2369738894c9855f930d113fe7c209dd2efa6d7b40e5ce55cc1c4152

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page