前接:赛题全景与难点,本篇主要介绍这个比赛可能涉及到的一些技术点


AFAC2026 赛题四金融长文本 Agent竞赛学习笔记(一)
AFAC2026 赛题四金融长文本 Agent竞赛学习笔记(二)
AFAC2026 赛题四金融长文本 Agent竞赛学习笔记:参赛方案解析(三)
4 关联技术
4.1 PDF 解析方案详解
来自AFAC2026-advance baseline-tutorial.md的详解方案
RAG 系统的质量上限由两个因素决定:检索策略和文档解析质量。如果第一步就把表格变成了乱码、公式丢失了、段落顺序乱了,后面所有环节都在错误的文本上工作。这种错误无法通过优化检索或 prompt 来补救 。
保险条款和财报类 PDF 有几个让解析器头疼的特点:
- 复杂表格(保费表、现金价值表、赔付比例表,行列密集且嵌套层级深)
- 数学公式(精算公式、财务比率公式,上下标和分式结构容易丢失)
- 双栏/多栏布局(部分研报和合同使用多栏排版,阅读顺序容易错)
- 页眉页脚混入正文、扫描件 vs 电子件(部分文档是扫描图片需要 OCR,部分是原生 PDF 可直接提取文字)。
4.1.1 轻量级:PyMuPDF4LLM(Baseline 方案)
PyMuPDF4LLM 是基于 PyMuPDF 的轻量封装,专门为 LLM 场景设计。核心能力是把 PDF 直接转为 Markdown 文本,保留标题层级,提取表格为 Markdown table 格式。
优势: 纯 Python 库,安装简单,不需要 GPU,速度快(50 页 PDF 约 5-10 秒),对原生 PDF 文字提取质量尚可。
局限: 不包含 OCR 能力(扫描件无法处理)、表格提取基于规则(复杂嵌套表格容易错位)、公式识别能力弱、双栏文档阅读顺序可能出错、字号推断标题层级不总是准确。
为什么 baseline 选它: 赛方评测环境不提供 GPU,PyMuPDF4LLM 是当时能在 CPU 上快速跑通的方案。17% 的准确率中,有一部分损失确实来自 PDF 解析不够好,但 baseline 的目标是先把端到端流程跑通 。
4.1.2 中量级:Marker
Marker(VikParuchuri, 2024, GitHub: VikParuchuri/marker)是一个基于 pipeline 架构的 PDF 转 Markdown 工具。流水线是:Surya 布局检测 → Surya OCR(可选)→ 文本提取 → Markdown 输出 。
核心能力: 布局检测使用 Surya 模型,能识别标题、正文、表格、公式、图片、页眉页脚等区域;内置 OCR 能力,支持 90+ 种语言;对扫描件和原生 PDF 都能处理;自动过滤页眉页脚。
局限: 依赖 PyTorch 模型,需要 4-8GB 显存(GPU 模式);CPU 模式下速度较慢(50 页 PDF 可能需要 5-15 分钟);对极端复杂的表格仍有遗漏;公式识别不支持 LaTeX 输出。
对本赛题的适用性: 如果赛方提供 GPU 环境,Marker 是一个性价比不错的选择。CPU 模式下虽然慢,但解析在预处理阶段完成,不占用提交时的 Token 预算,时间成本可以接受 。
4.1.3 重量级:MinerU
MinerU(上海 AI Lab / OpenDataLab, 2024 年发布, GitHub: opendatalab/MinerU)是目前开源社区最受关注的 PDF 解析工具之一,专为 LLM / RAG / Agent 场景设计
核心能力: 完整的版面分析管线(布局检测 → 阅读顺序恢复 → 元素识别 → 结构化输出);表格和公式提取质量高,公式自动转为 LaTeX;支持 109 种 OCR 语言;输出 Markdown / JSON / HTML / LaTeX 多种格式;内置 MCP Server 支持。
优势: 公式转 LaTeX 是本赛题的关键优势------保险条款和财报中的数学公式能完整保留;阅读顺序恢复能力强,双栏/多栏文档不乱序;对中文文档优化好;OmniDocBench 评测中英文文档解析表现领先。
局限: GPU 依赖(需要 CUDA 支持的 GPU,推荐 8GB+ 显存),纯 CPU 模式可以运行但非常慢;安装复杂(首次配置可能需要 30 分钟以上);内存占用大(处理高分辨率文档时可能占用 10GB+ 内存);单页处理时间 GPU 下约 3-8 秒/页,CPU 下可能 30-60 秒/页。
对本赛题的适用性: 如果赛方允许使用 GPU 环境,MinerU 是目前的最佳选择。公式 LaTeX 化、表格结构化、阅读顺序恢复这三项能力直接解决了本赛题 PDF 解析的核心痛点。即使赛方只给 CPU 环境,MinerU 也可以跑(只是慢),预处理阶段的时间成本通常可以接受。
4.1.4 视觉语言模型级:olmOCR
olmOCR(Allen AI, 2025 年 2 月发布, arXiv:2502.18443)代表了 PDF 解析的新方向:不用传统的 OCR + 版面分析流水线,而是用一个精调的 7B 视觉语言模型直接把 PDF 页面转成结构化的纯文本 。
核心能力: 基于 7B VLM,精调在 260,000 页多样化 PDF 上;支持表格、列表、公式、手写文字的提取;输出线性化的纯文本,保持自然阅读顺序;在 olmOCR-Bench 上表现优于 GPT-4o、Gemini Flash 2 和 Qwen-2.5-VL。
优势: 不需要复杂的版面分析管线,一个模型搞定所有页面类型;对扫描件、手写文档、低质量 PDF 的处理能力远超传统 OCR 方案;开源的 7B 模型可以在本地部署。
局限: 需要 GPU(7B VLM 推理),CPU 不可用;中文文档的处理质量未知(训练数据以英文为主);输出格式为纯文本而非 Markdown,丢失了部分结构信息;表格和公式以文本形式呈现,不如 LaTeX 精确。
对本赛题的适用性: 如果赛方提供 GPU 环境且中文处理质量过关,olmOCR 是一个值得尝试的方案。但目前中文支持情况不明朗,建议等社区有中文评测结果后再决定 。
4.1.5 本赛题的 PDF 解析选型建议
根据 AFAC2026-advance baseline-tutorial.md的表述,分三种情况:
| 环境 | 推荐方案 | 理由 |
|---|---|---|
| 纯 CPU | PyMuPDF4LLM + 预处理优化 | 无 GPU 时的唯一选择。可以在预处理阶段做更多工作来补偿解析质量(如人工修正表格、补充公式描述) |
| GPU(8GB+) | MinerU | 当前开源方案中综合能力最强,公式/表格/阅读顺序三项核心能力突出 |
| GPU(16GB+) | MinerU + olmOCR 互补 | MinerU 处理结构化文档,olmOCR 处理扫描件和低质量页面,两路互补 |
即使赛方最终只给 CPU 环境,学习 MinerU 和 olmOCR 也是有价值的。了解更好的解析方案能帮助理解当前 baseline 的瓶颈在哪里(哪些错误是 PDF 解析导致的,哪些是检索策略导致的,哪些是 prompt 设计导致的)。定位清楚瓶颈,才能精准优化 。
4.1.6 预处理阶段可以做的工作
无论用哪个解析工具,以下预处理手段对提升文本质量有帮助:
- 页眉页脚过滤:用正则匹配重复出现的页码、章节标题、公司名称等,统一去除
- 表格后处理:对解析出的表格做格式校验(行列数一致、数值列对齐),异常时回退到手动提取
- 公式补标注:在公式附近插入描述性文本(如"该公式表示:现金价值 = 累计保费 × 75%"),帮助 LLM 理解公式含义
- 段落合并:同一段落的文本可能被解析成多行,按标点和语义做合并
- 文档结构标注:为每个段落标注所属章节路径(如"第二章 > 第三节 > 现金价值计算"),增强检索时的上下文信息
"文档解析是'一次性投入',不消耗比赛在线 Token。这一步做不好,后续所有环节都在吃哑巴亏。"
4.2 RAG 技术架构
来自选手 AFAC2026-advance baseline-tutorial.md的详解
Baseline 的硬截断本质上跳过了检索,直接把文档前半部分塞给模型。要突破 17% 的准确率天花板,第一步就是引入检索模块。但检索不是简单加一层 BM25 就完事------分块、召回、排序、组装每个环节都有坑。
4.2.1 分块策略
文档切片是 RAG 的地基。切得不好,后面的检索和生成都受影响。
固定大小分块:按固定字符数切分,实现简单但容易切断语义。比如"因意外伤害发生上述情形的,无等待期"如果被切成两块,检索可能只命中前半句,模型看到的就是残缺的。
滑动窗口分块:相邻块之间有 10%-20% 重叠,减少边界信息丢失。适合保险条款这种前后文紧密关联的文档。重叠太多会导致检索结果重复,占用 Token 预算。
语义分块:按段落、章节等自然边界切分,保持语义完整。Markdown 文档天然适合按标题层级切分。缺点是块大小不均匀。
多粒度分块(Small-to-Big):把文档切成两层------子块(200-500 token)用于检索,父块(800-2000 token)包含完整上下文。检索命中子块后,把对应的父块一并取出送给 LLM。好处是"检索用小块(精确)、回答用大块(完整)",实验表明准确率比单一大块高 10%-15%。
推荐起步方案:按 Markdown 标题切分 + 滑动窗口,块大小 800-1200 token,重叠 15%。有精力的话升级到多粒度分块。
4.2.2 混合检索
单一检索策略各有盲区:BM25 对精确匹配敏感(数字、条款编号),但无法理解"退保费用"和"退保手续费"是同一个东西;向量检索能捕捉语义相似性,但对数字和年份不够敏感。
混合检索 = BM25 + 向量检索,两路同时召回,结果融合后一起送进 LLM。常用的融合方式是 RRF(Reciprocal Rank Fusion):按每路结果的排名位置加权融合,不依赖绝对分数。
⚠️ 赛题禁止使用 embedding 模型,所以向量检索在正式提交中无法使用。以下内容帮助理解 RAG 完整技术栈,实际参赛时只能依赖 BM25 + 关键词的稀疏检索路线。
4.2.3 前沿 RAG 范式
标准 RAG 有三个根本缺陷:
- 扁平化(无法理解跨块的语义结构)
- 局部性(擅长回答"这段话说了什么",回答不了"这些文档整体讲了什么")
- 无反思(检索到什么就用什么,不评估质量)。下面的范式各自针对其中一个或多个缺陷 。
GraphRAG:用知识图谱做检索
GraphRAG(Microsoft, 2024)的核心思路:不要只把文档切成碎片去搜,而是先从文档中提取实体和关系,构建知识图谱,再基于图谱做检索和推理。
流程:实体与关系抽取 → 知识图谱构建 → 社区检测(Leiden 算法)→ 社区摘要生成 → 两种检索模式:
- Local Search:从实体出发沿图的边扩散到邻居节点,适合事实查找("平安智盈金生的现金价值怎么算?")
- Global Search:匹配相关社区,用社区摘要生成部分回答再汇总,适合全局理解("四份条款的退保规则有什么系统性差异?")
对本赛题的适用性:跨文档对比题和多文档联合推理题是 GraphRAG 的最优场景。比如 ins_a_001(四产品身故保险金排序),传统 RAG 需要逐份检索再手动对比,GraphRAG 可以直接在图谱中查询"身故保险金"实体,沿关系边找到四个产品的计算规则。代价是预处理阶段需要大量 LLM 调用,但可以在提交前离线完成。
LightRAG:轻量级图 RAG
LightRAG(香港大学, 2024)是 GraphRAG 的轻量替代,保留了图结构的优势,但大幅降低了构建成本。
关键差异:GraphRAG 需要社区检测 + 逐社区摘要,是重操作。LightRAG 用双向量索引同时支持局部和全局检索------实体节点有独立的向量表示(Local Search),关系边也有独立的向量表示(捕捉跨实体的语义模式)。新文档加入时可以直接增量插入,不需要重建已有索引。
对本赛题的定位:适合作为从标准 RAG 向图 RAG 过渡的第一个实验方案。构建成本接近传统 RAG,但能同时支持局部事实查找和全局对比推理。
RAPTOR:树状递归摘要检索
RAPTOR(2024)解决的是"扁平检索丢失全局上下文"的问题。
构建流程:叶子层(基础文本块做 embedding)→ 聚类(高斯混合模型软聚类)→ 摘要(每个聚类生成摘要,成为上一层节点)→ 递归重复直到只剩根节点。最终形成一棵多层树:底层是原始文本块(精确细节),中层是主题摘要(如"退保规则"),顶层是全局摘要。
检索时按复杂度选择层级:简单事实查找从叶子层检索;全局理解从顶层摘要节点检索。
对本赛题的适用场景:行业研报类题目(如 res_a_001 银保渠道发展历程)和跨年度对比题(如 fin_a_001 比亚迪两年年报对比)是 RAPTOR 的优势场景------这些题需要同时理解宏观趋势和微观数据,树结构天然匹配"总-分"的信息粒度。
CRAG:让系统反思检索质量
CRAG(2024)的核心洞察:传统 RAG 无条件信任检索结果,但 BM25 可能因关键词匹配把不相关片段排到前面,向量检索可能因语义模糊召回弱相关内容。
CRAG 加入自动纠错机制:检索后用轻量特征(关键词重叠度、片段间语义一致性)对整体结果打分,分三级处理:
- 分数 ≥ 0.7(CORRECT):检索质量好,直接使用
- 分数 0.3-0.7(AMBIGUOUS):质量一般,保留当前结果同时换关键词补充检索
- 分数 ≤ 0.3(INCORRECT):质量差,丢弃检索结果,回退到全文阅读(baseline 硬截断作为 fallback)
对本赛题的适配:这个机制让系统在"检索结果好"的时候享受检索的效率,在"检索结果差"的时候自动回退到更稳健的方案,而不是一味信任检索。
HyDE:用假设答案做检索
HyDE(2023)解决的是"用户问题用词和文档用词不一致"导致的检索失败。
做法:先让 LLM 凭空生成一份假想的"理想答案"(用文档风格写,包含专业术语),再把这份假想答案(而非原始问题)转成向量去检索。假想答案更容易匹配到真实的相关片段。代价是每次检索多一次 LLM 调用,但召回率通常比直接向量检索高 10%-20%。
对本赛题的有效性 :对口语化问题(如"哪个产品最划算")特别有效。评测表明 HyDE + 混合检索(BM25 + 向量) 是目前综合表现最好的默认配置。
Agentic RAG:让 Agent 自主编排检索策略
前面所有范式都预设了检索策略:什么时候搜、搜什么、搜几次,都是提前写死的。Agentic RAG 把这个决策权交给 LLM 自己:通过 Function Calling,LLM 自主决定当前问题是否需要检索、搜什么关键词、搜到什么程度才算足够、搜到的东西质量差怎么办。
与本赛题的关联:Baseline 测试过 Function Calling,Token 消耗比 no-tool 高约 18%,但 FC 的灵活性(模型可以自主决定"什么时候搜、搜什么")是提升准确率的关键路径。
4.2.4 本赛题的 RAG 路线建议
从 baseline 的硬截断出发,建议按以下顺序逐步引入 RAG 优化 ,观点来自AFAC2026-advance baseline-tutorial.md:
| 阶段 | 方案 | 预期收益 | 风险 |
|---|---|---|---|
| 1 | BM25 检索 + 语义分块 | 解决"答案不在前 4000 字"的问题 | 连贯性断裂,可能降分 |
| 2 | + 多粒度分块(子块检索 + 父块回答) | 缓解连贯性断裂 | 实现复杂度增加 |
| 3 | + HyDE(假设答案检索) | 提升召回率,改善口语化问题匹配 | 增加一次 LLM 调用 |
| 4 | + Rerank 精排 | 提升精确率 | 额外计算开销 |
| 5 | + 动态记忆压缩 | 在有限 Token 预算内保留最多有效信息 | 过度压缩可能丢失关键条件 |
| 6 | + Bash 工具(Python 代码执行做数值计算) | 消灭公式计算题的算术错误 | 需要设计沙箱执行环境 |
| 7 | + CRAG 自检机制(质量评估 + 自动回退) | 减少低质量检索导致的错误 | 需要设计评估器逻辑 |
| 8 | LightRAG(跨文档题) | 解决跨文档联合推理,支持增量更新 | 预处理 Token 消耗 |
| 9 | Agentic RAG(FC 自主编排检索策略) | 灵活应对不同题型 | Token 消耗增加约 18% |
| 10 | smolagents Code Agent | 减少 30% 推理步骤,精准数值计算 | 需要学习 smolagents 框架 |
建议每完成一个阶段就跑一次 A 榜提交,验证实际收益,避免"加了优化反而降分"的陷阱。
4.3 上下文与动态记忆
赛题名称里就有"动态记忆压缩",这定义了本赛题的核心技术挑战。PDF 解析和 RAG 检索解决的是"怎么找到有用信息",这一章解决的是"怎么在有限 Token 预算内把最重要的信息喂给模型"。
4.3.1 问题的本质:上下文窗口是稀缺资源
每道题的推理链路可以拆成:读文档 → 提取信息 → 判断 → 输出答案。每一步都消耗 Token,但预算有限(总预算 500 万 Token)。这意味着不能把所有文档全读一遍,也不能把检索结果全塞进 prompt。
上下文管理的核心问题可以表述为:给定 Token 预算,如何从候选信息池中选择一个子集,使得模型回答正确的概率最大化?
4.3.2 动态截断与信息密度控制
Baseline 的硬截断固定取前 4000 字符。更好的策略是让模型自己决定什么时候停止阅读:分段读取文档,每读一段就判断"当前信息是否足够回答问题"。如果足够就停止,不够就继续读下一段。
更精细的做法是按题型设定不同的阅读预算:事实查找题可能读前 2000 字符就能找到答案;跨文档对比题需要读多份文档,每份可能 1000 字符就够;公式计算题只需要定位到公式所在的段落,读到公式后就可以停。
保险条款和监管法规中有大量模板化文本(如"本合同的构成""投保须知"等),这些内容对答题几乎没有价值。可以预处理时过滤掉高频无意义段落,或者对"释义""名词定义"等章节降权。
4.3.3 工业界的记忆压缩实践
几个主流 Agent 框架都有类似的记忆管理机制,核心思路都是分层存储 + 选择性保留。
Kimi Code CLI 的 Context Compaction
当对话历史超过 token 阈值时自动触发 compaction,按优先级保留:当前任务状态、错误与解决方案、代码最终版本、系统上下文、设计决策、TODO 项。压缩后的历史替换原始对话,模型只看到摘要。
对本赛题的启发:可以定义类似的优先级------题目原文(绝不压缩)> 提取的公式和数值(核心证据)> 检索到的相关原文片段 > 文档结构信息 > 中间推理摘要 > 不相关的检索内容(优先丢弃)。
Hermes 的 Trajectory Compressor
核心算法是保护首尾、压缩中间、LLM 替代:
- 头部保护:任务的初始上下文(题目定义、第一个工具调用)
- 尾部保护:最后 N 个 turns(最新的推理状态和即将做出的决策)
- 中间压缩:用 LLM 生成结构化摘要,替代原始阅读内容
对本赛题的映射:
- "首" = 题目文本 + 选项(不可压缩)
- "尾" = 最终推理步骤(列出公式 → 代入数值 → 计算结果 → 对比选项 → 输出答案)
- "中间" = 文档阅读过程。读了一份 50 页条款,中间可能读了 20 页才找到"现金价值"定义,这 20 页可以压缩为一段结构化摘要
Claude Code 的四层渐进压缩
从便宜到贵逐级尝试:Layer 1 Snip(裁剪工具输出,免费)→ Layer 2 Microcompact(轻量压缩)→ Layer 3 Context Collapse(折叠搜索/读取操作为摘要)→ Layer 4 Autocompact(LLM 全量总结,最贵)。核心原则:只有低层搞不定才升级。
对本赛题的启发:检索返回的文档片段如果太长,先 Snip(只保留包含关键词的段落 + 前后各一段上下文);Snip 后仍然超预算再调 LLM 做摘要。不要一上来就让模型总结。
Codex 的 Memento 策略:为什么不能只留摘要
Codex 的 compaction 有一个关键设计:压缩后的历史不是纯摘要,而是 initial_context + 精选 user 消息 + summary + 最近 N 条。原因很简单------LLM 生成的 summary 会丢失精确信息。
一个典型场景:保险条款里"因意外伤害发生上述情形的,无等待期"这句例外条件,压缩时可能被总结为"等待期内一般不赔","意外伤害例外"这个关键信息就丢了。
对本赛题来说,压缩时至少要保留三类信息不被摘要化:
- 题目原文(包括选项):压缩题目等于修改题目
- 从文档中提取的精确数值和公式:如"现金价值 = 累计保费 × 75%"
- 包含例外条件的条款原文:如"但意外伤害导致的情形除外"
MemGPT:操作系统式的记忆管理
MemGPT(UC Berkeley, 2023)的核心类比是操作系统的虚拟内存:
- 主上下文 = LLM 的固定上下文窗口(物理 RAM),容量有限但访问最快
- 外部上下文 = 几乎无限的长期存储(磁盘),访问慢但容量不受限
关键创新:LLM 自己控制"换页"过程。当主上下文快满时,LLM 通过 Function Calling 主动检索需要的信息、判断哪些信息可以换出到外部存储、哪些外部信息需要换入。这本质上是把记忆管理从"系统层的固定规则"升级为"应用层的智能决策"。
对本赛题的映射:主上下文对应当前题目的 prompt(受单题 Token 预算约束),外部上下文对应文档全文(不受单题预算约束)。"换页"逻辑在本赛题中应该调整为"分段读取 + 渐进压缩":把读过的文档段落压缩后换出,释放上下文空间给下一个段落。
4.3.4 对本赛题的迁移
上述方案都针对"长对话"场景,但本赛题是"长文档 + 短推理":每道题是一轮独立的推理,不需要跨题记忆。动态压缩应该用在单题推理链的内部 :
- 文档阅读阶段:分段读取,每读一段就压缩提取关键信息(公式、数值、条件判断),只保留压缩后的摘要进入下一段
- 多文档对比阶段:读完文档 A 后生成结构化摘要,读文档 B 时只带着 A 的摘要而非原文
- 验证阶段:自检时不需要重新读全文,只需要带上第一轮推理的结构化摘要做交叉验证
4.3.5 实现建议
触发策略 :参考 Kimi CLI 的双条件触发------当 当前 prompt tokens >= 模型上下文窗口 × 0.7 或 当前 tokens + 预计下一轮检索返回的 tokens >= 模型上下文窗口 时触发压缩。0.7 这个阈值给后续推理留 30% 余量。
保留策略(按优先级从高到低):
- System prompt + 题目原文:不压缩,始终保留
- 从文档中提取的精确数值和公式:保留原文,不压缩
- 包含例外条件的条款原文(如"但...除外"):保留原文
- 中间推理步骤:可压缩为结构化摘要
- 已读但未用到的文档段落:直接丢弃
结构化摘要模板:压缩时不要用 plain text 总结,用结构化模板。参考格式:
[CONTEXT SUMMARY]
Goal: 判断四款产品的身故保险金高低
Documents Read: doc_1(平安智盈金生)、doc_2(国寿增益宝)
Key Formulas Extracted:
- 平安智盈金生: 身故保险金 = max(已交保费, 现金价值)
- 国寿增益宝: 身故保险金 = 基本保额 × 年龄系数
Numerical Values:
- 平安: 已交保费=100万, 现金价值=90万 → max = 100万
- 国寿: 基本保额=90万, 系数=1.6 → 144万
Pending Verification: 文档 3 和文档 4 尚未读取
这种格式的好处是:后续推理可以直接定位到需要的字段,不需要在摘要里重新搜索。而且结构化的 Key Formulas 和 Numerical Values 不会被 LLM 的总结语言"改写"导致精度丢失。
4.4 Prompt 工程
Prompt 不是越长越好。hipw 在 36.8684 到 55.2313 的阶段把所有精力都放在改 Prompt 上,成绩确实有提升,但很快停住。真正有效的 Prompt 设计遵循两个原则:
按题型差异化 + 用 Few-shot 定格式。
4.4.1 题型差异化 Prompt
不同题型需要不同的引导策略:
- 计算题:要求模型先列出公式、再代入数值、再计算结果。避免模型在心算环节出错
- 条款定位题:要求模型先定位条款原文、再逐条比对。避免模型凭记忆判断
- 多选题:要求模型逐选项判断,最后汇总。避免模型漏判或误判个别选项
这也是 Baseline 改进方案中 7 种题型(calc/extract/multi/compare/clause/fact/mcq)各用专用 Prompt 的来源
4.4.2 Few-shot 示例
在 prompt 中提供 1-2 个已答对的题目作为示例,帮助模型理解答题格式和推理过程。注意示例不要占用太多 token。
4.5 Agent
前面的章节解决了"怎么找信息"和"怎么压缩信息",这一章解决的是"怎么让系统自主决策"。Baseline 是单轮调用:读文档 → 一次性输出答案。Agent 化的核心是把这一步拆成"思考 → 行动 → 观察 → 再思考"的循环,让模型自己决定什么时候搜、搜什么、什么时候算、什么时候停 。
4.5.1 从单轮到多步:Agent 的核心思路
Baseline 的单轮模式对简单题有效,但对复杂题(跨文档、多条件、需计算)就力不从心。Agent 化的第一步是把流程拆成多步:
- 读文档:分段读取,提取关键信息
- 判断信息是否足够:如果不够,继续搜索;如果够了,进入推理
- 综合推理:基于收集到的证据做判断
- 输出答案
Function Calling(FC)是实现这一步的基础工具。Baseline 测试过 FC,Token 消耗比 no-tool 高约 18%,但模型可以自主决策"什么时候搜、搜什么",这对跨文档题和信息不足时需要补搜的场景特别有效。
4.5.2 计算题交给代码,不要交给 LLM
大语言模型本质上是"文字接龙"引擎,不是计算器。它在做数学运算时其实是在"背诵"训练数据里见过的计算结果,而不是真正执行算术。即使是最强的 LLM,在多步数值计算中的错误率也显著高于使用 Python 解释器辅助的方案。
解决方案:让 LLM 写代码,用 Bash 工具执行,再把执行结果还给 LLM 做最终判断。
这是终端 Agent(Terminal Agent)模式在金融 QA 中的典型应用:
- 模型不直接输出答案,而是输出可执行的 Python 代码
- 通过 Bash 工具在沙箱中执行代码,获取精确的数值结果
- 模型拿到结果后再做语义层面的判断(比如"增长率 20.1% 是否满足'实现增长'")
为什么 Bash 工具比 Function Calling 更适合计算 :Function Calling 通常只能调用预定义的函数(如 calculator(expression="8*0.0667")),不能写多步逻辑、不能定义中间变量、不能做条件判断。Bash 执行的 Python 脚本给模型一个完整的编程环境,可以自由定义数据结构、写循环、做断言。
额外收益:Bash 执行的 Token 消耗远低于让模型一步步推理。一段 Python 代码 50 个 token,执行结果 10 个 token;同样的计算让模型用 CoT 推理可能需要 200+ token。
4.5.3 ReAct:思考与行动交替
ReAct (Reasoning + Acting, 2023)是目前最主流的 Agent 推理范式。核心循环是:思考(Thought)→ 行动(Action)→ 观察(Observation)→ 再思考 → ...
在本赛题中的应用:
Thought: "这道题需要计算三份保险的退保金。
先从文档中提取各产品的退保金公式和参数。"
Action: 搜索文档,提取公式
Observation: "国寿增益宝:退保金 = 个人账户价值 × (1-退保费用率)
退保费用率第7年为 0%"
Thought: "公式和参数已提取,现在用 Python 计算。"
Action: Bash 执行 Python 代码
Observation: "国寿增益宝 = 120000, 平安智盈金生 = 115000"
Thought: "排序:120000 > 115000,对应选项 A。"
这个循环的关键在于:模型每一步都基于上一步的观察结果做决策,而不是一次性把所有动作都规划好再执行。
4.5.4 Code Agent:用代码替代 JSON 工具调用
smolagents (HuggingFace, 2025)是一个轻量级的 Code Agent 框架,核心设计理念是:让 Agent 通过编写 Python 代码来执行操作,而不是通过 JSON 格式的工具调用。
传统 Function Calling 的流程:模型输出 JSON → 外部系统解析 JSON → 执行工具 → 返回结果 → 模型再输出 JSON...每一步都需要序列化/反序列化,且模型只能一次调用一个工具,无法写条件判断、循环、中间变量。
Code Agent 的流程:模型直接写一段 Python 代码,代码中调用多个工具、定义变量、做分支判断,然后一次性执行完毕,中间结果自动传递。
效率提升:据 HuggingFace 实验,Code Agent 相比 JSON Tool Calling 减少了约 30% 的推理步骤。原因是批量操作(一次代码块包含多个工具调用)、变量传递自动流入下一步、LLM 在代码生成上的训练数据远多于 JSON 工具调用格式。
对本赛题的适用性:
- 公式计算题:直接写 Python 代码做数值计算,精确无误
- 跨文档对比题:一次代码块中调用多次搜索工具(分别搜不同文档),收集所有数据后再统一计算
- 多步推理题 :用
if/else做条件分支,比如"如果资产负债率超过 70%,触发特别决议;否则普通决议" - 自检题 :代码中可以加入断言或验证逻辑,比如
assert result > 0, "计算结果不应为负"
实现建议 :在 Function Calling 的 tools 定义中加入
execute_python(code: str)工具,工具描述中明确说明"用于精确数值计算,不要用 LLM 自己做算术"。代码在受限沙箱中执行(限制import os/subprocess等危险模块),超时设为 5 秒。如果代码报错,把错误信息返回给模型,让模型自己修。
下接:参赛方案解析
参考文献
- AFAC2026 赛道四官方赛题信息页。蚂蚁集团 / 阿里云天池,2026。
- hipw 博客:AFAC2026 赛题四B榜第一名方案复盘。hipw,2026 年 9 月。
- AFAC2026 获奖频道|华中科技大学"Lucky"团队获挑战组二等奖。AFAC 官方公众号,2026 年 9 月 29 日。
- afac2026-financial-qa:Baseline 改进方案。GitHub,2026。
- LogicRAG: Retrieval Augmented Generation with Adaptive Reasoning Structures。arXiv:2508.06105v2,2025。
- SmartChunk Retrieval: Query-Aware Chunk Compression with Planning for Efficient Document RAG。arXiv:2602.22225v1,2025。
- RAG over Tables: Hierarchical Memory Index, Multi-Stage Retrieval, and Benchmarking。arXiv:2504.01346v4,2025。
- FAIR-RAG: Faithful Adaptive Iterative Refinement for Retrieval-Augmented Generation。arXiv:2510.22344v1,2025。