| name | evidence-visualization |
| description | Meta-model-agent 将计算成果转换为可发表的数据图形、表格和排版引用。适用于证据图谱构建。 |
证据图谱构建
稳定执行契约
- 执行目标:把已冻结的计算结果转换为可核验、可复用、可直接入文的图形与表格证据。
- 调用参数:[visual-plan-or-data-path]。
- 权威输入:计算结果.md、图表/全部结果.json、逐问结果文件与用户图表要求。
- 允许交付:图表/中的数据图、表格和图表引用.tex;不得改写上游数值。
- 禁止写入:不得越权修改已冻结的上游事实、用户原始文件或本协议未授权的目录。
- 可用工具边界:Bash(*), Read, Write, Edit, Grep, Glob, Agent。
- 最小交付:每项核心结论至少有匹配的图或表、可追溯数据源、中文标注与论文引用入口。
- 恢复入口:优先读取当前工作、状态记录和已有产物,从最近一次通过门禁的位置继续。
- 失败回退:缺少结果或口径冲突时停止绘图并回退计算实现;不得臆造数据补齐视觉效果。
- 收口顺序:先核对输入,再完成产物,再运行本环节门禁,最后登记状态;门禁未通过不得宣告完成。
Produce visuals and tables from data: $ARGUMENTS
运行参数
-
FIG_DIR = 图表/
-
FORMAT = pdf (vector, suitable for LaTeX)
-
DPI = 300
-
CUSTOM_REQUIREMENTS — User-specified requirements, highest priority.
<tools_and_style>
工具与表达规范
shared-scripts/plot_utils.py 提供学术绘图的基础样式。Meta-model-agent 可按任务需要选用其中的辅助函数、仅调用 setup_style() 后直接使用 matplotlib,或完全采用自定义实现。
Quality floor: 300 DPI PDF, no in-visual title (plt.title), font ≥9pt, grayscale-distinguishable.
Color palette and recipes: read 工具/figure_style_guide.md (color schemes) and 工具/figure_recipes_*.md (implementation examples).
plot_utils functions: setup_style, save_fig, heatmap, forest_plot, trend_plot, bar_compare, distribution_plot, scatter_plot, residual_diagnostic, multi_line_plot, box_plot, radar_plot, subplot_grid
Stats tables: stats_utils.py supplies regression_table, descriptive_table, correlation_table.
</tools_and_style>
⛔⛔⛔ 交付契约(最高优先级)
除 图表/图表引用.tex 外,必须生成 图表/figure_manifest.json。每张图登记 path、claim、source、reader_task、publish 和 placement。只有 publish=true 的图必须嵌入正文;诊断图、调试图和被替代的图应登记为 publish=false,不得为了覆盖文件而挤入正文。
{
"version": 1,
"figures": [
{
"path": "图表/fig_q1_sensitivity.pdf",
"claim": "参数扰动不改变最优方案排序",
"source": "图表/全部结果.json",
"reader_task": "比较趋势与稳定区间",
"publish": true,
"placement": "body"
}
]
}
Must produce all planned visuals (per 论文规划.md or skill-specific plan) as 图表/fig_*.png/pdf plus 图表/图表引用.tex (or, in docx mode, the same PNGs without 图表引用.tex requirement).
⛔ 特殊豁免:若 论文规划.md 清晰标明写"无图形与表格"或图形与表格清单为空(纯文字综述/思辨论文),准许 图表/ 为空,但务必写一个空的 图表/图表引用.tex (touch 图表/图表引用.tex; mkdir -p 图表) 让下游知道这步跑过了。
⛔ MUST run output verification prior to ending:
PASS=true
mkdir -p 图表
FIG_PNG=$(ls 图表/fig_*.png 2>/dev/null | wc -l)
FIG_PDF=$(ls 图表/fig_*.pdf 2>/dev/null | wc -l)
TOTAL=$((FIG_PNG + FIG_PDF))
PLAN_HAS_FIG=$(grep -E '^\s*-?\s*fig_|图表清单|图表/fig_' 论文规划.md 2>/dev/null | wc -l)
if [ "$TOTAL" -ge 1 ]; then
echo "✅ 图表/fig_*.png/pdf ($TOTAL)"
elif [ "$PLAN_HAS_FIG" -eq 0 ]; then
echo "✓ 规划无图表, 创建占位 图表引用.tex"
touch 图表/图表引用.tex
else
echo "❌ 规划要求图表但未生成"
PASS=false
fi
MODE=$(grep -q "Word(.docx)\|docx mode" META_MODEL_AGENT.md 2>/dev/null && echo docx || echo pdf)
if [ "$MODE" = "pdf" ] && [ ! -f 图表/图表引用.tex ]; then
touch 图表/图表引用.tex
fi
[ "$PASS" != true ] && echo "⛔ Output verification FAILED — must complete before ending"
执行流程
工作节点 0:恢复核验(断线重跑必读)
⛔ 当前环节可能由于断线/人工重跑被多次启动。每一次启动前务必先扫描已有产物:
echo "=== 工作区扫描 ==="
HAS_PNG=$(ls 图表/fig_*.png 2>/dev/null | wc -l)
HAS_PDF=$(ls 图表/fig_*.pdf 2>/dev/null | wc -l)
HAS_TIKZ=$(ls 图表/tikz_*.pdf 2>/dev/null | wc -l)
HAS_INCLUDES=$([ -f 图表/图表引用.tex ] && wc -c < 图表/图表引用.tex || echo 0)
echo " fig_*.png: $HAS_PNG, fig_*.pdf: $HAS_PDF, tikz_*.pdf: $HAS_TIKZ"
echo " 图表引用.tex: $HAS_INCLUDES bytes"
依据扫描结果决定行动:
| 运行状态 | 行动 |
|---|---|
| 满足 论文规划.md 中规划的图形与表格数(不少于规划) + 图表引用.tex 出现 | 跳到 Phase 9 (count verification) 校验,校验通过即完成 |
| 已有部分图但少于规划数 | 只产出缺失的图(已出现的图避免重画) |
| 图表引用.tex 缺失但图都在 | 只产出 Phase 6 的 图表引用.tex |
| 啥都没有 | 从 Phase 1 启动 |
⛔ 铁律:
工作节点 1:Read manuscript structure + data discovery
- Consult the full style guide (color schemes + visual selection decision table + anti-patterns + DrawIO/TikZ color schemes — all in one file):
cat 工具/figure_style_guide.md 2>/dev/null || cat skills/shared-scripts/figure_style_guide.md
- Scan recipe file headings to know what templates are available:
echo "=== Advanced ==="
(cat 工具/figure_recipes_advanced.md 2>/dev/null || cat skills/shared-scripts/figure_recipes_advanced.md 2>/dev/null) | grep '^## '
echo "=== Basic ==="
(cat 工具/figure_recipes_basic.md 2>/dev/null || cat skills/shared-scripts/figure_recipes_basic.md 2>/dev/null) | grep '^## '
echo "=== Academic ==="
(cat 工具/figure_recipes_academic.md 2>/dev/null || cat skills/shared-scripts/figure_recipes_academic.md 2>/dev/null) | grep '^## '
echo "=== Competition ==="
(cat 工具/figure_recipes_competition.md 2>/dev/null || cat skills/shared-scripts/figure_recipes_competition.md 2>/dev/null) | grep '^## '
echo "=== Empirical ==="
(cat 工具/figure_recipes_empirical.md 2>/dev/null || cat skills/shared-scripts/figure_recipes_empirical.md 2>/dev/null) | grep '^## '
echo "=== Basic (fallback only) ==="
(cat 工具/figure_recipes_basic.md 2>/dev/null || cat skills/shared-scripts/figure_recipes_basic.md 2>/dev/null) | grep '^## '
- ⛔ MANDATORY: Extract the COMPLETE visual plan from planning docs. Read ALL planning docs and extract every planned visual/table into a numbered checklist:
echo "=== Extracting figure plan ==="
for plan in 论文规划.md 问题分析.md 选题规划.md 建模报告.md; do
[ -f "$plan" ] || continue
echo "--- $plan ---"
cat "$plan"
done
Following reading, output a FIGURE PLAN CHECKLIST like this (you MUST produce this prior to proceeding):
FIGURE PLAN CHECKLIST (from planning docs):
[ ] 1. fig_xxx — Descriptive stats distribution (Rain Cloud) — data: results.json
[ ] 2. fig_yyy — Model comparison radar (Radar) — data: results.json
[ ] 3. fig_zzz — Regression coefficient forest plot (Forest Plot) — data: results.json
[ ] 4. TABLE_desc — Descriptive statistics table — data: results.json
[ ] 5. TABLE_reg — Regression results table — data: results.json
[ ] 6. drawio_roadmap — Technical roadmap (DrawIO)
Total planned: 6 figures + 2 tables + 1 DrawIO
Every item in the plan MUST appear in this checklist. If the plan says "12 visuals", the checklist is expected to include 12 entries.
3.5. ⛔ JSON 数据完整性核验(保证数据能支撑全部图形与表格):
echo "=== JSON 数据完整性检查 ==="
if [ -f 图表/全部结果.json ]; then
python3 -c "
import json
with open('图表/全部结果.json', 'r') as f:
data = json.load(f)
# 列出所有顶层 key
keys = list(data.keys()) if isinstance(data, dict) else [f'[{i}]' for i in range(min(len(data), 10))]
print(f'JSON 顶层 key ({len(keys)} 个): {keys}')
# 检查是否有空值
def verify_empty(obj, path=''):
issues = []
if isinstance(obj, dict):
for k, v in obj.items():
if v is None or v == '' or v == []:
issues.append(f'{path}.{k} 为空')
else:
issues.extend(verify_empty(v, f'{path}.{k}'))
elif isinstance(obj, list) and len(obj) == 0:
issues.append(f'{path} 为空列表')
return issues
issues = verify_empty(data)
if issues:
print(f'⚠ 发现 {len(issues)} 个空值:')
for i in issues[:5]:
print(f' - {i}')
else:
print('✅ JSON 数据无空值')
" 2>/dev/null
else
echo "⚠ 图表/全部结果.json 不存在,图表将缺少数据支撑"
fi
for f in 图表/problem_*_结果.json; do
[ -f "$f" ] && echo "✅ $(basename $f) 存在" || true
done
- Scan data files (
用户数据/ > 图表/ > root). ⛔ 避免 cat 或 print() 全部 JSON 文件——大 JSON 会撑爆上下文。 只用以下方式扫描:
ls -la 图表/*.json 2>/dev/null
python3 -c "
import json, os
def summarize(v, depth=0):
if isinstance(v, list):
n = len(v)
nulls = sum(1 for x in v if x is None)
nums = [x for x in v if isinstance(x, (int,float)) and x is not None]
if nums:
return f'list[{n}] nulls={nulls} range=[{min(nums):.4g}, {max(nums):.4g}] sample={v[:3]}'
elif v and isinstance(v[0], dict):
return f'list[{n}] of dict, keys={list(v[0].keys())[:8]}'
return f'list[{n}] sample={str(v[:3])[:100]}'
elif isinstance(v, dict) and depth < 2:
items = []
for k2, v2 in list(v.items())[:6]:
items.append(f'{k2}: {summarize(v2, depth+1)}')
return 'dict{' + ', '.join(items) + '}'
return f'{type(v).__name__}={str(v)[:60]}'
for f in sorted(os.listdir('图表')):
if not f.endswith('.json'): continue
sz = os.path.getsize(f'图表/{f}')
with open(f'图表/{f}') as fh: d = json.load(fh)
print(f'\n=== {f} ({sz//1024}KB) ===')
if isinstance(d, dict):
for k, v in list(d.items())[:10]:
print(f' {k}: {summarize(v)}')
elif isinstance(d, list):