news 2026/10/13 16:37:06

手搓百亿token投资Agent:大模型投研落地全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手搓百亿token投资Agent:大模型投研落地全解析

前段时间在一个内部模拟项目里,我决定不走现成的SaaS,也不套开箱即用的Agent框架,从底层开始手搓一个投资agent。系统前后积累的语料、训练和运行轨迹加起来到了百亿token级别,模型调度、数据清洗、工具调用、仓位计算、风控回测全部在一套自建链路里跑。趁着这些坑还热乎,我把这个agent到底怎么工作的一次性拆完,尤其是一些被文档和Demo掩盖掉的反直觉细节。

这个投资agent做的事情很简单:把“投资研究员+交易员”的部分日常工作自动化。它接收新闻、财报、行情等数据,调用各种分析工具,最后输出带有置信度的结论和建议。它不只是一个会聊天的机器人,而是一个能自主规划任务、操作函数、读取结构化数据的完整系统。如果你正在琢磨大模型怎么落地到投研、量化或其他决策类场景,这篇文章应该能帮你少走很多弯路。

1. 为什么是“百亿token”,为什么是“手搓”

1.1 投资agent到底是个什么东西

很多人一听到“投资agent”,第一反应是让大模型看看行情图然后告诉我买什么。实际上这个定位太模糊,也太危险。一个真正能用的agent,至少要完成四件连续的事情:感知信息、拆解目标、调用工具、输出带约束的决策。这里面每一步背后都有对应的工程模块,任何一个环节掉链子,结果都是不可用的。

我做的这个agent,核心是把大模型当作“调度中枢”而不是“答案生成器”。大模型负责理解任务、判断需要什么数据、决定调用哪个工具、组织最终结论。而具体的数字、事实、行情快照,全部从外部工具拿,不让模型自己凭记忆编。这套思路上手之后,你会发现投资agent其实就是一个“长着大模型大脑的自动化投研流水线”。

投研场景比其他Agent场景更难的地方在于,信息时效性极强。昨天的数据可能今天就失效,财报数字差一个零,结论就完全反过来。所以agent必须对时间戳极度敏感,对数据来源极度较真。这意味着很多通用Agent框架里好用的东西,到了投研场景反而要重新设计。

1.2 “百亿token”到底意味着什么

先解释一下token的概念。token是模型处理文本的基本单位,一个token可以是一个词的一部分、一个完整单词,也可以是一个汉字片段。中文百亿token,换算过来大概是几十亿到上百亿个汉字,相当于把几万份财报、几十万篇新闻、上百万条公告和研报里的文字全部喂给模型。

这些数据不是一次性填进提示词里的。模型有上下文窗口限制,不可能把百亿token都塞进一次推理里。真正的用法分两条线:一条线是离线训练,把海量语料做继续预训练和指令微调,让模型“懂行话、懂格式、懂工具调用”的底层能力变强;另一条线是在线运行,每次决策只抽取出最相关的几十万token进上下文,用检索和工具调用把信息密度提高。

所以“百亿token”不是指一个模型吃了百亿长度的一次性输入,而是指整个系统在训练和运行层面累计消耗的语料总量。这个量级的好处是,覆盖的公告、研报、新闻类别足够多,模型对各种边缘表达都有了基本认知。缺点是数据清洗工作量非常大,占到整个项目一半以上的工时,这点后面详细说。

1.3 为什么必须手搓,而不是买现成的

市面上的金融大模型和Agent平台越来越多,但在我这个场景里,直接用现成品有几个绕不过去的问题。第一是可控性,投资agent的错误代价极高,我需要能审计每一次调用、每一个参数、每一行逻辑,现成黑盒产品很难做到。第二是数据隔离,内部整理的语料和策略特征不想经过外部不可控的服务,自建链路才可以把隐私边界牢牢攥在自己手里。第三是可变现,投资场景的字段、术语、风控规则高度定制,通用产品调整起来的成本往往比从头做还高。

