位置:首页 > 进阶教程 > 审计知识库Agent化改造:从能查到能干的落地路径

审计知识库Agent化改造:从能查到能干的落地路径

时间:2026-08-21  |  作者:冻月看渠  |  阅读:0

摘要:传统审计知识库只能查条款,无法直接驱动工作流。本文介绍如何将知识库升级为"可执行知识库",通过技能封装、Agent调度和RAG增强,实现审计程序自动执行、风险自动识别与报告智能生成。

审计知识库的Agent化改造:从

一、为什么传统知识库不够用了

审计师的知识库建设,已经走过两个阶段。

第一阶段:文件柜时代

准则、解释、案例以PDF形式散落在硬盘和网盘中。需要时只能靠记忆定位文件路径,打开后再逐页翻阅。

一个条款查询平均耗时45分钟,还常常找不到原文出处。

第二阶段:检索库时代

借助OCR、向量索引和语义检索,审计师可以快速定位准则条款。查询耗时从45分钟降到8分钟,这是巨大的进步。

但检索库本质上仍然是"被动查询"。人提问,机器给答案,剩下的判断、执行、复核仍然依赖人工。

真正的成本不在"查",而在"干"。

查到存货跌价准备的适用条款后,审计师还要执行减值测试程序、收集证据、编制底稿、撰写说明、交叉复核。

这些环节占据了项目工时的80%以上。

可执行知识库试图解决这个痛点:让知识库不仅能回答"是什么",还能直接执行"怎么做"。

它的核心思想,是把审计知识封装成可被Agent调用的原子技能,再由Agent根据任务目标自动组合这些技能,形成完整的审计工作流。

二、可执行知识库的三层架构

可执行知识库不是对检索库的简单升级,而是架构层面的重构。下图展示了我们实践中的三层架构:

