# Jupyter AI 合并多个 Excel 工作表：统一列名，保留来源并单独导出异常行

原生三工作簿已由artifact-tool生成；Python只读真实XLSX后合并，保留file/sheet/row并隔离3条异常，结果已输出。未运行Jupyter AI Agent。

## 版本与门槛

Jupyter AI v3.2.0、JupyterLab4和另装的Agent/ACP适配器；不会自带免费Agent。参考读取用openpyxl，XLSX创建/渲染用artifact-tool。BSD-3-Clause；Agent模型费用另计。

## 操作步骤

1. 查看三份输入和不一致表头

打开north.xlsx的AM/PM、south.xlsx的Registrations及broken-schema.xlsx。表头分别用编号/报名号、姓名/联系人、人数/名额；south含空编号与0人，broken-schema缺人数列。本题一共7条数据，不能静默跳过坏Sheet。

2. 准备Jupyter AI和实际Agent

在JupyterLab创建新Notebook和Chat，确认v3.2.0及至少一个可用Agent。部分Agent需ACP适配器，模型授权由其自身决定；不用旧版/generate按钮当本题步骤，也不向模型发送真实报名信息。

3. 把列名映射与拒绝规则交给Agent

上传三份文件，使用prompt.md要求先检查schema再生成处理代码。id只作字符串保留，count必须正整数，来源字段必须来自真实文件/Sheet/行号，不让模型事后编一列来源名。

4. 审查代码后运行合并Notebook

确认代码只读取指定文件，输出到新文件，禁止覆盖输入。先运行读取/表头预览单元格，再运行规范化与校验。不要把本包merge_reference.py的结果说成Jupyter AI已经完成合并。

5. 分开处理正常和拒绝行

参考结果为4条正常、3条拒绝：空ID、0人数、缺列各1条。拒绝行应保留原值、原因及来源，不能靠填1人使总表看起来完整。核对合法的N01/N02/N03/S01均保留。

6. 逐来源核对行数守恒

按north AM 2、PM 1、south 3、broken 1对账，合入+拒绝必须仍为7。检查source_row为原Sheet的实际一基Excel行号（数据从第2行开始），而不是合并后的新序号。

7. 重启内核从头复跑

保存Notebook后重新启动内核，Run All，使用同一原始文件确认仍为4/3且输出一致。全新环境运行不能依赖聊天中曾定义但未写入Notebook的变量；具体隐藏依赖排查见相邻Jupyter题。

8. 导出可打开的表和代码

实际输出可交merged/rejected CSV或XLSX，但文件格式要写准确。本包提供真实merged-reference.xlsx与rejected-reference.xlsx及JSON；保留模型原代码、人工修正和版本记录，对外共享前去掉账号密钥。

## 本地参考与运行

原生三工作簿已由artifact-tool生成；Python只读真实XLSX后合并，保留file/sheet/row并隔离3条异常，结果已输出。未运行Jupyter AI Agent。

运行 `python3 verify.py` 检查材料；原生文档检查需要pypdf、openpyxl或lxml。需要重建参考时运行本包对应reference.py；这些脚本不调用模型。

## 官方来源

- https://github.com/jupyterlab/jupyter-ai/releases/tag/v3.2.0
- https://jupyter-ai.readthedocs.io/en/stable/releases/v3.2.0.html
- https://jupyter-ai.readthedocs.io/en/stable/users/index.html
- https://jupyter-ai.readthedocs.io/en/stable/getting-started.html
- https://github.com/jupyterlab/jupyter-ai/blob/main/LICENSE

## 素材身份与许可

本站原创教学输入与参考代码采用CC0-1.0；官方截图仅用于识别软件和说明操作入口，其版权归相应项目。工具与模型许可分别按官方来源执行。请勿将人工/参考算法文件描述成目标软件或模型的实际结果。
