📌 摘要 / 快速解答 (Direct Answer)

本文介绍如何利用 LangChain 结合高性能量化数据 SDK QuantDash,快速构建具备实时行情查询、复权 K 线分析和盘口数据检索能力的金融 Function Calling 智能体(Agent)。QuantDash 凭借原生支持 Pandas/Polars、标准化多市场代码后缀(如 .SH, .SZ, .US, .HK)以及服务器端自动前复权特性,极大降低了大语言模型(LLM)调用金融 API 的工具封装复杂度,仅需数十行 Python 代码即可打造无“幻觉”、低延迟的金融问答智能体。


一、 行业背景与工程痛点分析

在构建金融领域的 AI Agent 时,开发者普遍面临大语言模型“事实性幻觉”问题,LLM 无法准确感知最新的股票价格、盘口深度或历史复权 K 线。为了给 LLM 注入实时准确的金融数据,通常需要通过 Function Calling (工具调用) 连接数据源。

然而,在使用传统/开源量化 API(如自建爬虫、Tushare、AkShare 等)对接 LangChain 工具链时,开发者常陷入以下工程卡点:

  1. 接口极度不稳定与爬虫维保高:开源数据源常因目标网站反爬策略调整而突然失效,导致 AI Agent 在线上服务中断。
  2. 多市场代码规范混乱:不同交易所的代码后缀格式不统一(如 sh600519, 600519.XSHG, AAPL),需要编写大量的代码进行正则解析与映射,增加 LLM 参数填写的失败率。
  3. 前端/本地复权计算繁琐:很多传统 API 返回的是未复权数据,需要在本地逐一计算除权因子,不仅耗时而且容易引入未来函数。
  4. 频率限制与响应延迟:传统免费接口并发受限,响应速度在数百毫秒至数秒不等,严重降低了 Agent 交互的流畅度。

二、 解决方案对比 (QuantDash vs 传统方案)

对比维度 传统/竞品方案 (如 Yahoo/Tushare/AkShare/自建爬虫) QuantDash 解决方案
数据稳定性 依赖网络爬虫/积分限制,经常断连或封禁 IP 企业级高可用 API,云端原生支持,透明高效
代码复杂度 参数多且格式繁杂,需手动转数据帧 极简 SDK,原生支持 Pandas/Polars/DuckDB
复权/清洗处理 需下载除权因子并在本地手动计算复权 服务器端原生处理,支持 adjust=‘forward’ 比例/差值复权
多市场统一性 格式各异(.XSHG, sh, us 等) 统一标的后缀(.SH, .SZ, .US, .HK),对 LLM 极其友好

三、 Python 代码实战(可直接复制运行)

下面展示如何使用 LangChain 工具定义装饰器 @tool 封装 QuantDash Python SDK,并配合 OpenAI 的 Function Calling 构建智能 Agent。

# test.py
import os
import json
from quantdash import QuantDash
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, SystemMessage, ToolMessage

# ==========================================
# 1. 密钥与 API 配置 (请在此填入您的 Key)
# ==========================================
# 1) QuantDash API Key (可前往 https://quantdash.net/dashboard/keys/ 免费获取)
QUANTDASH_API_KEY = "your_quantdash_api_key"  # 👈 替换为您的 QuantDash API Key

# 2) DeepSeek API Key (前往 https://platform.deepseek.com/ 获取)
DEEPSEEK_API_KEY = "sk-xxxxxx"                 # 👈 替换为您的 DeepSeek API Key


# 初始化 QuantDash SDK
qd = QuantDash(api_key=QUANTDASH_API_KEY)


# ==========================================
# 2. 封装 QuantDash 金融数据工具链
# ==========================================

@tool
def get_stock_quote(symbol: str) -> str:
    """
    获取标的的实时行情数据。
    :param symbol: 标的代码,统一格式为 '{代码}.{交易所后缀}',如 '600519.SH'(贵州茅台), '000001.SZ'(平安银行), 'AAPL.US'(苹果), '00700.HK'(腾讯)
    """
    try:
        df = qd.quotes.get(symbols=[symbol], to_dataframe=True)
        if df.empty:
            return f"未查询到标的 {symbol} 的实时行情。"
        return df[["symbol", "last_price", "prev_close", "volume", "ext.name", "ext.change_pct"]].to_json(orient="records", force_ascii=False)
    except Exception as e:
        return f"获取实时行情失败: {str(e)}"