手搓最大的好处是透明。模型为什么调这个工具、为什么拒绝回答、为什么给出这个置信度,每一个环节都有日志可查。模型出问题的时候,你能直接定位到是prompt写得不清楚、微调数据不够、还是工具返回格式有歧义。这种可观测性在投研场景不是加分项,而是刚需。

当然,代价也很明显。数据管道要自己搭,模型微调要自己跑,工具和风控要自己写,排错周期长,对人的综合能力要求很高。如果你只是想快速验证思路,那完全可以先用现成框架;但如果目标是长期可靠地跑,手搓这条路带来的积累是不可替代的。

2. 地基:语料清洗与训练配方

2.1 数据源选择与接入

投资agent的上限不是模型决定的,而是语料决定的。我最初收集的数据覆盖了公告、定期报告、券商研报、新闻流、行业数据和行情快照,累计处理了大概几TB的原始文本。数据源的选择逻辑很简单:凡是会影响投资决策的信息,都应该有对应语料;凡是噪音太大或者无法溯源的数据,宁可不要。

接入方式多种多样,有API接口,有离线文件包,也有需要自己解析的网页结构。所有源都会统一转成JSONL格式,字段固定为id、timestamp、source、title、content、meta。这里的timestamp是重中之重,投资信息有强时效性,没有时间的文本会污染整个训练集和决策链路。meta字段里会记录原始来源、抓取时间、解析版本,用于后续溯源和审计。

每天的增量更新机制也必不可少。初版我试过全量重跑,既慢又浪费。后来改成每日增量拉取,新数据进入待清洗队列,清洗完再合并进总库。这样从源头保证信息新鲜度,也让百亿token级别的大库可以持续滚动增长,而不是越跑越脏。

2.2 清洗和质量筛选

原始文本的噪音比例远超想象。公告里的表格模板、研报页眉页脚、网页里夹带的广告和推荐位、新闻评论区,这些内容直接进模型完全是灾难。清洗的第一步就是去掉这些模板和乱码,再剔除纯图片、纯表格的无效文本,最后把长文本按段落切块并补齐缺失字段。

重复数据是另一个大坑。同一个公司公告会被多个源转载,同一篇新闻会有几十个版本。如果不去重,微调模型会被重复样本带偏,在线检索也会召回一堆几乎一样的内容,白白浪费宝贵的上下文空间。我用的是MinHash近似去重,先把文本分块做指纹,再通过局部敏感哈希找出重复项。这套方案对百亿级语料来说足够快,准确率也在可接受范围内。

清洗完之后还需要做质量打分。打分维度包括:文本可读性、信息密度、行业相关性、时效性、是否包含具体数字和日期。低于阈值的片段直接丢弃。整个处理下来,原始数据大概会淘汰掉一半以上。很多人觉得数据越多越好,我的经验是,投资场景里十份高质量公告胜过一千份没营养的口水文章。

2.3 训练样本组织:从“问答”到“决策过程”

清洗后的文本不能直接用来训练agent。Agent需要的不只是“看懂文本”,还需要学会“用工具完成任务”。所以需要把语料重组成三种类型的样本。第一类是领域继续预训练样本,直接喂清洗后的原始文本,让模型熟悉财务术语、公告格式和行业黑话。第二类是指令微调样本,格式是“用户问题-工具调用序列-最终回答”,模型要照着完整的决策链路去生成。第三类是工具调用样本,专门训练模型在特定条件下选择正确工具并生成合法参数。

第三类是最费功夫的。一条典型样本长这样:用户问“某公司最近一个季度营收增速怎么样”,模型应该先判断需要财务数据,于是调用财报查询工具,传入标的代码和报告期,拿到返回结果后再做计算,最后用自然语言总结。这个过程里,工具调用的JSON格式必须完全正确,参数不能多不能少,日期和单位必须精确。

为什么要费劲做这种微调而不是靠prompt让模型现学现用?因为测试下来,没有经过微调的模型在function calling上的表现非常不稳定。它经常把不存在的字段填进参数,或者漏掉必填项,甚至自己编一个工具出来。用高质量微调样本约束之后,输出格式的合规率有质的提升,这也为后面减少幻觉打下了基础。

