拆解一个 AI Agent 技能:Excel 公式批量分析器是怎么工作的
在华为云「AI Agent 开发实践中心」里,有一个很有意思的技能仓库
agent-best-practices/excel-formula-explainer:给它一个.xlsx文件,
它会自动读出所有公式,并输出一份纠错与优化报告。这篇文章带你把它的
实现方式拆开看一遍,顺便聊聊"给 Agent 写技能"这件事的工程要点。
一、为什么需要"读公式"这件事
财务、运营同学每天都要和 Excel 打交道。表格一旦复杂起来,问题就来了:
- 公式里引用了已经被删掉的单元格(死引用);
- 两个单元格互相引用,形成循环(循环引用),打开就报错;
- 跨表引用到处都是,改一张表就"牵连一片";
- 数值直接写死在公式里,换个参数就要挨个改(硬编码)。
人工核对动辄几百上千个公式,效率极低。把这件事交给一个 Agent 技能,
正好合适——它不需要"聪明",只需要确定性、可复现地跑一遍静态检查。
二、整体架构:一个小而完整的流水线
这个技能只依赖 openpyxl,代码分成五个清晰的角色:
analyze_excel.py 命令行入口:参数解析、打印/写文件
│
excel_reader.py 读取 xlsx,提取「公式原文 + 缓存值」
│
graph.py 构建依赖图:循环 / 死引用 / 跨表 / 硬编码 检测
│
analyzer.py 编排上述检测,并补上每个公式的上下文
│
report.py 把结果格式化成人类可读的报告
这是一个非常典型的 Agent 技能形态:入口薄、逻辑纯、输出可读。
没有 Web 服务、没有数据库,一个 CLI 就能被 Agent 直接调用。
三、关键实现细节
1. 公式和缓存值要读两遍
openpyxl 有个重要特性:data_only=False 读到的是公式文本,
data_only=True 读到的是最后一次保存时的计算结果。二者互不覆盖:
wb_f = openpyxl.load_workbook(filepath, data_only=False) # 公式
wb_d = openpyxl.load_workbook(filepath, data_only=True) # 缓存值
因此 excel_reader.py 会把文件打开两次,再把同一单元格的"公式"和"值"
拼成一条记录。这个思路值得记住:读 Excel 想同时拿到公式和结果,就得开两遍。
2. 用正则从公式里抽出引用
graph.py 用两条正则分别匹配单元格引用和区域引用:
_CELL_REF = r"(?:'[^']*'|[A-Za-z_][\w]*(?=\!)!)?\$?[A-Z]{1,3}\$?\d+"
_RANGE_REF = r"(?:'[^']*'|[A-Za-z_][\w]*!)?\$?[A-Z]{1,3}\$?\d+:\$?[A-Z]{1,3}\$?\d+"
匹配到区域(如 A1:Z100)后,再展开成一个个单元格,从而把依赖关系
统一成"单元格 → 单元格"的图结构。有了图,很多检查就顺理成章了。
3. 四类检查各有门道
- 循环引用:对依赖图做三色 DFS(白/灰/黑),遇到灰色节点即发现环。
- 死引用:解析引用目标,区分"不存在"“空单元格”"常量值"三种情况,
给出 high / medium / low 的梯度严重度。 - 跨表引用:正则提取公式里出现的
Sheet!前缀,与本表不同即记录。 - 硬编码值:用正则找出紧跟在运算符/括号后面的数字,排除
0、1这类
正常边界值。
最后 report.py 把它们汇总成"共检测 N 个公式、M 个有问题、K 个高风险"的报告,
并逐个公式列出明细。
四、一个真实的坑:整列 / 整行引用会被漏掉
在 graph.py 里,提取公式引用的两条正则都要求引用带数字行号(如 A1):
_CELL_REF = r"...\$?[A-Z]{1,3}\$?\d+" # 必须有行号
_RANGE_REF = r"...\$?[A-Z]{1,3}\$?\d+:\$?[A-Z]{1,3}\$?\d+" # 两端都必须有行号
但 Excel 里非常常见的整列 / 整行引用并不包含行号,例如 SUM(A:A)、SUM(1:1)、
COUNTIF(Sheet2!B:B, ...)。这些写法匹配不到任何引用,于是:
extract_references("=SUM(A:A)") # [] 期望应识别 A 列
extract_references("=SUM(A:A)+B1*2") # ['B1'] A:A 被丢失
依赖图因此缺失该依赖,循环引用、死引用检测都会跟着漏报。
教训:解析公式语法时,别默认"列 + 行"一定成对出现;整列、整行是合法且高频的写法。
另外,对整列/整行也不该逐格展开(A:A 展开会是上百万个单元格),而应建模成区间来处理。
(我顺手给这个仓库提了一个 Issue,附上了最小复现和修复方向。)
五、给 Agent 写技能的几点体会
- 确定性优先:能用静态规则搞定的,就别上大模型。快、准、可复现。
- 输出面向人:Agent 技能最终是给人看的,报告要"能直接贴进工单"。
- 主键要完整:跨表、跨目录、跨命名空间时,别在中间层把前缀削掉。
- 双读兜底:外部文件格式的协议细节(如
data_only)要照顾到边界情况。
华为云「AI Agent 开发实践中心」里还有很多类似的技能仓库,覆盖文档处理、
信息检索、桌面自动化等场景,感兴趣的可以直接去 gitcode.com 上翻一翻,
照着改一改,就是一个很好的练手项目。
本文配套示例仓库:agent-best-practices/excel-formula-explainer(GitCode)
- 点赞
- 收藏
- 关注作者
评论(0)