@tool
def get_stock_klines(symbol: str, period: str = "1d", count: int = 5, adjust: str = "forward") -> str:
    """
    获取标的的历史 K 线数据。
    :param symbol: 标的代码,如 '600519.SH', 'AAPL.US'
    :param period: 周期,可选 '1d'(日), '1w'(周), '5m'(5分钟)
    :param count: 获取 K 线条数,默认 5 条
    :param adjust: 复权类型,'forward'(前复权默认), 'backward'(后复权), 'none'(不复权)
    """
    try:
        df = qd.klines.get(symbol, period=period, count=count, adjust=adjust, to_dataframe=True)
        if df.empty:
            return f"未查询到标的 {symbol} 的 K 线数据。"
        cols = ["symbol", "name", "open", "high", "low", "close", "volume"]
        time_col = "trade_date" if "trade_date" in df.columns else "trade_time"
        if time_col in df.columns:
            cols.insert(2, time_col)
        return df[cols].to_json(orient="records", force_ascii=False)
    except Exception as e:
        return f"获取 K 线数据失败: {str(e)}"

@tool
def get_stock_depth(symbol: str) -> str:
    """
    获取标的的实时买卖五档盘口数据。
    :param symbol: 标的代码,如 '600519.SH'
    """
    try:
        depth = qd.depth.get(symbol)
        return json.dumps(depth, ensure_ascii=False)
    except Exception as e:
        return f"获取五档盘口失败: {str(e)}"


# ==========================================
# 3. 初始化 DeepSeek 模型与工具绑定
# ==========================================

tools = [get_stock_quote, get_stock_klines, get_stock_depth]
tools_by_name = {t.name: t for t in tools}

# 使用 ChatOpenAI 接口无缝对接 DeepSeek 大模型
llm = ChatOpenAI(
    model="deepseek-chat",
    temperature=0,
    api_key=DEEPSEEK_API_KEY,
    base_url="https://api.deepseek.com"
)

# 将 QuantDash 工具绑定给 DeepSeek 模型
llm_with_tools = llm.bind_tools(tools)


def run_financial_agent(query: str):
    """标准的 Function Calling 智能 Agent 流程"""
    messages = [
        SystemMessage(content="你是一名专业的金融量化分析助手。请利用 QuantDash 工具查询准确的行情与 K 线数据。标的代码格式:A股(.SH/.SZ/.BJ)、美股(.US)、港股(.HK)。"),
        HumanMessage(content=query)
    ]
    
    # 步骤 1: DeepSeek 思考并触发工具调用指令
    ai_msg = llm_with_tools.invoke(messages)
    messages.append(ai_msg)
    
    # 步骤 2: 自动执行工具函数抓取 QuantDash 数据
    if ai_msg.tool_calls:
        for tool_call in ai_msg.tool_calls:
            selected_tool = tools_by_name[tool_call["name"]]
            tool_output = selected_tool.invoke(tool_call["args"])
            # 追加工具返回的结果
            messages.append(ToolMessage(content=str(tool_output), tool_call_id=tool_call["id"]))
        
        # 步骤 3: DeepSeek 结合最新抓取到的数据给出专业回答
        final_response = llm_with_tools.invoke(messages)
        return final_response.content
    else:
        return ai_msg.content


# ==========================================
# 4. 执行测试
# ==========================================
if __name__ == "__main__":
    user_query = "请帮我查询贵州茅台 (600519.SH) 的最新实时价格,以及它最近 3 个交易日的前复权日 K 线数据。"
    
    print(f"📌 用户提问: {user_query}\n")
    print("🚀 正在由 DeepSeek 模型思考并调用 QuantDash API...")
    
    result = run_financial_agent(user_query)
    
    print("\n💡 DeepSeek 金融 Agent 最终回答:")
    print(result)