3. 投资agent的四层骨架:感知、规划、工具、记忆

3.1 一次完整决策的运行链路

整个agent的架构,拆开看是四层:感知层、规划层、工具层、记忆层。感知层负责接收外部信号,比如新闻推送、行情快照、定时任务触发;规划层由大模型驱动,负责把目标拆解成子任务;工具层提供所有实际能力,比如查询、计算、执行代码;记忆层负责在长期跨度上保留状态和经验。

一次完整的运行链路大概是这样的:感知层检测到某只标的发布了财报,于是生成一个“财报解读”任务。规划层拆解出三个子任务:读取财务数据、对比历史数据、计算关键指标。接下来工具层依次执行财务数据查询和历史数据查询,返回结构化结果。最后模型把结果组织成结论,附上置信度和风险提示,写入运行日志。

这个链路最关键的地方在于,模型不是一次性输出所有内容,而是每走一步都看一眼工具返回的结果再决定下一步。这是一个自反馈循环,而不是简单的“输入问题,输出答案”。自反馈的好处是,如果某个工具调用失败,模型可以重新规划策略,而不是将错就错继续编。这在投资场景里极其重要。

为了让大家直观感受,我贴一段高度简化的调度伪代码,真实系统远比这个复杂,但核心骨架就是这样。

def run_agent(task): plan = llm_plan(task, memory.retrieve(task)) for step in plan: if step.type == "tool": result = call_tool(step.tool_name, step.params) if not result.success: step = llm_replan(step, result.error) elif step.type == "reason": context = summarize(plan, result, memory) answer = llm_reason(context) memory.save(step, result, answer) return final_answer(answer)

3.2 function calling:工具层的接口设计

工具层是agent的手和脚。在大模型场景里,工具调用通常通过function calling实现,模型根据工具描述生成一个结构化的调用请求,系统执行后再把结果返回给模型。这里有一个核心设计原则:工具数量要少而精,接口要统一。

我最初接了二十多个工具,后来砍到十二个。工具太多,模型的选择准确率会下降,描述文档也会占用上下文。每个工具的描述要写得非常具体,包括用途、入参、出参、示例,甚至包括常见坑点。比如行情查询工具,描述里要说明“输入统一使用某标准代码,日期使用YYYY-MM-DD格式,若停牌则返回状态字段”。

工具返回格式也必须标准化,我统一用JSON结构:status表示成功或失败,data存放结果,error存放错误信息。这样模型无论拿到什么工具的结果,都能用同一套逻辑处理。失败的返回里会带上错误原因和可能的修复建议,比如“日期格式不正确,请检查”,这能显著降低模型重试时反复犯同样错误的概率。

还有一个容易忽略的点:工具权限边界。某个内部工具可以执行一段简单的Python脚本,但运行环境和依赖库都是受控的,脚本禁止访问网络、禁止写任意文件、禁止超过单次5秒执行时间。这种硬限制能防止模型在调试过程中产生无法预料的副作用。投资agent的工具调用发生在真实系统里,防呆设计必不可少。

3.3 记忆系统:短期上下文与长期经验档案

大模型本身没有记忆,它只能看到当前上下文里的内容。要让agent看起来有连续性,必须自己建记忆系统。我把它拆成两层:短期上下文和长期经验档案。

短期上下文解决的是“当前这个任务里,前面做了什么”。比如分析一只股票,前半段已经查了财务数据,后半段就不需要重新查一遍。做法是维护一个任务级的状态记录,把已调用的工具、已拿到的重要数据、已得出的中间结论都写进去。上下文快满的时候,会对早期内容做摘要压缩,只保留关键数字和结论,丢掉原始文本。

长期经验档案解决的是“类似的历史场景下,我们吃过什么亏”。做法是把每次决策的关键要素存进向量数据库,要素包括事件类型、市场环境、当时的核心数据、最终结果、复盘反思。当下一次任务到来时,先用向量检索把最相似的历史经验捞出来,拼进提示词,让模型参考。

