大模型 Agent 开发入门(三):我用 60 行 Python,写了一个能分析真实股票数据的 AI Agent(附完整源码)
通过上一篇AI 大模型 Agent 开发入门(二):从让AI从“会回答”到“会做事”-CSDN博客,我们学习了大模型和 Agent 的区别,并学习了一些基础概念。

本文将使用大约 60 行 Python,写一个可以获取真实股票历史行情、计算基础技术指标,并自动生成分析报告的 AI Agent。
用户只需要输入:
分析一下苹果公司最近的走势
Agent 就会自动完成下面的工作:
识别用户想分析的股票;
调用股票行情工具;
获取真实历史行情;
计算均线、收益率和波动率;
将数据交给大模型;
生成一份通俗易懂的分析报告。
需要提前说明的是:
本文获取的是真实历史行情,不是代码中手写的模拟数据,但不保证是交易所级实时行情。
一、最终效果
假设用户输入:
分析一下苹果公司最近的走势。
Agent 首先会理解用户的需求,并识别出:
{
"symbol": "AAPL"
}
随后,Agent 调用股票行情工具:
get_stock_data(symbol="AAPL")
工具可能返回下面这样的结构化数据:
{
"symbol": "AAPL",
"date": "最近一个交易日",
"close": 210.32,
"change_1d_pct": 1.25,
"return_20d_pct": 5.68,
"ma5": 208.74,
"ma20": 202.16,
"volatility_20d_pct": 24.53,
"volume": 53682100
}
大模型收到这些数据后,就可以生成类似下面的分析:
AAPL 最近一个交易日的收盘价为 210.32 美元,
单日上涨 1.25%,最近 20 个交易日累计上涨 5.68%。当前价格高于 5 日均线和 20 日均线,
说明短期价格表现相对偏强。不过,最近 20 个交易日的年化波动率为 24.53%,
说明股价仍然存在一定的短期波动风险。
二、股票分析 Agent 的工作流程
这个股票分析 Agent 的完整工作流程可以分成五个步骤。