![image.png](https://developer.qcloudimg.com/http-sa ve/yehe-12479937/9af54a4db54d394b2b93f8aa03c34a15.png)

第一层:知识资产层

这是传统知识库的核心,包括准则原文、实务案例、程序模板、历史数据等。

与过去不同,这些资产需要进一步结构化。

  • 每条准则条款标注编号、适用场景、关联准则;

  • 每个实务案例标注行业、风险类型、处理结论;

  • 每个程序模板标注输入字段、输出格式、验证规则。

结构化的目的,不是方便人阅读,而是方便机器调用。

当Agent需要执行"应收账款坏账准备测试"时,它能自动找到对应的程序模板,读取输入要求,调用相关技能。

第二层:技能封装层

这是可执行知识库的关键创新。技能(Skill)是对审计程序的原子化封装,具有三个特征:

  • 输入明确:每个技能定义清晰的输入参数。例如账龄分析技能需要"应收账款明细表"和"账龄区间"。

  • 输出规范:每个技能输出标准格式的结果。例如账龄分析技能输出"分账龄金额表"和"应计提坏账准备"。

  • 可独立运行:每个技能不依赖特定项目上下文,可以在任何符合输入条件的场景下复用。

常见技能包括:账龄分析、截止测试、抽样、异常检测、准则引用、脱敏处理、报告生成等。

第三层:Agent调度层

Agent是任务编排器。它接收审计任务目标,拆解为子任务,选择合适技能,按顺序调用,最后组装结果并提交人工确认。

例如,面对"复核应收账款坏账准备是否充分"这一任务,Agent会执行以下步骤:

  • 调用"准则引用技能",获取CAS22关于预期信用损失的规定;

  • 调用"账龄分析技能",计算历史迁徙率和预期损失率;

  • 调用"异常检测技能",识别大额逾期、关联方欠款等异常;

  • 调用"底稿生成技能",输出坏账准备测试底稿;

  • 将结果汇总,标注需要人工判断的关键点,提交审计师终审。

三、从文档到技能:知识萃取实战

把审计知识封装为技能,最大的挑战不是技术,而是"知识萃取"。

一个资深审计师脑子里有很多隐性经验,但如何把这些经验转化为机器可执行的规则,是关键难点。

我们的做法是从具体项目出发,反向提炼通用模式。

以应收账款账龄分析为例。不同项目的明细表格式千差万别。

  • 有的按客户列示;

  • 有的按发片列示;

  • 有的账龄已经分好区间;

  • 有的只有发生日期。

传统做法是审计师每次手动清洗数据,耗时且容易出错。

我们萃取出的通用模式是:

  • 读取任意格式的应收账款明细;

  • 识别日期字段和金额字段;

  • 按资产负债表日倒推账龄区间;

  • 应用迁徙率模型或固定比例法计算坏账准备;

  • 输出标准化结果和异常提示。

这个模式被封装为"账龄分析技能",核心代码如下:

```python

import pandas as pd

from datetime import datetime

from dateutil.relativedelta import relativedelta

class AgingAnalysisSkill:

"""应收账款账龄分析技能:输入明细,输出账龄分布与坏账准备"""

def __init__(self, report_date: str):

self.report_date = datetime.strptime(report_date, "%Y-%m-%d")

self.buckets = [(30, "1个月以内"), (90, "1-3个月"),

(180, "3-6个月"), (365, "6个月-1年"),

(730, "1-2年"), (9999, "2年以上")]

def run(self, detail_df: pd.DataFrame,

date_col: str = "invoice_date",

amount_col: str = "amount",

provision_rates: dict = None) -> dict:

"""

执行账龄分析

:param detail_df: 应收账款明细表

:param date_col: 日期字段名

:param amount_col: 金额字段名

:param provision_rates: 各账龄段计提比例,如 {"1个月以内": 0.005, ...}

:return: 包含账龄分布、坏账准备、异常记录的字典

"""

if provision_rates is None:

provision_rates = {

"1个月以内": 0.005, "1-3个月": 0.02,

"3-6个月": 0.05, "6个月-1年": 0.20,

"1-2年": 0.50, "2年以上": 1.00

}

detail_df = detail_df.copy()

detail_df[date_col] = pd.to_datetime(detail_df[date_col])

detail_df["days_overdue"] = (self.report_date - detail_df[date_col]).dt.days

def classify_bucket(days):

for threshold, label in self.buckets:

if days <= threshold:

return label

return "2年以上"

detail_df["aging_bucket"] = detail_df["days_overdue"].apply(classify_bucket)

# 账龄分布

aging_summary = detail_df.groupby("aging_bucket")[amount_col].sum().reindex(

[b[1] for b in self.buckets], fill_value=0

).reset_index()

aging_summary.columns = ["账龄区间", "金额"]

aging_summary["计提比例"] = aging_summary["账龄区间"].map(provision_rates)

aging_summary["坏账准备"] = aging_summary["金额"] * aging_summary["计提比例"]

# 异常识别:逾期超过180天且金额大于10万元

anomalies = detail_df[

(detail_df["days_overdue"] > 180) &

(detail_df[amount_col] > 100000)

].copy()

return {

"report_date": self.report_date.strftime("%Y-%m-%d"),

"aging_summary": aging_summary.to_dict("records"),

"total_provision": aging_summary["坏账准备"].sum(),

"anomaly_count": len(anomalies),

"anomalies": anomalies[[date_col, amount_col, "days_overdue"]].to_dict("records")

}

# 使用示例

if __name__ == "__main__":

sample = pd.DataFrame({

"invoice_date": ["2026-05-10", "2026-02-15", "2025-08-20", "2024-12-01"],

"amount": [50000, 120000, 300000, 80000]

})

skill = AgingAnalysisSkill(report_date="2026-08-09")

result = skill.run(sample)

print(f"应计提坏账准备: {result['total_provision']:.2f}")

print(f"异常记录数: {result['anomaly_count']}")

```

这段代码的关键在于,它不接受固定格式的输入,而是通过参数化日期字段和金额字段来适配不同项目。

同时,它输出的是结构化字典,而不是仅供人阅读的表格,这让它可以被Agent进一步调用。

四、RAG增强:让技能知道"为什么这么做"

技能封装了"怎么做",但Agent还需要知道"为什么这么做"。

这就是RAG(检索增强生成)发挥作用的地方。

以坏账准备测试为例。账龄分析技能可以计算出结果,但它不会解释:

  • 为什么采用迁徙率模型而不是固定比例法;

  • 什么情况下需要单独计提;

  • CAS22对预期信用损失有哪些具体规定。

这些知识存储在知识资产层中,通过RAG在运行时动态注入。

具体流程是:

  • Agent接收到"复核应收账款坏账准备"任务;

  • 先调用RAG检索器,查询"CAS22 应收账款 预期信用损失";

  • RAG返回相关准则条款、解释公告、历史案例;

  • Agent把这些上下文作为参数,调用"准则引用技能"生成引用说明;

  • 同时调用"账龄分析技能"计算数据结果;

  • 最终把"数据结果 准则依据 风险提示"组装成完整底稿。

这种模式的核心价值在于,知识库一旦更新,依赖它的所有技能都会同步获得最新内容。

比如财政部发布新的金融工具解释公告后,只需在知识资产层完成一次更新,所有与坏账准备测试相关的技能和Agent就会直接基于新依据运行,无需逐一调整代码。

五、Agent调度:从单一技能到完整工作流

单个技能只能完成原子任务,真正的价值在于Agent对多个技能的编排。

下面是一个简化的Agent示例,展示如何调用上述技能完成"应收账款坏账准备复核"任务:

```python

class AuditAgent:

"""审计Agent:理解任务目标,编排技能执行完整审计程序"""

def __init__(self, knowledge_retriever):

self.retriever = knowledge_retriever

self.aging_skill = None

def set_report_date(self, report_date: str):

self.aging_skill = AgingAnalysisSkill(report_date)

def review_receivable_provision(self, detail_df: pd.DataFrame) -> dict:

"""执行应收账款坏账准备复核工作流"""

# 步骤1:检索准则依据

standards = self.retriever.search(

"CAS22 应收账款 预期信用损失 计提方法",

top_k=3

)

# 步骤2:执行账龄分析

data_result = self.aging_skill.run(detail_df)

# 步骤3:生成审计结论草稿

conclusion = self._draft_conclusion(data_result, standards)

return {

"准则依据": standards,

"数据分析结果": data_result,

"审计结论草稿": conclusion,

"需人工判断事项": self._flag_manual_items(data_result)

}

def _draft_conclusion(self, data_result, standards):

total = data_result["total_provision"]

anomalies = data_result["anomaly_count"]

return (

f"截至资产负债表日,应收账款按账龄组合计提坏账准备合计 {total:,.2f} 元。"

f"识别出 {anomalies} 笔重大逾期款项,建议单独进行减值测试。"

f"依据包括:{', '.join([s['metadata']['source'] for s in standards])}。"

)

def _flag_manual_items(self, data_result):

items = []

if data_result["anomaly_count"] > 0:

items.append("重大逾期客户是否需单独计提坏账准备")

return items

```

这个Agent没有使用任何大模型,完全依靠规则和结构化知识完成工作。

它的价值在于,把原本需要审计师手动串联的多个步骤自动化,同时保留人工判断的入口。

六、效率对比:从"人找知识"到"知识找人"

可执行知识库带来的效率提升,不仅体现在查询速度上,更体现在整个审计工作流的缩短上。

下图对比了人工模式与可执行知识库模式在四个核心环节的耗时:

![image.png](https://developer.qcloudimg.com/http-sa ve/yehe-12479937/663b8c8a2ae1ea5a4aea77d09346a92d.png)

  • 准则条款查询:45分钟 → 6分钟,提升87%

  • 审计程序执行:90分钟 → 18分钟,提升80%

  • 风险点识别:60分钟 → 10分钟,提升83%

  • 三级复核检查:90分钟 → 15分钟,提升83%

需要强调的是,这里的"审计程序执行"耗时18分钟,不是AI替代审计师做职业判断。

而是AI完成数据清洗、计算、底稿填充等重复劳动,审计师把精力放在异常识别和结论判断上。

七、落地避坑指南

在实际建设中,我们总结出五条关键经验:

1. 先建技能清单,再写代码

很多团队一上来就写代码,结果做出一堆无法复用的脚本。

正确的做法,是先用Excel或文档列出所有可封装的审计技能,明确每个技能的输入、输出、调用场景,再开始编码。

2. 技能必须输出结构化数据

如果技能输出的是Word或Excel文件,Agent就无法继续处理。

所有技能都应优先输出JSON或DataFrame,需要生成文档时再由专门技能负责格式化。

3. RAG检索质量决定Agent上限

Agent能调用多少正确知识,取决于底层检索器能否精准召回相关条款。

建议采用"关键词粗筛 向量精排 元数据过滤"的混合策略,而不是单一向量检索。

4. 保留人工终审入口

审计是责任行业,AI不能独立出具审计意见。

每个Agent的输出都应明确标注"已自动执行"和"需人工判断"两部分,后者必须经注册会计师确认。

5. 从高频、低风险的程序入手

不要一开始就尝试把完整年报审计流程自动化。

建议从账龄分析、截止测试、抽样、模板填充等高频、规则明确的程序开始,逐步扩展到更复杂的领域。

八、总结:五条行动要点

  • 知识库的下一代是可执行知识库:从"能查"升级到"能干",把审计知识封装为可被Agent调用的技能。

  • 三层架构是落地骨架:知识资产层、技能封装层、Agent调度层缺一不可。

  • 技能设计遵循输入明确、输出规范、可独立运行三个原则:这是Agent能够编排技能的前提。

  • RAG为技能注入"知识上下文":让Agent不仅知道怎么做,还知道为什么这么做,并能在法规更新时自动同步。

  • 始终保留人工终审:AI执行程序,专家承担责任,这是审计智能化的安全边界。

本文使用的核心技术栈:Python 3.13、pandas(数据处理)、RAG 检索、FAISS(向量索引)、sentence-transformers(语义编码)、Chart.js(数据可视化)

作者背景:从事审计、资产评估与财务咨询15年以上的资深专家,同时具备Python自动化开发能力。本文基于真实项目实践,代码示例可直接运行并扩展。

欢迎在评论区交流你的审计智能化经验。你认为审计工作中哪些程序最适合先被封装为技能?

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多