尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用Skill构建AI投研流程:从财报数据到投资备忘录的自动化实践

用Skill构建AI投研流程:从财报数据到投资备忘录的自动化实践 从去年开始我把日常投研里最耗时的那部分工作交给 AI 处理陆陆续续做了十几个用于选股、财报解读、行业对比、舆情分析的 skill到现在已经形成一套稳定可复用的流程。所谓 skill你可以理解成给 AI 写好的一份“岗位说明书”告诉它面对什么数据、按什么顺序、输出什么格式、用什么口径做判断。这篇文章把我踩过的坑、最终落地的方案、以及每一步取舍的原因全部写出来既适合刚接触 AI 投研的新手照着重现也适合已经在用 prompt 做分析、想升级成标准化 skill 的朋友做对照参考。1. 项目概述AI 投研场景与 skill 的切入点1.1 AI 投研到底在解决什么问题先说我手里真实的投研工作长什么样。我每天要看的东西大概包括目标公司的财报和业绩说明会纪要、行业政策动态、卖方研究报告摘要、产业链上下游数据、以及市场情绪指标。这些信息源数量巨大且格式混乱人工处理的话光是做第一步的信息清洗就要花掉一两个小时。AI 投研的核心价值不在于替你做投资决策而在于把“从信息到判断素材”的过程压缩到几分钟。具体来说我需要 AI 能完成这几类动作第一从财报原文里提取毛利率、净利率、现金流、运营资本变动等关键财务指标并和上一期做同比环比第二把非结构化的公告、新闻、纪要文本按照公司、业务线、时间线三个维度整理成结构化摘要第三对同一行业的几家公司做横向对比输出统一的对比维度表格第四根据财务数据和舆情信号给出风险提示清单。这些动作听着不复杂但用普通 prompt 写每换一家公司、每换一种数据格式都要重新调整提示词重复劳动太严重。把整套流程封装成 skill 之后输入变了、分析框架不变实用性立刻上来了。1.2 为什么选择 skill 而不是普通 prompt很多人问过同一个问题直接用一段写好的长 prompt 不行吗我的回答是行但只限于一次性任务。prompt 本质上是一段静态文本它的问题在于难以稳定地调用外部工具、难以约定多步骤的中间结果、难以对输出格式做强约束。而 skill 在设计上解决的就是这三个问题。我把 skill 理解为“prompt 代码 参考知识”的组合体。skill 内部可以声明自己需要调用的函数、可以定义参数和参数类型、可以嵌入一份或多份参考文档还可以指定执行时的步骤顺序。这意味着当我把一份财报 PDF 丢给 AI 时skill 会自动触发对应的解析脚本而不是靠模型“临时发挥”。用编程的类比来讲普通 prompt 是写一段注释让新手去猜怎么做skill 则是给出一份带类型定义、模块划分和默认参数的接口文档。对于投研这种对稳定性和一致性要求很高的场景后者显然更可靠。我在实践中还发现一个额外的好处skill 是可分发的。同一个 skill 文件发给团队成员谁运行结果都一样不需要每个人重新理解背景。这一点在多人协作做行业研究时尤其重要。2. 整体设计与方案选型我的投研 skill 架构2.1 关键模块怎么拆刚开始做的时候我犯过一个典型错误想在一个 skill 里塞进所有功能。既做财报分析又做新闻抓取还做估值比较结果就是代码臃肿、AI 经常调用错函数。后来我按照“数据获取、分析计算、报告生成”三层把能力拆开每个 skill 只负责一个环节。我当前的主 skill 体系分三个模块。第一层是数据获取层负责从公开数据接口拉取财务数据、从本地文件读取 PDF 或者 CSV、把非结构化文本做初步清洗。第二层是分析计算层负责实现具体的财务指标计算、增长率测算、行业排名等逻辑。第三层是报告生成层负责把分析结果转成 Markdown 格式的投资备忘录包含结论、数据附表、风险提示三个部分。这三个模块之间通过参数传递数据前一层输出是后一层输入互不越界。分层设计的好处很明显。一次只需要调试一个环节的问题出错了定位也快。更重要的是AI 在执行时会按声明顺序调用函数各层的输出格式是约定好的模型不容易在中途“自由发挥”分析结果的复现性大幅提高。2.2 工具链选型与取舍逻辑工具选型上我试过好几套方案最终固定下来的是这样一套组合核心运行时用支持 skill 机制的 AI 客户端程序代码用 Python财务数据获取优先用开源数据库和公开财经接口知识库文件以 Markdown 形式保存在 skill 的 references 目录下。Python 是我在这类场景下的首选理由很简单数据处理的生态成熟pandas 能做表格计算openpyxl 能生成 Excel 报告requests 能拉取网页数据。我不建议在 skill 里写太多自定义函数能用成熟库完成的工作就不要重复造轮子AI 在写代码的时候也更容易理解常见库的用法。有一个例外是研报里经常出现的复杂表格截图转文字这一步我试过好些 OCR 方案最终留下的是结构保持能力最好的那一个具体工具名字这里不做硬性推荐选型标准是“对表格结构识别稳定”。数据源方面有两点必须说明。第一国内上市公司的财报数据以巨潮资讯等官方披露渠道为准第三方聚合数据只做参考这是我吃了好几次数据打架的亏之后定下的规矩。第二拉取数据必须控制频率高频请求会被接口封禁我后来的策略是把原始数据缓存到本地skill 优先读取缓存而不是每次都现拉。注意不管用什么工具原始数据源一定要优先选官方公开披露渠道。第三方接口可以做交叉验证但不要作为唯一依据数据口径一旦出错后续分析全都会偏。3. 核心细节解析skill 文件结构与参数设计3.1 SKILL.md 约定与目录结构目前社区里比较常见的 skill 组织方式参考了 Anthropic 提出的 Agent Skills 约定核心是一个 Markdown 文件加若干辅助目录。我的每个投研 skill 都按这个结构组织根目录必须有 SKILL.md这是 skill 的“入口文件”里面写清楚这个 skill 是干什么的、什么情况下触发、需要哪些参数、执行分几步。代码放在 scripts 目录下可以是单文件也可以是多文件模块。参考资料放在 references 目录下可以是完整的分析模板、财务术语对照表、行业背景文档AI 在执行时会根据 SKILL.md 的指引有选择地使用这些材料。可选有一个 params 定义文件用 YAML 或 JSON 声明输入参数的类型、默认值、取值范围。SKILL.md 的开头部分是 AI 判断是否触发技能的关键所以描述写得越精确越好。我最初写的是“分析财务报表”太模糊结果 AI 经常误触发。后来改成“当用户提供上市公司代码或财报文本需要提取关键财务指标、计算同比变化、生成结构化投资备忘录时使用”触发准确率明显提升。3.2 关键参数与执行流程设计参数设计是 skill 的核心工程。拿我最常用的“财报分析” skill 举例它的输入参数包括股票代码或公司名字符串必填、分析期间字符串默认最近一期、是否生成 Markdown 报告布尔值默认 true、额外关注项数组可选。参数定义的好处是AI 在执行前就知道自己需要向用户索取什么信息而不是把缺参数的错误留到执行中途。执行流程在 SKILL.md 里用步骤列表写清楚一般控制在五步以内。我的标准步骤是第一步根据参数定位公司并获取对应财报数据第二步计算关键指标并保存中间结果第三步读取 references 目录下的分析框架模板第四步按模板组织分析内容最后一步生成投资备忘录。每步之间都有明确的数据接口约定前一步输出保存在工作目录下的临时文件里后一步读取这个文件继续处理。提示流程步骤不要超过七步。测试下来步骤太多时 AI 会开始“跳步”跳过中间结果直接给结论这是我最不能接受的宁可把一个大 skill 拆成两个更小的 skill。3.3 经验注入让 skill 在实战中更精准同一个小细节写法和不写法效果差别很大。比如同样是“计算毛利率”模型可能会用“营业总收入”做分母也可能用“营业收入”两者在某些公司口径下差得不少。我会在 SKILL.md 里明确写明公式和口径“毛利率 (营业收入 - 营业成本) / 营业收入其中营业收入取自合并利润表的营业总收入项”。更进阶一点的做法是把“常识判断”也写进 skill。比如分析一家消费类公司时我会在参考文档里注明需要考虑渠道库存周期分析一家 To B 软件公司时会注明需要关注递延收入的变化。这些背景知识模型未必不知道但在没有提示的情况下它经常会漏掉。参考文档的作用就是把这些行业隐性知识显式化。我还做了一个值得推荐的小设计每次 skill 执行完毕后自动生成本次分析的关键假设清单包括数据截止日、数据来源、重要口径选择。这样即使后面发现某个结论有问题也能回溯到是哪一步的数据或者假设出了偏差。4. 实操流程手把手构建一个可用的财报分析 skill4.1 搭建目录与初始化设置直接上实操。我们以构建一个实用的财报分析 skill 为例完整走一遍流程。首先在 skill 目录下创建文件结构fundamental-analysis/ ├── SKILL.md ├── params.yaml ├── requirements.txt ├── scripts/ │ ├── fetch_data.py │ └── analyze.py └── references/ ├── analysis_template.md └── terms_glossary.md第一步先写 params.yaml把所有外部输入先定下来stock_code: type: string required: true description: 上市公司代码如 SH600519 period: type: string required: false default: latest description: 分析期间默认取最近一期 generate_report: type: boolean required: false default: true description: 是否生成 Markdown 报告这里我刻意用“如 SH600519”来做示例而不是真实股票代码纯粹是格式演示。实际使用时候注意如果代码写错了AI 会因为查不到数据直接报错所以建议在技能内部再做一个代码格式校验的步骤。接着写 requirements.txt把 Python 依赖固定往下拉一两个小版本不要追求最新因为 AI 在自动写代码时对最新库的 API 不一定熟悉。我常用的依赖只有三个requests、pandas、openpyxl简单够用。4.2 编写 SKILL.md 与参数说明SKILL.md 是这个 skill 的大脑我把我最终定稿的简化版本贴出来你可以看到哪些部分是必须的--- name: fundamental-analysis description: 当用户提供上市公司代码或财报文本需要提取关键财务指标、计算同比环比变化、生成结构化投资备忘录时使用。也可以用于多公司横向财务对比。 --- # 财报分析 Skill ## 功能概述 本 skill 用于对上市公司财报数据做结构化分析输出财务健康度评价和风险提示。支持单公司分析和多公司对比两种模式。 ## 参数说明 - stock_code: 必填字符串上市公司代码。 - period: 可选字符串默认 latest。 - generate_report: 可选布尔默认 true。 ## 执行步骤 1. 使用 scripts/fetch_data.py 获取财务数据数据优先读本地缓存。 2. 使用 scripts/analyze.py 计算核心指标保存中间结果 JSON。 3. 读取 references/analysis_template.md 作为输出模板。 4. 按模板组织输出确保包含概览、关键财务指标表、同比分析、风险提示。 5. 如果 generate_report 为 true输出完整 Markdown 报告否则仅输出指标摘要。 ## 指标计算口径 - 毛利率 (营业收入 - 营业成本) / 营业收入 - 净利率 净利润 / 营业收入 - 资产负债率 总负债 / 总资产 - 营业收入同比 (本期营业收入 - 去年同期营业收入) / 去年同期营业收入 * 100% ## 注意事项 - 数据截至日期必须标注在报告开头。 - 所有结论必须标注数据来源。 - 如果指标变化超过 30%必须在风险提示中单独说明。这个文件的每个小节都有实际用途。指标计算口径是为了防止模型按自己理解的口径算执行步骤是为了规范流程顺序注意事项是我踩坑之后的经验沉淀。我建议你在自己使用的 skill 里也单独开一个“注意事项”小节把已知的坑明文写出来。4.3 编写财务分析执行脚本接着写核心脚本 fetch_data.py 和 analyze.py。fetch_data.py 负责数据获取核心逻辑是“优先读缓存、缓存没有再拉接口、拉完存缓存”import json import os from datetime import date CACHE_DIR ./cache def check_cache(stock_code: str, period: str) - dict | None: cache_path os.path.join(CACHE_DIR, f{stock_code}_{period}.json) if os.path.exists(cache_path): with open(cache_path, r, encodingutf-8) as f: return json.load(f) return None def save_cache(stock_code: str, period: str, data: dict) - None: os.makedirs(CACHE_DIR, exist_okTrue) cache_path os.path.join(CACHE_DIR, f{stock_code}_{period}.json) with open(cache_path, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2)这个脚本设计的关键是缓存目录声明和检查逻辑前置。实际测试里重复请求接口会有很大概率被限流缓存机制能把接口请求次数减少到原来的十分之一以下。analyze.py 负责计算指标用 pandas 创建数据框结构再逐项计算。脚本里不需要实现复杂的估值模型只计算 ambition 的基本面指标复杂判断留给模型来完成import pandas as pd def calculate_metrics(financials: dict) - dict: income pd.DataFrame(financials[income_statement]) balance pd.DataFrame(financials[balance_sheet]) revenue income[revenue].iloc[-1] cost income[cost_of_revenue].iloc[-1] net_profit income[net_profit].iloc[-1] total_assets balance[total_assets].iloc[-1] total_liabilities balance[total_liabilities].iloc[-1] metrics {} metrics[gross_margin] (revenue - cost) / revenue if revenue ! 0 else None metrics[net_margin] net_profit / revenue if revenue ! 0 else None metrics[debt_ratio] total_liabilities / total_assets if total_assets ! 0 else None return metrics这个脚本刻意保持简洁把所有非量化判断如行业周期、管理层评价留给模型层处理。投研分析的价值本来就不在于简单算数而在于对数字的解读。4.4 把分析模板固化到 referencesreferences/analysis_template.md 是输出呈现的关键我把报告结构固定下来防止每次生成格式都不一样# {公司名称} 财报分析备忘录 数据截至日期{date} 数据来源{source} 分析期间{period} ## 一、公司概览 简要介绍公司主营业务和本期财报亮点。 ## 二、关键财务指标 | 指标 | 本期 | 上期 | 同比变化 | |------|------|------|----------| | 营业收入 | | | | | 毛利率 | | | | | 净利率 | | | | | 资产负债率 | | | | ## 三、同比分析 对表中的每一项变化做归因分析说明可能的原因。 ## 四、风险提示 列出值得关注的财务风险信号包括但不限于现金流紧张、负债率快速上升、毛利率下滑、应收账款增速超过营收增速。用固定模板还有个好处当你的分析报告每次都长一个样久而久之你对异常数据的敏感度会明显提高。我做这个 skill 之前每次看公司报告都要重新组织一遍思路现在模板帮我省掉了这部分精力我把更多的注意力分配到风险提示那一段的深度分析上。注意报告里的数字必须保留完整计算过程说明。纯粹给出结果数字的 AI 分析一文不值因为读者不知道口径就不知道可不可信。5. 常见问题与排查技巧实录5.1 数据源不稳定与接口限流这是我在投研 skill 上遇到的第一个大坑。最开始做数据获取的时候我没有加缓存每次分析都会拉一遍接口。结果就是在连续分析几家公司之后接口拒绝服务skill 直接中断。排查思路很简单先看报错类型再查请求频率最后一招就是加缓存。现在我的数据层有两条铁律第一任何网络请求必须经过缓存中间层第二拉取数据失败时自动切换到备用公开数据源并在报告中标注入警示。这里要特别强调备用数据源切换后一定要在做同比计算前对齐口径不然很容易出现“两个数来自不同渠道结果差异根本分不清是经营原因还是口径原因”的情况。我自己的处理方式是在指标计算脚本里用同一套口径对原始数据做标准化不标准化不进分析环节。5.2 AI 幻觉导致的分析失真第二个大坑是模型幻觉问题。早期测试的时候我让 AI 分析某家公司的营收增速结果它编造了一个体面的数字看起来像模像样一核对原财报发现完全对不上。这种事在投研场景里是致命的。后来我在技能里增加了一条硬性规定模型只能引用脚本算出来的指标不允许自行“推算”任何数字所有财务数据必须标注来源。我还要推荐一个小技巧在模板的每个数字后面手动加一个“数据核对通过/待核实”标记字段让模型在生成报告时对每个数字做一次自我检查。虽然这个动作会增加一点 token 消耗但换来的是结论可信度的显著提升。宁可慢一点也不能要一份编数据的研究笔记。5.3 skill 被跳过或误触发第三个常见问题是模型在对话过程中绕过了 skill直接凭自己的知识回答。通常原因有二一是 description 写得不够具体模型不认为自己该出手二是对话上下文里用户的问题已经包含答案模型懒得走流程。排查思路就是回看 SKILL.md 描述和实际对话的触发语句看两者是否匹配。解决方式也简单在技能描述里把“触发条件”写得更窄但同时把所有可能触发的场景都枚举进去。例如不只是“分析报表”要触发用户说“这家公司值得买吗”“对比一下这两家公司的财报”“帮我看看这份年报”时也应该触发。我实测下来随着列举触发场景增多误触发率反而是下降的因为模型对是否调用技能的判断会更明确。5.4 快捷键速查常见问题与解决方向为了便于你对照我把投研 skill 日常维护中最常遇到的问题整理成一张表问题现象可能原因解决方向数据为空接口限流或代码错误检查缓存检查代码逻辑指标异常口径不一致或数据源不同统一口径标注来源报告格式乱模板未加载或步骤跳步检查 references 是否读取结论明显错误AI 幻觉强制引用计算脚本输出技能未触发description 不准确细化触发场景描述执行中断脚本报错查看报错信息补全依赖这张表是我在实际使用中一点一点积累出来的每次被坑之后我就补一行现在已经成了团队新成员上手投研 skill 的第一份参考材料。6. 后续扩展思路从单 skill 到多 skill 协作6.1 把完整投研流程拆成 skill 流水线单 skill 能解决的问题边界有限但随着你手里的 skill 越来越多会发现一个新的用法把多个 skill 串成一个流水线。我的做法是建立一个“投研主控” skill它不直接做分析而是负责任务调度。主控 skill 接到的任务按照拆解逻辑分发给不同的子技能行情数据、财报分析、舆情分析、行业对比。每个子技能的输出保存为结构化的中间文件主控再汇总所有中间文件生成最终研究报告。这样做的好处是各环节可以独立调试也可以在不同项目里复用。比如“舆情分析”这个 skill我既用于个股研究也用于行业研究前的信息摸底不需要为两种场景各写一套。本质上这借鉴了传统软件开发的模块化思想。投研分析的复杂性不可能被一个 AI 调用彻底解决但把它拆解成多个职责单一的 skill再由一个调度者统一组织AI 系统的工作质量就有了结构性的保障。6.2 团队协作时的版本管理与分享注意事项如果你打算把 skill 分享给团队伙伴使用还有几个实际问题值得注意。首先是版本管理我建议每个 skill 目录都用 Git 管理并且保持一份 CHANGELOG任何口径调整、步骤修改都要记录。这样做的好处是当某一次分析结果出了问题你可以迅速定位到是“哪一次改动引入的”。我吃过一次没做版本管理的亏改了一个计算口径旧报告全部作废当时没有记录花了大半天才回忆起来自己改了什么。其次是分享文档的写作问题。写 SKILL.md 给“未来的自己”看的时候要假设你是一个已经完全忘了上下文的陌生人。凡是省略过的背景、理所当然的约定、觉得别人肯定懂的口径全部写清楚。我在团队内部有一个朴素的规则一份 SKILL.md 如果不能在五分钟内让新成员读懂并跑通那就说明文档写得不合格。最后提一下多 AI 协作这个延伸方向。目前我已经尝试把投研 skill 同时接入多个不同的 AI 运行环境让它们用同一套 skill 各自生成分析报告再进行交叉比对。因为输出模板完全一致对比起来非常直观。这个方案比较适合需要高度严谨的场景虽然成本会翻倍但结论的稳健程度也会翻倍。我在实际使用中踩过不少坑最深刻的体会是不要让 AI 替你做“决策”让 AI 替你“准备决策所需的事实和推理”。一份好的投研 skill本质上是一套质量标准它锁定了数据从哪里来、口径怎么算、报告长什么样、风险从哪几个角度来提示。把这些标准固化下来之后你会发现 AI 投研这件事的确定性大大提升以前最担心的“这次结果能不能复现”现在变成了一个有规范流程保证的常态。
返回列表