AskSage Multi-Model Review — Comprehensive Reference
Skill location: ~/.claude/skills/asksage-review/SKILL.md Scripts: asksage_review.py (code review), batch_review.py (batch multi-model review) — both ship in my asksage helper repo.
1. Architecture Overview
The AskSage review system has two components:
asksage_review.py— Single-model code review. Takes a file or directory, builds a txtarchive, sends to one AskSage model, returns the review.batch_review.py— Multi-model analysis review. Takes a directory of markdown/text files, sends each to multiple LLM models, saves per-model reviews.
Both use the asksageclient Python package and load credentials from ~/.config/asksage/credentials.env.
2. Authentication & Credentials
Credential File
# ~/.config/asksage/credentials.env
ASKSAGE_EMAIL=user@example.com
ASKSAGE_API_KEY=your_api_key_here
Loading Pattern
from pathlib import Path
import os
cred_file = Path.home() / ".config" / "asksage" / "credentials.env"
for line in cred_file.read_text().splitlines():
line = line.strip()
if line and not line.startswith("#") and "=" in line:
key, _, value = line.partition("=")
os.environ[key.strip()] = value.strip().strip('"')Client Initialization
from asksageclient import AskSageClient
client = AskSageClient(
email=os.environ["ASKSAGE_EMAIL"],
api_key=os.environ["ASKSAGE_API_KEY"],
)Security Rules
- NEVER commit
credentials.envto version control - NEVER print or log API keys in script output
- Always load from environment variables or credential file
.gitignoremust covercredentials.envand*.env
3. API Reference
client.query()
The primary method for sending prompts to models.
response = client.query(
message=full_prompt, # str — the full prompt text
model="google-claude-46-opus", # str — model identifier
temperature=0.0, # float — 0.0 for deterministic reviews
dataset="none", # str — "none" for no RAG dataset
)
review_text = response.get("message", "No response received.")client.get_models()
List available models on the platform.
response = client.get_models()
models = sorted(response.get("response", []))Available Models (as of 2026-03)
| Model ID | Short Name | Notes |
|---|---|---|
google-claude-46-opus |
claude-opus | Anthropic’s strongest model |
gpt-5.2 |
gpt5 | OpenAI’s flagship multimodal |
xai-grok |
grok | xAI Grok, detailed analysis |
google-gemini-2.5-pro |
gemini | Google’s latest, long context |
Use --list-models with asksage_review.py for the current full list.
4. Full Pipeline: HTML → Markdown → Multi-Model Reviews → Synthesis
Step 1: Render Analysis to HTML
# Quarto notebook
quarto render analysis.qmd --to html
# Jupyter notebook (outputs preserved, no re-execution)
quarto render analysis.ipynb --to htmlStep 2: Convert HTML to Markdown
# Basic conversion
pandoc analysis.html -t markdown --wrap=none -o analysis.md
# With media extraction (preserves plot descriptions)
pandoc analysis.html -t markdown --wrap=none --extract-media=./media -o analysis.mdWhy markdown? HTML is too token-heavy for LLM context windows. Pandoc markdown preserves tables, headings, and alt-text from plots while reducing size by ~80%.
Step 3: Send to Multiple Models
# Using batch_review.py
python batch_review.py ./markdown_dir/ ./reviews/
# Or per-file with asksage_review.py
python asksage_review.py analysis.md --model google-claude-46-opus -o review-claude.md
python asksage_review.py analysis.md --model gpt-5.2 -o review-gpt5.md
python asksage_review.py analysis.md --model xai-grok -o review-grok.md
python asksage_review.py analysis.md --model google-gemini-2.5-pro -o review-gemini.mdStep 4: Synthesize Cross-Model Reviews
After collecting reviews, synthesize into a single document covering:
- Consensus findings — points where 3+ models agree
- Unique insights — points raised by only one model
- Disagreements — where models contradict each other
- Priority recommendations — ranked by frequency across models
- Model-specific strengths — which model caught what others missed
5. Prompt Templates
5.1 Clinical/Epidemiological Analysis Review (7-Point)
You are a clinical epidemiologist specializing in {DOMAIN}. You are reviewing
the RESULTS of {ANALYSIS_DESCRIPTION}.
Please provide a detailed analysis addressing these 7 points:
1. **Model Performance**: Interpret the ROC AUC, sensitivity, specificity,
Brier scores, and calibration results. Are these clinically meaningful?
How does the model perform across train/test/external validation?
2. **Variable Importance & SHAP Analysis**: What are the most important
predictors? Do the SHAP values make clinical sense? Any surprising findings?
3. **Clinical Implications**: What does this analysis mean for patients?
How should clinicians use these predictions?
4. **Methodological Strengths & Weaknesses**: Evaluate the analytical approach.
What was done well? What are the limitations?
5. **Data Quality Concerns**: Are there any red flags in the data that affect
the conclusions?
6. **Single Most Important Clinical or Policy Takeaway**: What is the ONE
finding that matters most?
7. **Recommended Next Steps**: What should the research team do next?
Here are the analysis results:
5.2 Code Review (Single File)
Review this code. Focus on:
1. Code quality and best practices
2. Security concerns
3. Error handling
4. Suggestions for improvement
5.3 Package/Project Review
You are reviewing a software project. Provide a thorough code review covering:
1. Package architecture and design patterns
2. Code quality, readability, and idiomatic usage
3. Error handling and edge cases
4. Test coverage assessment
5. Security concerns
6. Performance considerations
7. Documentation quality
8. Top 5 priority improvements
5.4 General Analysis Review
You are an expert data scientist reviewing the results of an analysis.
Please provide a detailed review covering:
1. **Results Interpretation**: Are the findings sound? Any statistical concerns?
2. **Methodology**: Evaluate the analytical approach, assumptions, and
appropriateness of methods chosen.
3. **Visualizations**: Are the plots clear, appropriate, and correctly labeled?
4. **Limitations**: What caveats should accompany these results?
5. **Recommended Next Steps**: What should be done next?
Here are the analysis results:
6. CLI Reference
asksage_review.py
usage: asksage_review.py [-h] [--model MODEL] [--prompt PROMPT]
[--list-models] [--temperature TEMP]
[--output OUTPUT] [path]
Send code to any AskSage model for review.
positional arguments:
path File or directory to review
options:
--model, -m MODEL AskSage model (default: xai-grok)
--prompt, -p PROMPT Custom review prompt (replaces default)
--list-models List available models and exit
--temperature, -t Model temperature (default: 0.0)
--output, -o OUTPUT Save review to file instead of printing
batch_review.py
usage: batch_review.py [-h] [--models MODELS] [--prompt PROMPT]
[--prompt-file FILE] [--config CONFIG]
[--temperature TEMP] [--pattern PATTERN]
input_dir output_dir
Batch send files to multiple AskSage models for review.
positional arguments:
input_dir Directory containing files to review
output_dir Directory for review output files
options:
--models MODELS Comma-separated model list
(default: google-claude-46-opus,gpt-5.2,xai-grok,google-gemini-2.5-pro)
--prompt PROMPT Review prompt (prepended to file content)
--prompt-file FILE Read prompt from a file
--config CONFIG YAML config with per-file prompts
--temperature TEMP Model temperature (default: 0.0)
--pattern PATTERN Glob pattern for input files (default: *.md)
7. YAML Configuration Format
For per-analysis custom prompts, create a YAML config:
# review_config.yaml
# Default prompt used when an analysis has no custom prompt
default_prompt: |
You are an expert reviewing analysis results.
Please provide a detailed review covering methodology,
results interpretation, limitations, and next steps.
# Per-analysis overrides
analyses:
340-analysis.md:
title: "Adolescent SCD Organ Damage"
prompt: |
You are a clinical epidemiologist specializing in sickle cell disease.
Review this analysis of adolescent organ damage patterns...
345-analysis.md:
title: "ML Mortality Pipeline"
prompt: |
You are a biostatistician reviewing a machine learning mortality
prediction pipeline...
360-analysis.md:
title: "CKD Nephropathy Analysis"
# No custom prompt — uses default_prompt8. Output Organization
reviews/
├── {filename}-review-claude-opus.md
├── {filename}-review-gpt5.md
├── {filename}-review-grok.md
├── {filename}-review-gemini.md
└── {filename}-synthesis.md # Cross-model synthesis (manual)
The filename stem (without extension) is used as the analysis identifier. Review files are named {stem}-review-{model_short}.md.
9. Troubleshooting
Authentication Failures (401)
Check:
1. credentials.env has correct email and API key
2. API key has not expired
3. Account is active: log in at asksage.ai web UI
Rate Limits (429)
AskSage rate limits vary by account tier.
- Wait and retry (batch_review.py does not auto-retry)
- Reduce parallelism
- Contact AskSage support for limit increases
Token Limits
If prompt + content exceeds model context window:
- Use pandoc to convert HTML (smaller than raw HTML)
- Truncate or summarize long analyses
- Split into sections and review separately
Empty or Short Reviews
If response.get("message") is very short:
- Check that the prompt + content was not truncated
- Try a different model (some handle long context better)
- Verify the model ID is correct (use --list-models)
Model Not Found
- Run: python asksage_review.py --list-models
- Model IDs change as AskSage updates their platform
- Common current IDs: google-claude-46-opus, gpt-5.2, xai-grok, google-gemini-2.5-pro
10. Example: Batch Review Script Template
"""Batch review template — customize for your project."""
import os
import sys
from pathlib import Path
# Load credentials
cred_file = Path.home() / ".config" / "asksage" / "credentials.env"
for line in cred_file.read_text().splitlines():
line = line.strip()
if line and not line.startswith("#") and "=" in line:
key, _, value = line.partition("=")
os.environ[key.strip()] = value.strip().strip('"')
from asksageclient import AskSageClient
client = AskSageClient(
email=os.environ["ASKSAGE_EMAIL"],
api_key=os.environ["ASKSAGE_API_KEY"],
)
MODELS = [
("google-claude-46-opus", "claude-opus"),
("xai-grok", "grok"),
("gpt-5.2", "gpt5"),
("google-gemini-2.5-pro", "gemini"),
]
PROMPT = """Your review prompt here.
Here are the analysis results:
"""
input_dir = Path("./markdown_files")
output_dir = Path("./reviews")
output_dir.mkdir(exist_ok=True)
for md_file in sorted(input_dir.glob("*.md")):
content = md_file.read_text()
full_prompt = PROMPT + content
stem = md_file.stem
print(f"\n{'='*60}")
print(f"Reviewing: {md_file.name} ({len(full_prompt):,} chars)")
print(f"{'='*60}")
for model_id, model_short in MODELS:
output_file = output_dir / f"{stem}-review-{model_short}.md"
if output_file.exists() and output_file.stat().st_size > 100:
print(f" SKIP {model_short}: already exists")
continue
print(f" Sending to {model_id}...", end=" ", flush=True)
try:
response = client.query(
message=full_prompt,
model=model_id,
temperature=0.0,
dataset="none",
)
review = response.get("message", "No response received.")
output_file.write_text(review)
print(f"OK ({len(review):,} chars)")
except Exception as e:
print(f"FAILED: {e}")
print(f"\nReviews saved to {output_dir}/")