这个设计对投资场景特别有用。比如模型之前处理过一次“高营收增长但毛利率下滑”的案例,最后市场反应偏负面;下次再遇到类似公司财报,长期记忆就能提醒模型不要单纯因营收增速高就给乐观结论。这种能力不是预训练能带来的,而是必须靠运行中积累出来的。

4. 决策质量怎么控:幻觉约束与仓位计算

4.1 事实性约束与拒绝机制

大模型在没有外部约束时,会自信地编造数字。投资场景绝对不能让模型自由发挥,这是整个系统里最重要的一条经验。我的做法是给模型立下三条硬规矩。

第一,所有具体数字必须来自工具返回结果,不允许使用模型自身记忆里的数值。在系统提示词里明确写着:“当你需要引用营收、利润、增长率、价格等数据时,必须先通过工具获取;如果工具没有返回对应数据,请明确标注缺失,而不是猜测。”这条规矩不完美,但能挡住绝大多数幻觉。

第二,关键结论需要交叉验证。比如判断一个公司是否符合高增长特征,财务表里查到营收增速是40%,那么计算增速用的同比基数和本期数必须来自同一次工具返回,不能从不同来源拼凑。系统会单独跑一个校验器,检查结论中的关键数字与工具返回的原始数字是否一致,不一致则打回重算。

第三,拒绝机制。当关键数据缺失、工具调用连续失败、或者模型置信度低于阈值时,模型必须输出“需要更多信息”或“建议人工复核”,而不是硬给一个结论。刚开始我觉得这样会让agent显得很笨,后来发现这是它最聪明的设计。投资里没有把握时说“不知道”,价值远大于瞎猜一个看似精确的方向。

4.2 仓位计算与硬编码风控

投资agent不能只给方向,它最终要给出操作建议。如果建议涉及仓位,就必须有可计算、可验证的规则。我的做法是把模型输出和实际仓位建议彻底解耦:模型只负责生成方向判断和风险描述,真正的仓位比例由独立的规则模块计算,不让模型直接给出数字。

仓位计算逻辑大致是这样:先为每个标的风险设定一个可容忍的亏损预算,然后用标的的历史波动率除以这个预算得到基础仓位上限;如果多个标的高度相关,会做相关性惩罚,进一步降低各标的的仓位权重;最后再把结果限制在硬性最大仓位之下,比如单一标的不超过组合的一成,单一行业不超过三成。这套逻辑不是让模型去理解,而是把模型输出作为输入,由规则模块机械计算。

与模型输出解耦之外,还需要硬编码风控层。这个风控层独立于大模型存在,是最后一道闸门。无论模型怎么输出,只要风控层判断超出预设条件,比如标的价格波动触发异常阈值、组合回撤超过某一比例,就会强制降仓或拒绝执行。模型可以犯错,但硬风控不能让模型把整个组合拖下水。

这里想强调一个底层观念:模型的本性是生成文本,不是计算最优组合。在任何涉及资金的场景里,都不应该让模型直接输出可直接执行的交易指令,至少要做一层独立的规则校验和强制执行。这不是对模型能力的不信任,而是对复杂系统失控概率的必要敬畏。

4.3 回测环境:防止未来函数是底线

一套agent策略上线前,一定要在历史数据上回测。但回测里有一个特别阴险的坑,叫作未来函数。未来函数指的是你在回测的某一天,用了那一天之后才产生的数据。看起来像是指标更准了,实际上是在作弊,实盘时不可能复现。

举个例子,一篇财报解读新闻本来可能是在当日收盘后发出,如果回测系统把它当作当日盘中可获取信息来决策,就会过分乐观地假设能提前得到信息。为了杜绝这个问题,系统里给每条数据都打上了严格的可获得时间戳,回测引擎只允许读取“决策时点之前”的数据,任何未来信息在那一刻都不存在。

撮合环节也要做细。不能简单假设“想买就能按收盘价成交”。真实市场里有涨跌停、停牌、成交量限制和冲击成本。我的回测引擎把这些因素都建模进去:成交量不超过当日平均成交量的某一比例,涨停时买入单会被拒绝,数据不足的标的不参与回测。这些约束会让结果看起来没那么漂亮,但真实感强得多。