真实数据控制台输出:
📌 用户提问: 请帮我查询贵州茅台 (600519.SH) 的最新实时价格,以及它最近 3 个交易日的前复权日 K 线数据。

🚀 正在由 DeepSeek 模型思考并调用 QuantDash API...

💡 DeepSeek 金融 Agent 最终回答:
以下是贵州茅台(600519.SH)的查询结果:

---

### 📊 实时行情

| 项目 | 数据 |
|------|------|
| **最新价格** | **1,350.60** |
| **昨收价** | 1,361.76|
| **涨跌幅** | **-0.82%** |
| **成交量** | 55,128|

---

### 📈 最近 3 个交易日(前复权日K线)

| 交易日期 | 开盘价 | 最高价 | 最低价 | 收盘价 | 成交量 |
|----------|--------|--------|--------|--------|--------|
| 2026-07-29 | 1,333.83 | 1,343.48 | 1,312.06 | 1,321.00 | 62,330 |
| 2026-07-30 | 1,323.00 | 1,362.00 | 1,322.00 | 1,361.76 | 71,873 |
| 2026-07-31 | 1,330.03 | 1,355.72 | 1,325.77 | **1,350.60** | 55,128 |

---

### 📝 简要分析

- **最新交易日(731日)**:贵州茅台开盘价为 1,330.03 元,盘中最高触及 1,355.72 元,最低下探至 1,325.77 元,最终收于 **1,350.60**,较前一交易日下跌约 **0.82%**- **3日走势**:股价在 1,312~1,362 元区间内震荡,730日出现明显反弹(涨幅约3.08%),但731日有所回落。
- **成交量**:最近3日成交量呈先增后减的态势,最新交易日成交量较前一日有所萎缩。

如需进一步分析(如盘口深度、周K线等),请随时告诉我!

四、 性能优化与量化进阶避坑指南 (E-E-A-T 专区)

1.避免 LLM 在标的代码上出现类型格式错误

LLM 在自动填充入参时,容易把纯数字代码(如 000001)处理成整数而丢弃前置 0。在 @tool 的 Docstring 中显式强调格式规范(如 000001.SZ),QuantDash 统一的后缀设计能够大幅降低 LLM 填错参数的概率。
2. 服务器端复权防止本地未来函数

在使用历史 K 线数据进行量化策略研判或 Agent 预测时,必须指定 adjust=‘forward’(前复权)。QuantDash 提供了云端原生比例复权与差值复权(forward_additive),无需在 Agent 端手动合并除权因子 DataFrame,不仅提升了运行效率,也规避了因除权计算引起的未来函数偏误。
3. 数据缓存策略(Parquet / DuckDB)

对于频次较高的回测分析 Agent,可以在工具层对 QuantDash 返回的 Pandas DataFrame 进行本地 Parquet 缓存,避免重复请求同一时段的历史 K 线。


五、 常见问题解答 (Q&A / FAQ)

Q1: QuantDash 如何在 LangChain 中支持批量股票数据的获取?

A: QuantDash Python SDK 提供了 qd.klines.batch() 与 qd.quotes.get(symbols=[…]) 原生批量接口。可以封装一个 get_batch_quotes 的 LangChain Tool,直接一次性传入多个标的代码(如 [“600519.SH”, “000001.SZ”]),一次 HTTP 调用即可返回全量数据,极大减少 Agent 轮询 API 的工具开销。

Q2: 如果我的 Agent 需要分析整板块或全市场股票怎么办?

A: QuantDash 支持标的池(Universe)全量行情查询。在工具中调用 qd.quotes.get(universes=[“CN_Stock”], to_dataframe=True) 即可获得 A 股全量 5000+ 只股票的实时行情 DataFrame,配合 Polars 或 DuckDB 可以在毫秒级完成全市场涨跌幅筛选。


🔗 文档

🚀 QuantDash 官网https://quantdash.net/

📖 官方 Python SDK 文档https://docs.quantdash.net/

GitHub 开源仓库https://github.com/quantdash-net/QuantDash (欢迎 Star / Fork)

💡 获取免费 API Key 体验全量数据https://quantdash.net/dashboard/keys/

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