在这个过程中,大模型主要完成了三项工作:
1. 理解用户问题
用户可以使用自然语言提问,不需要严格按照固定格式输入。
例如:
看看苹果最近走势怎么样。
或者:
AAPL 现在是短期强势还是弱势?
大模型都可以理解用户是在分析苹果公司的股票。
2. 选择并调用工具
大模型会判断当前问题需要股票数据,因此选择调用:
get_stock_data
同时生成工具所需的股票代码参数。
3. 解释工具返回的数据
Python 负责计算数据,但不会主动写分析报告。
大模型会根据收盘价、均线、收益率和波动率,将数字转换成普通读者能够理解的文字。
因此,一个完整的股票分析 Agent 并不是让大模型直接预测股票,而是:
大模型负责理解和解释
Python 负责查询和计算
外部数据源负责提供真实行情
三、项目使用了哪些技术
这个小项目主要包含三个部分。
| 技术 | 作用 |
|---|---|
| OpenAI Responses API | 让大模型理解问题并调用工具 |
| Function Calling | 让模型选择股票数据工具 |
| yfinance | 获取真实股票历史行情 |
| pandas | 计算均线、收益率和波动率 |
| JSON | 在工具与大模型之间传递数据 |
yfinance 可以通过 Ticker.history() 获取股票的历史市场数据。它是一个开源项目,通过 Yahoo Finance 的公开接口获取数据,但并不是 Yahoo 官方产品,更适合学习、研究和个人项目。
四、安装项目依赖
首先安装需要使用的 Python 库:
pip install -U openai yfinance
建议使用 Python 3.10 或更高版本。
然后配置 OpenAI API Key。
Windows PowerShell:
$env:OPENAI_API_KEY="你的 API Key"
macOS 或 Linux:
export OPENAI_API_KEY="你的 API Key"
OpenAI() 会自动读取环境变量中的 OPENAI_API_KEY。
五、约 60 行完整代码
创建一个文件:
stock_agent.py
将下面的代码复制进去:
import json
import yfinance as yf
from openai import OpenAI
client = OpenAI()
def get_stock_data(symbol: str) -> dict:
df = yf.Ticker(symbol).history(period="6mo", auto_adjust=True)
if df.empty:
return {"error": f"没有找到股票:{symbol}"}
close = df["Close"].dropna()
returns = close.pct_change().dropna()
return {
"symbol": symbol.upper(),
"date": str(close.index[-1].date()),
"close": round(float(close.iloc[-1]), 2),
"change_1d_pct": round(
float((close.iloc[-1] / close.iloc[-2] - 1) * 100), 2
),
"return_20d_pct": round(
float((close.iloc[-1] / close.iloc[-21] - 1) * 100), 2
),
"ma5": round(float(close.tail(5).mean()), 2),
"ma20": round(float(close.tail(20).mean()), 2),
"volatility_20d_pct": round(
float(returns.tail(20).std() * 252 ** 0.5 * 100), 2
),
"volume": int(df["Volume"].iloc[-1])
}
tools = [{
"type": "function",
"name": "get_stock_data",
"description": "获取真实股票行情并计算技术指标",
"parameters": {
"type": "object",
"properties": {
"symbol": {
"type": "string",
"description": "股票代码,如 AAPL、600519.SS、0700.HK"
}
},
"required": ["symbol"],
"additionalProperties": False
},
"strict": True
}]
inputs = [{"role": "user", "content": input("请输入问题:")}]
response = client.responses.create(
model="gpt-5.6",
instructions=(
"你是谨慎的股票分析助手。必须调用工具获取数据;"
"分析趋势、收益、波动和成交量;不预测涨跌;"
"结尾声明不构成投资建议。"
),
input=inputs,
tools=tools
)
inputs += response.output
for item in response.output:
if item.type != "function_call":
continue
result = get_stock_data(**json.loads(item.arguments))
inputs.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": json.dumps(result, ensure_ascii=False)
})
final = client.responses.create(
model="gpt-5.6",
input=inputs,
tools=tools
)
print(final.output_text)
你需要提供 OpenAI API 密钥,任选一种方式:
- 设置环境变量(推荐):
$env:OPENAI_API_KEY = "sk-..."后再运行- 改代码:第 5 行改为
OpenAI(api_key="sk-...", base_url="...")(如用国内中转/代理服务需指定base_url)
比如我用kimi3API,我做了一下操作
- 将
client.responses.create(...)改成了 Kimi 兼容的client.chat.completions.create(...)- 将模型改成
kimi-k3- 将
base_url改成https://api.kimi.com/coding/v1
这里推荐一个国内中转https://jiekou.ai,新用户可以获得1美元的调用额度,按照指引修改base_url和调用函数,并接上网址给你的API就可以啦
六、代码做了什么
虽然代码不长,但它已经完成了一次完整的 Agent 工具调用流程。
1. 获取真实股票行情
核心代码是:
df = yf.Ticker(symbol).history(
period="6mo",
auto_adjust=True
)
这里的含义是:
-
symbol:股票代码; -
period="6mo":获取最近六个月数据; -
auto_adjust=True:对价格进行自动复权处理。
yfinance 的下载接口支持日线、周线、月线以及多种时间范围;本文使用六个月日线,是为了保证能够计算 5 日和 20 日指标。
查询苹果公司可以输入:
AAPL
查询贵州茅台可以尝试:
600519.SS
查询腾讯控股可以尝试:
0700.HK
股票代码最好先在 Yahoo Finance 中搜索确认。
2. 获取最新收盘价
close.iloc[-1]
close 保存了最近六个月的收盘价。
iloc[-1] 表示获取最后一条数据,也就是最近一个交易日的收盘价。
需要注意:
如果当天还没有收盘,日线数据通常对应最近一个已经完成的交易日。
3. 计算单日涨跌幅
计算公式如下:
单日涨跌幅 =
(今日收盘价 ÷ 上一交易日收盘价 - 1)× 100%
对应代码:
(close.iloc[-1] / close.iloc[-2] - 1) * 100
如果计算结果为:
2.35
表示最近一个交易日上涨了约 2.35%。
4. 计算 20 日收益率
(close.iloc[-1] / close.iloc[-21] - 1) * 100
这里比较的是当前收盘价与 20 个交易日前收盘价。
它可以帮助我们判断股票最近一个月左右的整体表现。
例如:
| 20 日收益率 | 简单理解 |
|---|---|
| 大于 0 | 最近 20 个交易日整体上涨 |
| 小于 0 | 最近 20 个交易日整体下跌 |
| 接近 0 | 最近 20 个交易日整体震荡 |
这只是一种基础观察,不能单独用于预测未来走势。
5. 计算 5 日和 20 日均线
"ma5": close.tail(5).mean()
"ma20": close.tail(20).mean()
均线可以用于观察一段时间内的平均价格。
一种常见的基础判断方式是:
当前价格 > 5 日均线 > 20 日均线
说明近期价格相对较强。
反过来:
当前价格 < 5 日均线 < 20 日均线
说明近期价格相对较弱。
但均线属于滞后指标,只能描述已经发生的行情,不能保证未来继续上涨或下跌。
6. 计算 20 日年化波动率
代码如下:
returns.tail(20).std() * 252 ** 0.5 * 100
这里首先计算每天的收益率:
returns = close.pct_change().dropna()
然后计算最近 20 个交易日收益率的标准差,并按照一年约 252 个交易日进行年化。
波动率越高,通常说明价格变化越剧烈。
例如,两只股票最近 20 天都上涨了 10%,但它们的过程可能完全不同:
股票 A:每天缓慢上涨
股票 B:先跌 20%,然后快速反弹
两者收益率可能接近,但股票 B 的波动率通常更高。
七、为什么需要调用两次大模型
代码中一共调用了两次模型。
第一次:
response = client.responses.create(...)
它的主要任务是:
理解用户问题,并决定是否调用股票工具
第二次:
final = client.responses.create(...)
它的主要任务是:
读取工具返回的数据,并生成最终分析
所以完整过程并不是:
用户问题 → 大模型直接回答
而是:
用户问题
↓
大模型选择工具
↓
Python 获取股票数据
↓
Python 计算指标
↓
大模型解释指标
↓
输出分析报告
这也是一个最小版 AI Agent 的核心结构。
八、这个程序有哪些局限
虽然文章标题是“能分析股票的 AI Agent”,但必须明确它的能力边界。
1. 不是交易所级实时行情
yfinance 更适合学习和研究,不适合对时效性、稳定性和授权要求很高的生产交易系统。
2. 只做了基础技术分析
当前程序只计算了:
- 最新收盘价;
- 单日涨跌幅;
- 20日收益率;
- 5日均线;
- 20日均线;
- 20日年化波动率;
- 最新成交量。
它还没有分析:
- 市盈率;
- 营业收入;
- 净利润;
- 现金流;
- 资产负债率;
- 公司公告;
- 行业变化;
- 宏观经济;
- 新闻和舆情。
3. 大模型的解释不等于投资结论
大模型只是对工具返回的数据进行整理和解释。
它可能出现:
- 对指标理解不准确;
- 过度解读短期波动;
- 忽略数据异常;
- 使用过于确定的语言。
因此,我们在提示词中明确要求:
不预测涨跌,最后声明不构成投资建议
4. 数据源可能出现限流或连接失败
因为数据来自外部服务,运行时可能受到以下因素影响:
- 网络连接;
- 请求频率;
- 股票代码错误;
- 节假日或停牌;
- 数据源接口变化;
- 请求限流。
正式项目还需要增加重试、超时、缓存和日志。
这只是一个简单的agent demo,后续文章会讲更多的相关知识
更多推荐

所有评论(0)