对回测结果的态度,我的经验是:如果回测里的年化收益高到离谱,比如比同期的市场基准高出几倍,那么大概率不是策略牛,而是回测某个环节出了bug,比如未来函数、幸存者偏差或者过拟合。先检查数据时间戳,再检查撮合逻辑,最后再怀疑策略本身,这个排查顺序能省很多时间。

5. 真正跑起来之后踩过的坑

5.1 工具调用幻觉比想象中严重

即便是微调过的模型,在真实运行中还是会出现工具调用幻觉。最典型的场景是,模型生成了一个看似合理的工具调用,但里面参数是编的。明明标的不存在某个财务字段,模型还是传了一个自创的字段名进去;明明某天没有交易数据,模型却自动生成一条“停牌”描述来解释空缺。

排查这类问题,一定要把每次工具调用的日志完整记录下来。我会记录调用的工具名、全部参数、返回结果、耗时、错误信息。一旦发现异常参数,就把当时的上下文截取下来,放回模型里做采样测试,看是不是稳定复现。如果稳定复现,说明训练样本里缺少这类边界情况的负样本,需要在微调数据里补充“工具不可用时的正确拒绝方式”。

另一个有效手段是加一层执行前校验器。所有的工具调用参数都要先过校验器,校验器里写清楚每个参数的类型、枚举范围、必填条件。参数不合法直接拦截,返回错误信息给模型,而不是带着错误参数执行真正的工具。这个拦截层成本很低,但能把工具调用幻觉造成的破坏限制在系统边界之内。

5.2 上下文爆炸与token成本失控

投资agent跑起来之后,我发现最大的性能瓶颈不是模型算得慢,而是上下文太长。每次决策都要查新闻、调财报、算指标,如果把这些过程全量塞进模型上下文,一轮任务下来很容易冲到几十万token。推理时间变长,费用变高,模型对早期内容的注意力也下降。

解决办法是把“检索”和“理解”分开。第一步先从新闻库和财报库里做召回,拿回大量候选结果;第二步用一个轻量级的rerank模型对候选结果排序,只保留最有价值的8到15条进入最终上下文;第三步把工具返回的长表格先压缩成摘要,摘要只保留关键数字、日期和结论。经过这三步,同样一个任务,上下文能从几十万token压到几万token,速度和成本都明显改善。

压缩的时候有一个禁忌:摘要不能丢数字。做摘要的模型我要它强制保留所有具体数值和日期,只删掉修饰性语言。因为投资决策对数字极其敏感,营收从10亿变成10.1亿可能改变结论,压缩模块如果自作聪明地四舍五入,会把整个分析带偏。这个细节如果没人提醒,很容易被忽略。

5.3 回答不稳定:低温、多数投票与校准

同样的输入,模型跑两次可能给出完全不同的结论,这在投资场景里是致命的。投资分析要可重复、可复核,不能像一个情绪化的人一样今天看多明天看空。刚开始时我把温度调到0.1,发现还是不够稳定,因为采样过程本身还有随机性,而且模型的内部状态在不同请求下依然存在微小差异。

后来我引入了一套“决策投票”机制:每次任务让模型独立跑5次,每次用不同的采样顺序和随机种子,然后对结论进行分层投票。第一层是方向投票,大家是看多、看空还是中性;第二层是幅度投票,如果方向一致,再看置信度高低;第三层是冲突检测,如果5次结果分歧太大,系统判定为低置信度情况,自动转人工复核或标记为不确定。

这套机制的效果是,单次模型的随机波动被平均掉了,最终输出的稳定性大幅提高。代价是推理成本变成原来的5倍。但投资场景下,稳定性比成本重要得多。我还把每次投票的原始结果都保存在日志里,随时可以复盘某次结论为什么是多数派、少数派当时的观点是什么,这对后续调优非常有价值。

6. 百亿token之后:还能往哪走

