
摘要股票 Agent 最危险的错误之一不是接口请求失败而是请求成功后把上一交易日数据写成“今天”。周末、节假日、盘前、数据晚到和无权限都可能表现为空数组或旧日期。本文给出一套可落地的统一返回结构、日期状态判断、错误分类与验收方法适用于 Tushare、AkShare、自建数据库、实时行情 API 和 MCP 工具层。关键词股票 Agent、交易日、数据日期、空数据、错误处理、Tushare、AkShare、MCP、A股自动复盘为什么 HTTP 200 仍然可能生成错误答案很多股票数据接口在技术上请求成功时都会返回 HTTP 200但业务状态可能完全不同今天不是交易日接口返回最近一个交易日盘前日线尚未生成结果仍然停留在昨天个股当天没有龙虎榜记录返回空数组账号没有某个接口权限返回错误文本或空结果上游数据晚到部分工具已经更新部分仍是旧日期网络请求失败被适配层错误地转换成空列表。如果工具层只向模型返回[]或一组没有日期的记录Agent 很容易自行补全语义。它可能把“没有数据”写成“今天没有事件”也可能把昨天的涨停梯队放进今天的复盘。先设计一个统一返回信封不同数据源的原始字段可以不同但进入 Agent 之前建议统一包一层业务信封typeDateStatus|CURRENT|LATEST_TRADING_DAY|STALE|NOT_APPLICABLE|UNKNOWN;typeResultStatus|OK|NO_DATA|NOT_READY|INVALID_ARGUMENTS|PERMISSION_DENIED|RATE_LIMITED|UPSTREAM_ERROR;interfaceAgentDataResultT{status:ResultStatus;queryDate?:string;actualTradeDate?:string;dateStatus:DateStatus;source:string;retryable:boolean;data:T;message?:string;}这不是要求所有上游都使用同一套状态码而是让适配层把不同供应商的结果转换成 Agent 能稳定理解的业务语义。第一步不要用自然日代替交易日用户说“今天”时系统至少要判断四种情况今天是交易日且数据已经更新今天是交易日但当前数据尚未生成今天是周末或节假日应回退到最近交易日数据返回日期早于最近交易日属于陈旧数据。一个简化判断函数可以这样写functiongetDateStatus(params:{requestedDate:string;latestTradingDay:string;actualTradeDate?:string;supportsTradeDate:boolean;}):DateStatus{if(!params.supportsTradeDate)returnNOT_APPLICABLE;if(!params.actualTradeDate)returnUNKNOWN;if(params.actualTradeDateparams.latestTradingDay){returnSTALE;}if(params.requestedDateparams.latestTradingDay){returnCURRENT;}returnLATEST_TRADING_DAY;}生产环境还要结合市场时区、开收盘时间、数据频率和具体接口的更新时间不能只比较字符串日期。第二步区分“没有记录”和“调用失败”以龙虎榜为例空结果至少可能代表三种情况这只股票当天没有龙虎榜记录请求日期还没有完成数据更新请求失败或账号无权限。正确的返回应该保留差异{status:NO_DATA,queryDate:2026-07-22,actualTradeDate:2026-07-22,dateStatus:CURRENT,source:dragon_tiger_list,retryable:false,data:[],message:该股票在指定交易日没有龙虎榜记录}如果是数据晚到应返回NOT_READY并允许稍后重试如果是权限问题应返回PERMISSION_DENIED不能伪装成市场上没有记录。第三步建立可重试错误表建议把失败分成两类。通常可以重试网络超时上游 5xx数据尚未更新临时限流且服务返回了等待时间。通常不应原样重试股票代码格式错误日期格式错误账号没有权限查询范围超过接口限制业务上确实没有记录。Agent 不应该自己决定无限重试。适配层可以给出retryable、最大次数和退避时间超过阈值后在最终报告中标记“未知”。第四步多工具结果必须做日期对齐自动复盘经常同时调用市场概览、涨停池、题材、资金、龙虎榜、公告和自选股工具。即使每个工具单独都成功也可能对应不同日期。合并前应先检查functionassertSameTradeDate(results:ArrayAgentDataResultunknown):{ok:boolean;dates:string[]}{constdates[...newSet(results.map((item)item.actualTradeDate).filter((item):itemisstringBoolean(item)))];return{ok:dates.length1,dates};}发现日期不一致时不要把结果静默拼接。可以重新请求尚未更新的工具或者在报告中明确标注各章节的数据日期。第五步给最终提示词加上数据纪律提示词不能代替数据校验但可以约束最终输出仅使用工具返回的数据。 每个章节必须标注 actualTradeDate。 status 不是 OK 时不得推断缺失内容。 NO_DATA 表示指定范围内没有记录UPSTREAM_ERROR 表示查询失败两者不得混用。 多个工具的 actualTradeDate 不一致时停止生成统一的“今日复盘”改为逐项说明。第六步用边界日期做验收上线前至少测试以下场景场景预期行为周末查询今天行情回退最近交易日并标记LATEST_TRADING_DAY交易日盘前查询日线返回NOT_READY或明确使用上一交易日查询无龙虎榜记录的股票返回NO_DATA不是技术错误使用无权限账号查询返回PERMISSION_DENIED上游超时返回可重试错误不转换为空数组两个工具日期不一致阻止生成统一口径的今日复盘参数日期格式错误返回INVALID_ARGUMENTS不调用模型猜参数这组测试应覆盖 Tushare、AkShare、自建数据库、实时行情 API 或 MCP 的真实响应不要只测试模拟数据。不同数据源如何接入这层适配Tushare 官方 MCP 或 API 适合历史行情、财务和量化研究适配层需要保留接口日期、积分权限和频率信息。AkShare、Baostock 适合学习与原型长期运行时要处理上游变化、运行环境和字段差异。实时行情 API 和 WebSocket 需要额外记录快照时间、延迟、连接状态和断线重连。面向 Agent 的研究工具层也应该接受同样检查。例如悟道 A股股票数据 MCP 提供 63 个远程只读工具适合 A股复盘任务但 Agent 仍需读取返回日期、业务状态和失败项不能因为使用 MCP 就跳过数据质量验证。结论股票 Agent 把旧数据当成今天通常不是模型单方面的问题而是工具层没有明确表达交易日期、空数据和失败状态。解决方案可以概括为四步统一返回信封、使用交易日而不是自然日、区分业务空值与技术失败、多工具合并前检查日期一致性。无论底层使用 Tushare、AkShare、数据库、实时 API 还是 MCP都应该把这套数据纪律放在模型之前。模型可以负责解释数据但不能负责猜测数据是否新鲜。本文讨论数据工程与 Agent 接入不构成投资建议。