1. 为什么 Agent 做股票分析,卡点从来不在提示词
很多人第一次让 AI Agent 做股票分析,都会先写一大段提示词,比如「帮我复盘今天 A 股市场,重点看涨停梯队、主线题材、资金方向和明日观察」。写完发现输出要么是空话,要么数据对不上,于是继续改提示词,改到第十版还是不稳。
问题不在提示词。AI Agent 接股票数据源这件事,本质是让 Agent 稳定拿到结构化数据。提示词只是告诉它「要什么」,真正决定输出质量的是「它能不能拿到、拿到的字段对不对、日期是不是最新的」。我试过把同一段复盘提示词分别喂给「能调数据工具」和「只能靠模型记忆」的 Agent,前者能列出具体涨停家数和连板梯队,后者只能给一段听起来很顺但没有日期的市场描述。
所以这条链路的正确拆法是三层:数据源层(Tushare / AkShare 这类取数库)、工具层(MCP 把取数能力暴露成 Agent 可发现的工具)、调用层(统一 Key 与鉴权,让 Agent 每次调用都有边界)。本文就按这三层走一遍,给出可复制的 MCP 工具定义、数据源适配配置和统一 Key 调用示例,最后做一次端到端行情查询验证。
适合谁看:正在用量化投研 Agent、想让 Codex / Cursor / 自建 LangGraph 服务直接查 A 股行情的开发者;已经会用 AkShare 写脚本、但每次都要重新解释接口的人;以及想把内部取数逻辑封装成受控工具、又不想维护一整套后端的团队。
先说清楚边界:本文只讨论数据接入与研究,不涉及任何下单执行,也不承诺收益。股票数据工具应该明确写清「不执行交易、输出用于复盘、重要结论需结合原始数据核验」。
2. TaoToken 前置:统一 Key 与调用链的入口
在把 Tushare / AkShare 封装成 MCP 工具之前,先解决一个容易被忽略的问题:Key 管理。自建路径下,你会有 Tushare Token、可能有行情服务的 Key、再加上模型侧的 Key,散落在脚本、环境变量、前端代码里。Agent 一旦长期运行,Token 暴露和调用失控是迟早的事。
TaoToken 在这里的角色是统一调用入口。它提供兼容主流协议的统一 Key,模型对话、编码 Agent、API 调用走同一套鉴权,你不需要在每个工具里各写一套 Key 逻辑。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api (这个地址不加 UTM 参数)。
具体到操作,你需要先拿到 Key。进入控制台创建:
- 控制台:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
- API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
创建完 Key 之后,建议先做一次最小验证,确认 Key 可用,再往下接数据源。验证模型调用可以直接用模型对话页:
- 模型对话:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite
如果你打算长期跑编码类 Agent(比如让 Agent 自己写取数脚本、改 MCP 工具定义),可以看 Coding Plan:
- Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite
接入细节和字段说明在文档里:
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
这里要强调一点:TaoToken 是统一调用入口,不是让你跳过数据源授权。Tushare 的 Token、AkShare 的取数逻辑仍然各自独立,TaoToken 解决的是「模型侧和工具侧调用链的 Key 统一与鉴权边界」。两者不冲突,是叠加关系。
为什么先讲这个?因为后面 MCP 工具定义里会同时出现「模型调用」和「数据源调用」两类配置。如果 Key 管理没理顺,排障时你分不清是模型侧 401 还是数据源侧权限不足。先把统一 Key 跑通,后面出错定位会快很多。
3. 可复制配置:MCP 工具定义与数据源适配
这一节给可直接复制的配置。分两部分:MCP 服务器配置(让 Agent 发现工具)和数据源适配(Tushare / AkShare 的取数封装)。
先看 MCP 服务器配置。以支持远程 HTTP MCP 的客户端为例,配置文件通常长这样,注意路径和字段名要和你客户端实际要求一致:
{ "mcpServers": { "stock-data": { "url": "https://taotoken.net/api/mcp", "headers": { "Authorization": "Bearer YOUR_TAOTOKEN_KEY" } } } }如果你的客户端要求显式声明连接类型,补上"type": "http"或对应字段。不同客户端字段名有差异,以文档为准。这里 Base URL、Key、Model ID 三件套要写全:Base URL 用https://taotoken.net/api,Key 用你在 API Keys 页创建的,Model ID 按你实际调用的模型填。
接下来是数据源适配。MCP 工具层不直接写死 Tushare 或 AkShare,而是包一层适配器,把不同数据源的返回统一成结构化字段。下面是一个 AkShare 适配的 MCP 工具定义示意:
from mcp.server import Server from mcp.types import Tool, TextContent import akshare as ak import json app = Server("stock-data") @app.list_tools() async def list_tools(): return [ Tool( name="get_daily_kline", description="获取A股日K线。参数:symbol(6位代码), start_date, end_date, adjust(qfq/hfq/空)", inputSchema={ "type": "object", "properties": { "symbol": {"type": "string"}, "start_date": {"type": "string"}, "end_date": {"type": "string"}, "adjust": {"type": "string", "default": "qfq"} }, "required": ["symbol", "start_date", "end_date"] } ) ] @app.call_tool() async def call_tool(name: str, arguments: dict): if name == "get_daily_kline": df = ak.stock_zh_a_hist( symbol=arguments["symbol"], period="daily", start_date=arguments["start_date"], end_date=arguments["end_date"], adjust=arguments.get("adjust", "qfq") ) records = df.tail(60).to_dict(orient="records") return [TextContent(type="text", text=json.dumps({ "symbol": arguments["symbol"], "rows": records, "source": "akshare", "tradeDate": records[-1]["日期"] if records else None }, ensure_ascii=False))]Tushare 适配同理,只是把取数函数换成pro.daily(),并在返回里带上ts_code和trade_date。关键点是每个工具返回都要带source和tradeDate字段,这是后面排障和防止「拿昨天收盘价当现价」的关键。
工具粒度建议按任务组织,不要一次暴露几十个接口。市场复盘、个股研究、涨停复盘、题材研究分开建工具组,Agent 选错工具的概率会明显下降。
4. 验证请求:一次端到端行情查询
配置写完必须验证,否则你不知道是工具没被发现,还是发现了但调用失败。验证分两步:先tools/list确认工具可见,再tools/call实际取数。
第一步,让 Agent 列出工具。在支持 MCP 的客户端里发起:
请列出当前可用的股票数据工具,并说明每个工具的参数。正常返回应该能看到get_daily_kline及其参数说明。如果这里为空,说明 MCP 服务器没连上,先查 URL 和 Authorization 头。
第二步,实际调用一次。用贵州茅台做样例:
调用 get_daily_kline,symbol=600519,start_date=20240101,end_date=20260615,adjust=qfq,返回最近5条。预期返回结构类似:
{ "symbol": "600519", "rows": [ {"日期": "2026-06-11", "开盘": 1680.0, "收盘": 1702.5, "成交量": 32100}, {"日期": "2026-06-12", "开盘": 1703.0, "收盘": 1695.2, "成交量": 29800} ], "source": "akshare", "tradeDate": "2026-06-12" }看到tradeDate和source就说明链路通了。注意:看到工具名称不等于成功取得数据,参数和返回字段以当前服务为准。如果返回里rows为空,先检查日期区间是否落在交易日范围内,再检查symbol格式(AkShare 用 6 位纯数字,Tushare 用600519.SH)。
第三步,做一次「日期一致性」检查。让 Agent 回答「600519 最新交易日收盘价是多少」,然后核对返回的tradeDate是不是最近交易日。这一步能提前暴露「K 线当实时行情」的坑。
如果你用的是 Claude Code 这类编码 Agent 来写和调 MCP 工具,接入方式参考:
- Claude Code 接入:https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claude-code&utm_campaign=rewrite
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
排障按「模型侧 → 工具侧 → 数据源侧」顺序查,不要一上来就改代码。
401 Unauthorized。两种可能:TaoToken Key 无效,或数据源 Token 无效。先确认Authorization: Bearer后面的 Key 是从 API Keys 页复制的完整串,没有多余空格。如果模型调用正常但工具调用 401,问题在数据源侧,检查 Tushare Token 是否过期、AkShare 是否触发了频率限制。
local proxy failed。通常是 MCP 客户端本地代理没起来,或 URL 写错。检查配置里的url是不是https://taotoken.net/api/mcp,有没有误写成带 UTM 的地址。远程 HTTP MCP 不需要本地代理,如果客户端强制走本地代理,确认代理进程在运行。
reading choices 报错。这类错误一般出现在模型返回结构解析阶段,说明返回体不是预期的 JSON。常见原因是数据源返回了 HTML 错误页(比如被限流),而工具层没做异常捕获。在call_tool里加 try/except,把异常转成结构化错误返回,而不是让原始 HTML 透传。
OAuth 相关报错。部分客户端对远程 MCP 要求 OAuth 流程,而你的配置用的是静态 Bearer 头。这时要么在客户端里选择「API Key / Bearer」模式,要么按客户端文档补 OAuth 配置。不要混用两种鉴权方式。
工具可见但调用无返回。检查inputSchema的required字段是否和实际传参一致。Agent 有时会漏传end_date,导致取数函数报错但被吞掉。
日期对不上。返回的tradeDate是昨天,但用户问的是现价。这是工具描述没写清「本工具返回历史 K 线,非实时行情」。在description里明确写「历史日线,更新时间 T+1」,并单独建实时行情工具。
排障时如果拿不准是 Key 问题还是配置问题,回到接入文档对照字段:
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
- API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
6. 按任务选路径:现成服务与自建工具怎么组合
走到这里你有两条路。路径 A:Agent → 现成数据 MCP 服务 → 数据查询与核对,适合想少维护取数代码、先验证能力的场景。路径 B:数据 API / Python 库 / 内部数据库 → 自建受控工具 → Agent,适合有内部指标、特殊权限规则的团队。两条路可以按任务组合,不需要为了用现成服务先自建数据库。
如果你希望 Agent 直接查询 A 股涨停梯队、市场宽度和题材资金做盘后复盘,可以先把现成数据 MCP 服务列入候选,完成配置和历史样例验收,再测自己的目标日期。已有 Tushare 生态需求的,评估其官方 MCP 或继续用 SDK;想自己控制采集和内部指标的,用 AkShare 加自建服务。
选择依据是任务覆盖、数据日期、实际输出、权限和维护成本,不是只看是否支持 MCP。无论哪条路,都要核对实际日期、字段单位、结果截断和失败状态。定时执行、文件落盘和报告发送由 Agent 客户端或调度器负责,数据工具不自动包办这些动作。
最后给一个实用技巧:把「工具描述」当成给 Agent 的接口文档来写,参数含义、返回字段、更新频率、边界(不执行下单)都写进去。Agent 选错工具,八成是描述没写清,而不是模型不行。统一 Key 用 TaoToken 管住调用链,数据源适配用适配器隔离,工具粒度按任务拆,这三件事做完,Agent 拿结构化股票数据就稳了。