这个agent做到现在,最大的收获反而不是模型多聪明,而是整个系统的“克制”。它知道什么时候该查数据,什么时候该拒绝回答,什么时候该让人来拍板。单纯让模型变得更强的边际收益,已经远不如给系统增加正确的约束来得大。

接下来我计划做三件事。第一,给每个决策结论加归因分析,到底是哪个数据、哪个历史经验导致了最后的判断,让决策链路更加透明可解释。第二,在多个独立agent之间引入对抗辩论,一个负责看多,一个负责看空,最后由仲裁模块给出综合结论,这比单个agent的自言自语更稳。第三,继续扩充另类数据,比如供应链、舆情情绪、地区事件等结构化弱相关的信息源,让agent的感知范围更宽。

最后分享一个调试小技巧,非常管用。排查问题的时候,先把所有工具调用都关掉,让模型只基于纯文本做分析,观察它的输出风格和错误模式;然后逐个打开工具,每打开一个就记录它对最终结果的边际贡献。哪一层引入之后出现了明显的问题,问题往往就在那一层的工具描述、返回格式或校验逻辑上。这个方法能快速定位到浪费token和引入幻觉的环节,比盲目调prompt高效得多。

如果你正准备在类似方向上做一些尝试,我的建议是不要急着追求大模型,先想清楚你的agent每一步能调用什么、不能调用什么、拿到结果之后怎么验证。把边界划清楚,剩下的工作都是在边界之内不断打磨。百亿token只是一个数字,真正值钱的是这些token背后,你如何看待“AI能做什么”和“AI不该做什么”之间的那条线。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 16:36:00

固定资产管理之—硬件产品的分类

企业固定资产品类繁杂:办公电脑、工控设备、仪器仪表、货架机具、IT 硬件、精密配件,传统人工盘点耗时耗力、错盘漏盘频发、资产去向无从追溯。随着数字化资产管理普及,RFID 标签打印机、RFID 发卡器、手持数据采集器、RFID 通道门四款核心硬…

作者头像 李华
网站建设 2026/10/13 16:35:30

DeepSeek Harness桌面端:本地大模型离线推理工具

我无法根据当前输入内容生成符合要求的博文。 原因如下: 输入中仅提供了项目标题 "DeepSeek Harness 桌面端来啦!更便捷更安全的选择" ,但未提供任何实质性的【项目正文】、【关键词】或【摘要描述】。 标题本身属于典型的产品…

作者头像 李华
网站建设 2026/10/13 16:32:53

脑电功率谱与多尺度熵分析的MATLAB实现:从Welch法到MSE特征提取

简介:面向脑电信号分析和生物医学工程研究者的多尺度熵(MSE)与功率谱分析工具包,由经典C代码重写为MATLAB实现,支持从Brain-atlas III等设备读取脑电数据,完成多尺度熵计算、粗粒化、样本熵估计、频谱分析与…

作者头像 李华
网站建设 2026/10/13 16:31:35

SSM+Flask混合架构博客系统:设计、部署与智能推荐实践

博客系统这种项目,网上搜一套SSM源码很容易,但同时把JavaSSM和Python Flask凑一起做成一个完整系统的,还真不多见。今天我想聊的这套项目,就是我实际用过、也带人复现过的基于JavaSSMFlask的博客系统,里面包含了源码、…

作者头像 李华
网站建设 2026/10/13 16:31:04

rtk 把 git log 压缩 98%,LLM 调用成本优化实战

做 AI 辅助代码分析的人,大概率都经历过这种尴尬:仓库一拉,git log输出几万行,还没等模型真正分析,光 token 费就烧掉一大截。我试过在某个模拟项目上直接拿原始日志喂模型,一次全量分析跑下来,…

作者头像 李华
网站建设 2026/10/13 16:29:27

AI Agent上线后持续优化:质检、自学习与排障的协同体系

1. 上线只是起点:AI Agent 持续优化的整体设计思路很多团队把 AI Agent 的上线当成项目终点,觉得灰度跑完、指标达标就万事大吉。我见过太多这样的案例:上线第一周效果惊艳,第二周开始用户投诉变多,第三周业务方开始质…

作者头像 李华