# Table Format Alignment

> 表格答案格式与行集合对齐总则：行身份双表示、行宇宙精确率校准、数值单位契约、多值与取值约束、规则文本阈值保留、合成前对齐自检

- Skill: `antins-labs/table-format-alignment` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add antins-labs/table-format-alignment`
- Raw SKILL.md: https://api.skillmd.com/api/skills/antins-labs/table-format-alignment/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: antins-labs (https://skillmd.com/u/antins-labs)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/antins-labs/table-format-alignment

---

# 表格答案格式对齐总则

表格任务的行得分逻辑是：行身份先对上 → 行内每一列都对 → 行集合还要齐。内容找对了但**表示法、口径、粒度、覆盖**与提问方预期不一致，得分等于零。本 playbook 的原则：凡是存在多种合理表示的地方，不猜对方要哪种——**要么双写，要么遵循源页面的主流写法，并把规则固化进 schema**。

## 一、行身份列：多表示并存时，全都要

行身份列（primary key 里的列）是 merge 的钥匙，表示法错一个字整行作废。

1. **识别**：explore 或首批页面里，同一个行身份概念出现两种以上等价写法——编号↔文字（站点代码"PVG"↔"浦东国际机场"）、缩写↔全称、代际编号↔商品名、不同年份页面写法不一致——即触发本节。
2. **双列采集**：两种表示都建为 schema 列。必需属性校验只认其中一个名字时，以它为主列，另一种作伴生列；**绝不为通过校验删掉任何一种表示**。
3. **对照表**：当映射关系是一张独立小字典（编号→含义），建第三张映射表（PK=编号，列=文字表示），并立刻用 `link_tables` 声明主表.编号 → 映射表.编号 的 relation——不声明 relation，最终渲染不会 join。
4. **采集契约**：column_desc 写明"源页面同时给出编号与文字时两者都记录"，dispatch 任务文本同样写明，防止子代理只抄较短的一列。
5. **输出双写**：最终单元格写 `文字表示（编号）`。编号脱离上下文不可解释，只输出编号是最脆的选择。

## 二、行宇宙：基数要双向校准，多出的行和漏掉的行一样致命

行得分是精确率与召回率的 F1，且每行要全列都命中才计数。**多收一批不该有的行直接拉低精确率，与漏行一样砍掉 row_f1。** 不要把"宁多勿漏"当免责：多出来的行若不在合成前清掉，就是实打实的扣分。

1. 穷举类任务先找**目录型权威页**（官方列表/索引/年报附表）确定行基数量级，再开始填列。没有基数的枚举，漏掉一半行也毫无感知。
2. 从 query 显式推导**变体收录规则**并写进 dispatch 任务：衍生型号/区域版本/联合项目/克隆品算不算独立行？粒度是"对象"还是"对象×版本"？规则不明时先按细粒度收集，**但合成前必须按 query 的限定词跑一遍 scope-filter，把超出范围的行剔除**（query 限定了某家族/某地区/某榜单，就只保留严格属于该范围的实体；旁系、衍生、近义实体一律删）。
3. **合成前去重 + 范围复核（强制）**：(a) 同一实体的不同写法合并为一行；(b) 对照 query 的限定词逐行自问"这一行真的在范围内吗"，删掉勉强沾边的；(c) 双向核对基数——行数**远超**目录基数和**远低于**基数都要回头，前者查过度收录，后者查漏采。
4. 同一张表的行粒度必须一致：不允许一部分行是"系列"、另一部分行是"系列×型号"。

## 三、数值列：单位是值的一部分

1. 每个数值列在 column_desc 声明单位与精度（货币、万/亿、百分比、物理单位）。必须和任务要求保持一致。
2. **列名即单位契约**：当列名自带单位标注（如「距离（公里）」「面积（km²）」），column_desc 的 desc 中声明的单位**必须与列名量级严格一致**。CJK 量级词（万/亿/千）与英文量级词（thousand/million/billion）之间存在非等价映射（亿=1e8 ≠ billion=1e9），绝不允许将不等量级互相 gloss 为同义。正确做法：desc 中只写与列名完全相同的量级词，若源数据量级不同则显式声明换算公式（如"源值若为 X 单位需 ×N 换算为列名单位"）。
3. 源页面主流写法带单位的，最终值**带单位输出**（"12.6万千米"而非裸"12.6"）；裸数字只在 query 明确要求纯数值时使用。
4. 跨源单位不一（"1.2万米"与"12 km"），且换算是确定的，把换算规则写进 desc，全列统一到声明口径。同一列内禁止混杂多种写法。

## 四、规则/条件类长文本列：阈值原文保留

列语义为"准入条件、资质要求、适用范围、评定标准"这类规则描述时：

1. 这类列的价值在**具体阈值**与**完整枚举**。例：招标资质"注册资本不低于500万元，且近三年完成同类项目不少于 2 个"——其中每个数字和"且/或"逻辑都是答案本体，必须原样保留，禁止概括成"需满足资金与业绩要求"。
2. column_desc 写明："记录原文数字阈值与条件逻辑，禁止抽象转述"。
3. 阈值必须与**本行**身份核对——表格页里相邻行的条款极易抄串；填完抽查：单元格里没有任何数字而证据原文有数字 = 信息已丢失，回填。

## 五、日期/时间列：格式必须遵从 query 指定或推断

1. **query 显式指定格式时**（如"formatted as YYYY"、"MM-DD-YYYY"），column_desc 照抄该格式，全列严格执行。
2. **query 未指定时**，从 query 的语言和惯例推断：英文 query 默认 MM-DD-YYYY 或 YYYY-MM-DD（看 query 示例）；中文 query 默认 YYYY-MM-DD 或 YYYY年M月D日。在 column_desc 中显式声明选定格式。
3. **绝不允许同列混用格式**（如部分行 YYYY-MM-DD、部分行 DD/MM/YYYY）。reformat 阶段做最终统一。
4. "最近 N 年"类时间范围：以 **query 提出时的当前年份**为终点向前推 N 年，不要自行猜测起止年。当前年份从系统时间获取。

## 六、语言一致性：输出语言跟随 query 语言

1. **query 用英文提问 → 实体名、地名、机构名全部用英文输出**。即使源页面是中文/日文/其他语言，也必须翻译为英文（或使用其官方英文名称）。
2. **query 用中文提问 → 输出中文**。同理。
3. column_desc 中写明语言要求："输出英文名称"或"输出中文名称"。
4. 特殊情况：当实体的官方名称就是外语（如品牌名、学术术语），保留原文不翻译。

## 七、地名/位置列：粒度在 schema 中声明

1. 位置信息天然存在多粒度："城市"、"城市, 州/省"、"城市, 州/省, 国家"、"具体地址"。
2. **在 column_desc 中显式声明粒度**，例如："格式为 City, State/Province, Country" 或 "仅写城市名"。
3. 从 query 推断粒度线索：query 说"Location"且给出示例"Atlanta, Georgia, United States"→ 三级粒度；query 只说"城市"→ 一级。
4. 当 query 未给出粒度线索时，采用**源页面的主流写法**——若权威源（Wikipedia infobox、官方数据库）写 "City, State, Country" 则照搬。

## 八、聚合/排名列：口径必须与 query 时间窗口对齐

1. 涉及"过去 N 个赛季/年/期间"的聚合统计：**先确认 N 个区间的具体起止**，在 column_desc 写明（如"2022-23, 2023-24, 2024-25 三个赛季的总和"）。
2. 排名/Top-N 类：**数据源必须与 query 指定的排名体系一致**。query 说"according to TDF"就只能用 TDF 的数据；query 说"based on annual passenger traffic for 2022"就只能用 2022 年数据。不要用其他年份或其他排名体系的数据替代。
3. 多源数据不一致时，**优先使用 query 明确指定的来源**。如果 query 未指定来源，优先使用最权威/官方的数据源。

## 九、行粒度与 PK 选择：严格从 query 推导

1. **PK 选择错误是最致命的失误**——PK 错了意味着全表行无法与 gold 对齐，row_f1 直接归零。
2. 从 query 中的**列名**和**示例值**推导 PK：query 说"names (e.g., Charming Garden)"→ PK 是店名而非地址；query 说"Rank"在首列→ PK 含 Rank。
3. query 给出了**示例格式**（如"e.g., 23906570"）时，这是粒度的硬约束。如果示例暗示 15 条结果但你找到了 100 条，说明收录规则理解有误——回头审视 query 的限定条件（如"located on Hong Kong Island"的范围）。
4. 开放集表（行数未知）：先搜目录/索引页确认基数，再决定 PK 粒度。不要先采集再事后发现粒度不一致。

## 十、多值单元格与显式取值约束

1. **多值单元格要完整**：一格里合法地含多个实体（多位作者、多个配偶、并列项）时，必须**全部列出**，漏掉任意一个该格即判负。多值内部的顺序与分隔符（`,` / `&` / `;`）评测方一般容忍，但成员不能缺。
2. **遵守 query 对取值形式的显式约束**：query 说"creator's real name（真名）"就不能填笔名/艺名；说"official name""full legal name"同理。源页面给的是别名时，回查其要求的形式，别图省事抄最显眼的那个。

## 十一、合成前对齐自检（逐条过）

1. 行身份列是否存在未双写的多表示？→ 回到第一节。
2. 行数对照基数：明显低于基数（如 <70%）→ 回到枚举，不要急着合成。
3. 数值列抽 3 行：单位齐不齐、口径统不统一？
4. 规则文本列抽 3 行：原文阈值在不在？
5. 排序、列序、单表/多表是否符合 query 的字面要求？
6. **日期格式**：全列是否统一？是否与 query 指定/推断的格式一致？
7. **语言**：实体名的语言是否与 query 语言匹配？
8. **位置粒度**：Location 类列的详细程度是否全列一致？
9. **聚合口径**：统计/排名数据的时间窗口和来源是否与 query 要求一致？
10. **行集合精确率**：是否有超出 query 范围/旁系/重复的行没清掉？行数是否远超目录基数？→ 回到第二节做 scope-filter。
11. **多值与取值约束**：多值格成员是否齐全？真名/官方名等显式约束是否遵守？

## 常见误区
- ❌ 编号"看起来更规范"于是只采编号 → 文字口径场景整题归零
- ❌ 映射关系记在备注/desc 里而不是表里 → 渲染 join 不到，输出仍是单表示
- ❌ 把"已发现的行全填满"当作"该有的行都齐了"（fill rate ≠ recall）
- ❌ 同列混杂 "1.2万米 / 12000 / 12 km" 三种写法 → 逐格判负
- ❌ 列名量级与 desc 声明量级不一致（如 CJK"亿"≠ EN"billion"），照搬源值不换算 → 全列差一个数量级归零
- ❌ 规则文本概括转述、或把相邻行的阈值抄串
- ❌ 日期格式不统一或与 query 期望不一致（如输出 YYYY-MM-DD 但 query 期望 MM-DD-YYYY）→ PK 含日期时全表行失配
- ❌ query 用英文提问但输出中文实体名 → 行无法与英文 gold 对齐，row_f1 归零
- ❌ 位置列有的行写"City, Country"有的写"City, State, Country" → 同列粒度不一致
- ❌ PK 列选错（如选地址而非店名）→ 整表行身份错位，即使内容正确也全判负
- ❌ "最近N年"从错误年份起算（如 query 在 2025 年问"最近10年"却从 2015 开始）→ 时间窗口偏移导致行集合不匹配
- ❌ 聚合统计的赛季/年份与 query 不一致（如数了 4 个赛季而非 3 个）→ 数值偏差
- ❌ "宁多勿漏"收了一堆旁系/克隆/近义实体却不在合成前剔除 → 精确率崩，row_f1 随之归零
- ❌ 多值单元格漏掉其中一个成员（如两位作者只写一位）→ 该行判负
- ❌ query 要"真名"却填笔名/艺名 → 判负

