PerfGuard: Performance-Aware Agent for Visual Content Generation
This skill enables Claude to design and implement multi-tool orchestration systems for AI-generated visual content (AIGC) that select tools based on measured performance boundaries rather than static descriptions. Derived from the PerfGuard framework (ICLR 2026), the approach replaces the naive assumption that "all tools work equally well" with a structured scoring, ranking, and adaptive update system across three mechanisms: Performance-Aware Selection Modeling (PASM), Adaptive Preference Update (APU), and Capability-Aligned Planning Optimization (CAPO).
When to Use
- When the user is building a pipeline that routes tasks to multiple image generation or editing models (e.g., FLUX, SDXL, DALL-E, Midjourney APIs)
- When the user wants to automatically pick the best tool for a specific visual subtask (e.g., "which model handles spatial relationships better?")
- When the user needs a scoring/evaluation system for comparing AI-generated images across quality dimensions
- When the user asks to build a self-improving agent that learns which tools work best over time
- When the user wants to decompose complex visual tasks into subtasks matched to tool strengths
- When the user is implementing fallback/retry logic for visual generation where output quality is uncertain
Key Technique
The core insight: Generic tool descriptions ("generates high-quality images") are useless for selection. PerfGuard replaces them with multi-dimensional performance scores measured on fine-grained capability axes. For text-to-image tools, these axes are: color accuracy, shape fidelity, texture realism, 2D spatial, 3D spatial, numeracy (correct object count), and non-spatial semantics. For image editing tools: addition, removal, replacement, attribute alteration, motion change, style transfer, and background change. Each tool gets a score (0.0-1.0) per dimension, producing a capability fingerprint.
Selection works by weighted dot product. Given a task, the system identifies which dimensions matter (e.g., a request involving "three red cups arranged left to right" weights numeracy, color, and 2D-spatial heavily). The preference score for each candidate tool is sum(tool.score[dim] * task.weight[dim]). Tools are ranked by this score; the top-N candidates execute. Results are evaluated via a multi-dimensional quality assessment (object count, position, attributes, style, background, semantic alignment) scored at three levels (L1=1.0, L2=0.66, L3=0.33). If the composite score falls below a threshold (default 0.8), the system re-plans and retries with alternative tools.
The system learns from outcomes. APU compares the predicted tool ranking against the actual quality ranking from execution. When discrepancies occur (predicted #1 actually performed worst), preference scores are updated. This closes the loop: the system gets better at tool selection over time without manual re-tuning. CAPO feeds these updated scores back into the planner, biasing subtask decomposition toward operations where strong tools exist rather than generating subtasks no tool can reliably handle.
Step-by-Step Workflow
Define capability dimensions for your tool domain. For text-to-image: [color, shape, texture, 2d_spatial, 3d_spatial, numeracy, non_spatial]. For image editing: [addition, removal, replacement, attribute_alter, motion_change, style_transfer, background_change]. For video or other domains, define analogous axes.
Build a tool registry with performance scores. For each tool, populate a score dictionary across all dimensions. Initialize from benchmarks or manual evaluation. Store as JSON:
{
"flux": {"color": 0.74, "shape": 0.57, "texture": 0.69, "2d_spatial": 0.63, "numeracy": 0.52, "non_spatial": 0.92},
"sd3": {"color": 0.81, "shape": 0.59, "texture": 0.73, "2d_spatial": 0.61, "numeracy": 0.48, "non_spatial": 0.91}
}
Implement the task analyzer (Analyst role). Parse user requests to extract: the task type (generation vs. editing), target objects, spatial relationships, style requirements, and reference images. Output a structured goal representation.
Implement dimension weight extraction. From the analyzed task, compute a weight vector over capability dimensions. A task mentioning "three objects arranged in a grid" gets high weights on numeracy and 2d_spatial. A style-transfer edit gets high weight on style_transfer. Use an LLM to classify or use keyword/rule-based mapping.
Compute preference-weighted tool rankings. For each candidate tool, calculate: score = sum(tool_scores[dim] * task_weights[dim] for dim in dimensions). Sort tools descending by score. Select top-N (typically 2-3) for parallel execution.
Execute and evaluate results. Run selected tools. Score each output on evaluation dimensions: object category/count correctness, positional accuracy, attribute binding, style match, background fidelity, overall semantic alignment. Use three-tier scoring (L1=1.0 fully correct, L2=0.66 partially correct, L3=0.33 present but wrong). Composite score = (mean(non_semantic_dims) + semantic_score) / 2.
Apply the quality threshold and retry loop. If the best output scores below 0.8, feed the evaluation back to the planner to generate corrective subtasks (e.g., "fix object count" or "adjust color balance"). Re-execute with the next-ranked tools. Limit to 5 iterations.
Update preference scores via APU. After execution, compare predicted ranking to actual quality ranking. For each dimension where a tool underperformed expectations, decrease its score; where it overperformed, increase it. Use exponential moving average: new_score = alpha * observed + (1-alpha) * old_score with alpha ~0.1-0.3.
Store experiences for retrieval. Log each completed task as an experience record: {tool_name, subtask, pre_tool, conditions, scores}. Use CLIP embeddings or text similarity to retrieve relevant past experiences when planning new tasks.
Feed updated preferences into planning (CAPO). When decomposing future tasks, the planner should consult updated tool scores to avoid generating subtasks that fall into weak capability regions. If no tool scores above 0.5 on a needed dimension, restructure the plan to work around that limitation.
Concrete Examples
Example 1: Building a multi-model image generation router
User: "I have access to FLUX, SDXL, and DALL-E APIs. Build a system that automatically picks the best model for each image generation request."
Approach:
- Define the tool registry with initial scores per capability dimension
- Build a FastAPI service with a
/generate endpoint
- Implement request analysis to extract dimension weights
- Compute ranked tool selection per request
- Execute with the top tool, evaluate output, update scores
Output structure:
# tool_registry.py
TOOL_SCORES = {
"flux": {
"color": 0.74, "shape": 0.57, "texture": 0.69,
"2d_spatial": 0.63, "3d_spatial": 0.45, "numeracy": 0.52,
"non_spatial": 0.92
},
"sdxl": {
"color": 0.81, "shape": 0.59, "texture": 0.73,
"2d_spatial": 0.61, "3d_spatial": 0.50, "numeracy": 0.48,
"non_spatial": 0.91
},
"dalle": {
"color": 0.78, "shape": 0.65, "texture": 0.71,
"2d_spatial": 0.58, "3d_spatial": 0.55, "numeracy": 0.60,
"non_spatial": 0.88
}
}
# selector.py
def select_tool(task_weights: dict[str, float], registry: dict) -> list[tuple[str, float]]:
"""Rank tools by preference-weighted score."""
rankings = []
for tool_name, scores in registry.items():
total = sum(scores.get(dim, 0) * w for dim, w in task_weights.items())
rankings.append((tool_name, total))
return sorted(rankings, key=lambda x: x[1], reverse=True)
# analyzer.py
def extract_task_weights(prompt: str) -> dict[str, float]:
"""Map prompt characteristics to dimension weights."""
weights = {dim: 0.1 for dim in DIMENSIONS} # baseline
if any(w in prompt.lower() for w in ["left", "right", "above", "below", "between"]):
weights["2d_spatial"] = 0.8
if any(w in prompt.lower() for w in ["three", "four", "five", "several", "many"]):
weights["numeracy"] = 0.8
if any(w in prompt.lower() for w in ["red", "blue", "green", "golden", "colorful"]):
weights["color"] = 0.6
# normalize
total = sum(weights.values())
return {k: v / total for k, v in weights.items()}
Example 2: Self-improving image editing pipeline with fallback
User: "Build an editing pipeline that tries multiple editing models and learns which works best for different edit types."
Approach:
- Define editing-specific dimensions: addition, removal, replacement, attribute_alter, style_transfer, background_change
- Implement the edit classifier to determine edit type from instruction
- Select top-2 tools, execute both, evaluate with multi-dimensional scoring
- Update tool preferences based on observed quality
- Persist updated scores to disk for future sessions
Output structure:
# evaluator.py
EVAL_DIMENSIONS = [
"object_category", "object_count", "positional_accuracy",
"attribute_binding", "style_match", "background_fidelity", "semantic_alignment"
]
TIER_SCORES = {"L1": 1.0, "L2": 0.66, "L3": 0.33}
def evaluate_output(original_prompt: str, image_path: str, llm_client) -> dict:
"""Score generated image across quality dimensions using VLM."""
scores = {}
for dim in EVAL_DIMENSIONS:
response = llm_client.evaluate(
image=image_path, prompt=original_prompt,
question=f"Rate {dim}: L1 (fully correct), L2 (partially), L3 (present but wrong)"
)
scores[dim] = TIER_SCORES.get(response.tier, 0.33)
non_semantic = [v for k, v in scores.items() if k != "semantic_alignment"]
composite = (sum(non_semantic) / len(non_semantic) + scores["semantic_alignment"]) / 2
return {"dimensions": scores, "composite": composite}
# updater.py
def update_preferences(tool_name: str, predicted_rank: int, actual_rank: int,
registry: dict, alpha: float = 0.2) -> dict:
"""APU: adjust scores when predicted vs actual rankings diverge."""
if predicted_rank != actual_rank:
adjustment = alpha * (predicted_rank - actual_rank) / max(predicted_rank, actual_rank)
for dim in registry[tool_name]:
registry[tool_name][dim] = max(0, min(1,
registry[tool_name][dim] + adjustment))
return registry
Example 3: Capability-aligned task decomposition
User: "I want to generate a complex scene: 'A medieval castle on a cliff at sunset with three knights on horseback in the foreground.' Break this into subtasks matched to the best available tools."
Approach:
- Analyze the prompt for required capabilities: 3d_spatial (cliff perspective), numeracy (three knights), texture (medieval materials), color (sunset lighting)
- Check tool registry for weak dimensions -- if no tool scores > 0.5 on numeracy, restructure to avoid relying on numeracy
- Decompose into capability-aligned subtasks
Output:
Plan (CAPO-aligned):
Subtask 1: Generate base scene "medieval castle on cliff at sunset"
-> Best tool: SDXL (high color: 0.81, texture: 0.73)
-> Avoids numeracy by not including knights yet
Subtask 2: Generate single knight on horseback as reference
-> Best tool: FLUX (high non_spatial: 0.92)
-> Generates one high-quality knight to use as reference
Subtask 3: Composite three knights into foreground using layout-guided generation
-> Best tool: Layout_to_Image (uses bounding boxes for placement)
-> Handles numeracy via explicit spatial layout rather than relying on model counting
Subtask 4: Harmonize lighting and style across composited image
-> Best tool: UltraEdit (style_transfer: 0.78)
-> Ensures consistent sunset lighting across all elements
Quality gate: Evaluate composite score after each subtask. Threshold: 0.8.
Retry budget: up to 5 rounds with fallback to next-ranked tools.
Best Practices
- Do: Benchmark tools empirically before populating the score registry. Run each tool on 50-100 diverse prompts spanning all capability dimensions. PerfGuard's value comes from accurate scores, not guesses.
- Do: Use parallel execution of top-N tools when latency budget allows. Comparing actual outputs is far more reliable than relying on scores alone, especially early in deployment.
- Do: Keep the APU learning rate (alpha) conservative (0.1-0.2). Aggressive updates cause score oscillation when evaluation is noisy.
- Do: Store experience records with CLIP embeddings of the prompt for fast semantic retrieval. Past task outcomes are the highest-signal input for planning.
- Avoid: Using the same weight vector for all tasks. The entire point of PASM is that different tasks stress different dimensions. A uniform weighting collapses back to a generic "best overall model" selection.
- Avoid: Skipping the evaluation step. Without measured output quality, APU cannot update preferences and the system cannot self-improve. Even a rough VLM-based evaluation (GPT-4V, Gemini) is better than none.
Error Handling
- Tool execution failure (timeout, OOM, API error): Assign a composite score of 0.0, fall through to the next-ranked tool immediately. Log the failure mode in the experience record.
- All top-N tools score below threshold: After exhausting the retry budget (5 rounds), return the best result achieved with a quality warning. Do not loop indefinitely.
- Evaluation model disagrees with human judgment: Periodically calibrate VLM evaluation scores against human ratings. If the evaluator is consistently wrong on a dimension, add dimension-specific calibration offsets.
- Score drift from APU: Implement score bounds (never below 0.05, never above 0.99) and add periodic score decay toward benchmark baselines to prevent runaway drift.
- New tool added to registry: Initialize scores at the population mean across all dimensions, then run a quick benchmark pass (20-30 prompts) to establish a real fingerprint before using in production routing.
Limitations
- Requires a vision-language model for evaluation. The multi-dimensional scoring system depends on a capable VLM (GPT-4V-class or better) to assess generated images. Without it, APU cannot function.
- Initial scores need manual effort. The system is only as good as its initial benchmarks. Cold-start with uniform scores will produce poor tool selection until enough APU iterations accumulate.
- Dimension taxonomy is domain-specific. The text-to-image and image-editing dimensions from the paper may not transfer directly to video generation, 3D, or audio. You must define appropriate axes for your domain.
- Does not model tool interactions. PASM scores tools independently. If two tools combined produce better results than either alone (e.g., generate + refine), this must be captured in the experience/planning layer, not in individual tool scores.
- Evaluation latency adds overhead. Running VLM evaluation after every generation step increases end-to-end latency. For real-time applications, consider batch evaluation or sampling strategies.
Reference
1---2name: perfguard-performance-aware-agent-visual3description: Performance-aware multi-tool orchestration for visual content generation pipelines. Implements PerfGuard's three mechanisms (PASM, APU, CAPO) to select, score, and schedule AI image/video tools based on measured capability boundaries instead of generic descriptions. Use when: "build a visual generation pipeline", "orchestrate multiple image tools", "select the best AI model for this image task", "score and rank generation tools", "adaptive tool selection for AIGC", "performance-aware tool routing".4---56# PerfGuard: Performance-Aware Agent for Visual Content Generation78This skill enables Claude to design and implement multi-tool orchestration systems for AI-generated visual content (AIGC) that select tools based on **measured performance boundaries** rather than static descriptions. Derived from the PerfGuard framework (ICLR 2026), the approach replaces the naive assumption that "all tools work equally well" with a structured scoring, ranking, and adaptive update system across three mechanisms: Performance-Aware Selection Modeling (PASM), Adaptive Preference Update (APU), and Capability-Aligned Planning Optimization (CAPO).910## When to Use1112- When the user is building a pipeline that routes tasks to multiple image generation or editing models (e.g., FLUX, SDXL, DALL-E, Midjourney APIs)13- When the user wants to automatically pick the best tool for a specific visual subtask (e.g., "which model handles spatial relationships better?")14- When the user needs a scoring/evaluation system for comparing AI-generated images across quality dimensions15- When the user asks to build a self-improving agent that learns which tools work best over time16- When the user wants to decompose complex visual tasks into subtasks matched to tool strengths17- When the user is implementing fallback/retry logic for visual generation where output quality is uncertain1819## Key Technique2021**The core insight:** Generic tool descriptions ("generates high-quality images") are useless for selection. PerfGuard replaces them with multi-dimensional performance scores measured on fine-grained capability axes. For text-to-image tools, these axes are: *color accuracy*, *shape fidelity*, *texture realism*, *2D spatial*, *3D spatial*, *numeracy* (correct object count), and *non-spatial semantics*. For image editing tools: *addition*, *removal*, *replacement*, *attribute alteration*, *motion change*, *style transfer*, and *background change*. Each tool gets a score (0.0-1.0) per dimension, producing a capability fingerprint.2223**Selection works by weighted dot product.** Given a task, the system identifies which dimensions matter (e.g., a request involving "three red cups arranged left to right" weights numeracy, color, and 2D-spatial heavily). The preference score for each candidate tool is `sum(tool.score[dim] * task.weight[dim])`. Tools are ranked by this score; the top-N candidates execute. Results are evaluated via a multi-dimensional quality assessment (object count, position, attributes, style, background, semantic alignment) scored at three levels (L1=1.0, L2=0.66, L3=0.33). If the composite score falls below a threshold (default 0.8), the system re-plans and retries with alternative tools.2425**The system learns from outcomes.** APU compares the predicted tool ranking against the actual quality ranking from execution. When discrepancies occur (predicted #1 actually performed worst), preference scores are updated. This closes the loop: the system gets better at tool selection over time without manual re-tuning. CAPO feeds these updated scores back into the planner, biasing subtask decomposition toward operations where strong tools exist rather than generating subtasks no tool can reliably handle.2627## Step-by-Step Workflow28291. **Define capability dimensions for your tool domain.** For text-to-image: `[color, shape, texture, 2d_spatial, 3d_spatial, numeracy, non_spatial]`. For image editing: `[addition, removal, replacement, attribute_alter, motion_change, style_transfer, background_change]`. For video or other domains, define analogous axes.30312. **Build a tool registry with performance scores.** For each tool, populate a score dictionary across all dimensions. Initialize from benchmarks or manual evaluation. Store as JSON:32 ```json33 {34 "flux": {"color": 0.74, "shape": 0.57, "texture": 0.69, "2d_spatial": 0.63, "numeracy": 0.52, "non_spatial": 0.92},35 "sd3": {"color": 0.81, "shape": 0.59, "texture": 0.73, "2d_spatial": 0.61, "numeracy": 0.48, "non_spatial": 0.91}36 }37 ```38393. **Implement the task analyzer (Analyst role).** Parse user requests to extract: the task type (generation vs. editing), target objects, spatial relationships, style requirements, and reference images. Output a structured goal representation.40414. **Implement dimension weight extraction.** From the analyzed task, compute a weight vector over capability dimensions. A task mentioning "three objects arranged in a grid" gets high weights on `numeracy` and `2d_spatial`. A style-transfer edit gets high weight on `style_transfer`. Use an LLM to classify or use keyword/rule-based mapping.42435. **Compute preference-weighted tool rankings.** For each candidate tool, calculate: `score = sum(tool_scores[dim] * task_weights[dim] for dim in dimensions)`. Sort tools descending by score. Select top-N (typically 2-3) for parallel execution.44456. **Execute and evaluate results.** Run selected tools. Score each output on evaluation dimensions: object category/count correctness, positional accuracy, attribute binding, style match, background fidelity, overall semantic alignment. Use three-tier scoring (L1=1.0 fully correct, L2=0.66 partially correct, L3=0.33 present but wrong). Composite score = `(mean(non_semantic_dims) + semantic_score) / 2`.46477. **Apply the quality threshold and retry loop.** If the best output scores below 0.8, feed the evaluation back to the planner to generate corrective subtasks (e.g., "fix object count" or "adjust color balance"). Re-execute with the next-ranked tools. Limit to 5 iterations.48498. **Update preference scores via APU.** After execution, compare predicted ranking to actual quality ranking. For each dimension where a tool underperformed expectations, decrease its score; where it overperformed, increase it. Use exponential moving average: `new_score = alpha * observed + (1-alpha) * old_score` with alpha ~0.1-0.3.50519. **Store experiences for retrieval.** Log each completed task as an experience record: `{tool_name, subtask, pre_tool, conditions, scores}`. Use CLIP embeddings or text similarity to retrieve relevant past experiences when planning new tasks.525310. **Feed updated preferences into planning (CAPO).** When decomposing future tasks, the planner should consult updated tool scores to avoid generating subtasks that fall into weak capability regions. If no tool scores above 0.5 on a needed dimension, restructure the plan to work around that limitation.5455## Concrete Examples5657**Example 1: Building a multi-model image generation router**5859User: "I have access to FLUX, SDXL, and DALL-E APIs. Build a system that automatically picks the best model for each image generation request."6061Approach:621. Define the tool registry with initial scores per capability dimension632. Build a FastAPI service with a `/generate` endpoint643. Implement request analysis to extract dimension weights654. Compute ranked tool selection per request665. Execute with the top tool, evaluate output, update scores6768Output structure:69```python70# tool_registry.py71TOOL_SCORES = {72 "flux": {73 "color": 0.74, "shape": 0.57, "texture": 0.69,74 "2d_spatial": 0.63, "3d_spatial": 0.45, "numeracy": 0.52,75 "non_spatial": 0.9276 },77 "sdxl": {78 "color": 0.81, "shape": 0.59, "texture": 0.73,79 "2d_spatial": 0.61, "3d_spatial": 0.50, "numeracy": 0.48,80 "non_spatial": 0.9181 },82 "dalle": {83 "color": 0.78, "shape": 0.65, "texture": 0.71,84 "2d_spatial": 0.58, "3d_spatial": 0.55, "numeracy": 0.60,85 "non_spatial": 0.8886 }87}8889# selector.py90def select_tool(task_weights: dict[str, float], registry: dict) -> list[tuple[str, float]]:91 """Rank tools by preference-weighted score."""92 rankings = []93 for tool_name, scores in registry.items():94 total = sum(scores.get(dim, 0) * w for dim, w in task_weights.items())95 rankings.append((tool_name, total))96 return sorted(rankings, key=lambda x: x[1], reverse=True)9798# analyzer.py99def extract_task_weights(prompt: str) -> dict[str, float]:100 """Map prompt characteristics to dimension weights."""101 weights = {dim: 0.1 for dim in DIMENSIONS} # baseline102 if any(w in prompt.lower() for w in ["left", "right", "above", "below", "between"]):103 weights["2d_spatial"] = 0.8104 if any(w in prompt.lower() for w in ["three", "four", "five", "several", "many"]):105 weights["numeracy"] = 0.8106 if any(w in prompt.lower() for w in ["red", "blue", "green", "golden", "colorful"]):107 weights["color"] = 0.6108 # normalize109 total = sum(weights.values())110 return {k: v / total for k, v in weights.items()}111```112113**Example 2: Self-improving image editing pipeline with fallback**114115User: "Build an editing pipeline that tries multiple editing models and learns which works best for different edit types."116117Approach:1181. Define editing-specific dimensions: addition, removal, replacement, attribute_alter, style_transfer, background_change1192. Implement the edit classifier to determine edit type from instruction1203. Select top-2 tools, execute both, evaluate with multi-dimensional scoring1214. Update tool preferences based on observed quality1225. Persist updated scores to disk for future sessions123124Output structure:125```python126# evaluator.py127EVAL_DIMENSIONS = [128 "object_category", "object_count", "positional_accuracy",129 "attribute_binding", "style_match", "background_fidelity", "semantic_alignment"130]131TIER_SCORES = {"L1": 1.0, "L2": 0.66, "L3": 0.33}132133def evaluate_output(original_prompt: str, image_path: str, llm_client) -> dict:134 """Score generated image across quality dimensions using VLM."""135 scores = {}136 for dim in EVAL_DIMENSIONS:137 response = llm_client.evaluate(138 image=image_path, prompt=original_prompt,139 question=f"Rate {dim}: L1 (fully correct), L2 (partially), L3 (present but wrong)"140 )141 scores[dim] = TIER_SCORES.get(response.tier, 0.33)142143 non_semantic = [v for k, v in scores.items() if k != "semantic_alignment"]144 composite = (sum(non_semantic) / len(non_semantic) + scores["semantic_alignment"]) / 2145 return {"dimensions": scores, "composite": composite}146147# updater.py148def update_preferences(tool_name: str, predicted_rank: int, actual_rank: int,149 registry: dict, alpha: float = 0.2) -> dict:150 """APU: adjust scores when predicted vs actual rankings diverge."""151 if predicted_rank != actual_rank:152 adjustment = alpha * (predicted_rank - actual_rank) / max(predicted_rank, actual_rank)153 for dim in registry[tool_name]:154 registry[tool_name][dim] = max(0, min(1,155 registry[tool_name][dim] + adjustment))156 return registry157```158159**Example 3: Capability-aligned task decomposition**160161User: "I want to generate a complex scene: 'A medieval castle on a cliff at sunset with three knights on horseback in the foreground.' Break this into subtasks matched to the best available tools."162163Approach:1641. Analyze the prompt for required capabilities: 3d_spatial (cliff perspective), numeracy (three knights), texture (medieval materials), color (sunset lighting)1652. Check tool registry for weak dimensions -- if no tool scores > 0.5 on numeracy, restructure to avoid relying on numeracy1663. Decompose into capability-aligned subtasks167168Output:169```170Plan (CAPO-aligned):171 Subtask 1: Generate base scene "medieval castle on cliff at sunset"172 -> Best tool: SDXL (high color: 0.81, texture: 0.73)173 -> Avoids numeracy by not including knights yet174175 Subtask 2: Generate single knight on horseback as reference176 -> Best tool: FLUX (high non_spatial: 0.92)177 -> Generates one high-quality knight to use as reference178179 Subtask 3: Composite three knights into foreground using layout-guided generation180 -> Best tool: Layout_to_Image (uses bounding boxes for placement)181 -> Handles numeracy via explicit spatial layout rather than relying on model counting182183 Subtask 4: Harmonize lighting and style across composited image184 -> Best tool: UltraEdit (style_transfer: 0.78)185 -> Ensures consistent sunset lighting across all elements186187Quality gate: Evaluate composite score after each subtask. Threshold: 0.8.188Retry budget: up to 5 rounds with fallback to next-ranked tools.189```190191## Best Practices192193- **Do:** Benchmark tools empirically before populating the score registry. Run each tool on 50-100 diverse prompts spanning all capability dimensions. PerfGuard's value comes from accurate scores, not guesses.194- **Do:** Use parallel execution of top-N tools when latency budget allows. Comparing actual outputs is far more reliable than relying on scores alone, especially early in deployment.195- **Do:** Keep the APU learning rate (alpha) conservative (0.1-0.2). Aggressive updates cause score oscillation when evaluation is noisy.196- **Do:** Store experience records with CLIP embeddings of the prompt for fast semantic retrieval. Past task outcomes are the highest-signal input for planning.197- **Avoid:** Using the same weight vector for all tasks. The entire point of PASM is that different tasks stress different dimensions. A uniform weighting collapses back to a generic "best overall model" selection.198- **Avoid:** Skipping the evaluation step. Without measured output quality, APU cannot update preferences and the system cannot self-improve. Even a rough VLM-based evaluation (GPT-4V, Gemini) is better than none.199200## Error Handling201202- **Tool execution failure (timeout, OOM, API error):** Assign a composite score of 0.0, fall through to the next-ranked tool immediately. Log the failure mode in the experience record.203- **All top-N tools score below threshold:** After exhausting the retry budget (5 rounds), return the best result achieved with a quality warning. Do not loop indefinitely.204- **Evaluation model disagrees with human judgment:** Periodically calibrate VLM evaluation scores against human ratings. If the evaluator is consistently wrong on a dimension, add dimension-specific calibration offsets.205- **Score drift from APU:** Implement score bounds (never below 0.05, never above 0.99) and add periodic score decay toward benchmark baselines to prevent runaway drift.206- **New tool added to registry:** Initialize scores at the population mean across all dimensions, then run a quick benchmark pass (20-30 prompts) to establish a real fingerprint before using in production routing.207208## Limitations209210- **Requires a vision-language model for evaluation.** The multi-dimensional scoring system depends on a capable VLM (GPT-4V-class or better) to assess generated images. Without it, APU cannot function.211- **Initial scores need manual effort.** The system is only as good as its initial benchmarks. Cold-start with uniform scores will produce poor tool selection until enough APU iterations accumulate.212- **Dimension taxonomy is domain-specific.** The text-to-image and image-editing dimensions from the paper may not transfer directly to video generation, 3D, or audio. You must define appropriate axes for your domain.213- **Does not model tool interactions.** PASM scores tools independently. If two tools combined produce better results than either alone (e.g., generate + refine), this must be captured in the experience/planning layer, not in individual tool scores.214- **Evaluation latency adds overhead.** Running VLM evaluation after every generation step increases end-to-end latency. For real-time applications, consider batch evaluation or sampling strategies.215216## Reference217218- **Paper:** [PerfGuard: A Performance-Aware Agent for Visual Content Generation](https://arxiv.org/abs/2601.22571v1) (ICLR 2026)219- **Code:** [github.com/FelixChan9527/PerfGuard](https://github.com/FelixChan9527/PerfGuard)220- **What to look for:** Section 3 details PASM scoring dimensions and the preference-weighted selection formula; Section 4 covers the APU update mechanism with predicted-vs-actual rank comparison; Section 5 describes CAPO's planner integration. The experience replay system using CLIP embeddings is in Section 3.3.