TIP
难度:★★☆☆☆ | 时长:15 分钟 | 收获:掌握本地金融研究 Agent 部署,理解工具调用与 DCF 技能扩展机制
简介
Dexter 是一个跑在终端里的自主金融研究 Agent。你问它一个复杂问题,它会自动拆解任务、调用多个数据工具、交叉验证结果,直到给出一个有数据支撑的结论——就像带了一个不会疲倦的资深分析师。
它的核心能力包括:
- SEC 文件读取:自动抓取 10-K、10-Q、8-K 等披露文档
- 实时行情查询:股价、财务指标、现金流、资产负债表
- DCF 内在价值估算:内置 SKILL.md 驱动的 DCF 技能,自己运行现金流折现
- 自验证循环:检查自己的中间结果,迭代直到结论成立
- Loop 保护:内置步数上限,防止 Agent 失控
整个项目用 TypeScript 写成,核心是 LangChain + Ink(React for CLI),运行在 Bun 1.0+ 环境下。如果你希望用更低的成本跑满这些能力,可以将 LLM 提供商切换到 Defapi,API 价格仅为官方的一半。
目标读者画像
- 有 1-5 年经验的开发者,对 AI Agent 架构(工具调用、Agentic Loop)有基础了解
- 独立投资者或金融科技从业者,想用 AI 工具辅助基本面研究
- 想了解如何在真实项目中集成多数据源(SEC、Financial Datasets、Exa)的工程师
- 对金融量化研究感兴趣,希望搭建本地研究流水线的用户
核心依赖与环境
| 依赖 | 说明 | 获取地址 |
|---|---|---|
| Bun 1.0+ | JavaScript/TypeScript 运行时 | bun.sh |
| Financial Datasets API Key | 机构级市场数据(部分股票免费) | financialdatasets.ai |
| OpenAI API Key | 默认 LLM 提供商 | platform.openai.com |
| Exa API Key | 网页搜索(可选,Tavily 作兜底) | exa.ai |
| Defapi API Key | 替 OpenAI 降低成本(可选) | defapi.org |
WARNING
Financial Datasets 的 AAPL、NVDA、MSFT 数据是免费的,其他股票需要订阅。开始之前建议先用免费标的验证流程。
完整项目结构树
dexter/
├── .dexter/
│ └── settings.json # Agent 运行配置(模型/提供商选择)
├── src/
│ ├── agent/ # Agent 核心:循环逻辑、提示词、scratchpad
│ │ ├── agent.ts # Agentic Loop 主循环
│ │ ├── prompts.ts # 系统提示词
│ │ └── scratchpad.ts # 工具调用历史记录
│ ├── cli.tsx # Ink/React CLI 渲染入口
│ ├── index.tsx # 程序入口
│ ├── components/ # CLI UI 组件(Ink)
│ ├── hooks/ # React hooks(AgentRunner, ModelSelector)
│ ├── model/
│ │ └── llm.ts # 多提供商 LLM 抽象层
│ ├── tools/
│ │ ├── registry.ts # 工具注册表
│ │ ├── finance/ # 金融工具:行情、财务、报表、内部交易
│ │ ├── search/ # 网页搜索工具(Exa / Tavily)
│ │ ├── browser/ # Playwright 浏览器自动化
│ │ └── descriptions/ # 工具描述(注入系统提示词)
│ ├── skills/ # SKILL.md 技能目录
│ │ └── dcf/
│ │ └── SKILL.md # DCF 内在价值估算技能
│ ├── evals/ # LangSmith 评测框架
│ └── utils/ # 环境变量、配置、缓存
├── scripts/
│ └── release.sh
├── .env # API 密钥(gitignored)
└── package.json
手把手步骤
Step 1:安装 Bun 与克隆项目
如果你的机器上没有 Bun,先装它。Windows/macOS/Linux 通用:
# macOS / Linux
curl -fsSL https://bun.com/install | bash
# Windows
powershell -c "irm bun.sh/install.ps1|iex"
验证安装:
bun --version
# 输出类似:Bun v1.2.x
然后克隆 Dexter 仓库:
git clone https://github.com/virattt/dexter.git
cd dexter
Step 2:配置 .env 环境变量
复制环境变量模板文件:
cp env.example .env
用编辑器打开 .env,填入你的密钥。重点说清楚 Defapi 接入方式——如果你想用 Defapi 替代 OpenAI(节省 50% 成本),按如下方式配置:
# .env
# ── LLM 提供商 ──────────────────────────────────────
# 方案 A:直接用 OpenAI(默认)
OPENAI_API_KEY=sk-your-openai-key
# 方案 B:通过 Defapi 接入 OpenAI(推荐,省 50%)
# OPENAI_API_KEY=sk-your-defapi-key
# OPENAI_BASE_URL=https://api.defapi.com/v1
# 其他可选 LLM 提供商
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key
GOOGLE_API_KEY=your-google-key
XAI_API_KEY=your-xai-key
OPENROUTER_API_KEY=your-openrouter-key
# 本地模型(OLLAMA)
OLLAMA_BASE_URL=http://127.0.0.1:11434
# ── 金融数据 ───────────────────────────────────────
# 机构级市场数据,AAPL/NVDA/MSFT 免费
FINANCIAL_DATASETS_API_KEY=your-financial-datasets-key
# ── 网页搜索 ───────────────────────────────────────
# 优先用 Exa,Tavily 作兜底
EXASEARCH_API_KEY=your-exa-key
TAVILY_API_KEY=your-tavily-key
TIP
Defapi 的所有模型兼容 v1/chat/completions 和 v1/messages 接口,Dexter 无需任何代码修改,只要把 OPENAI_API_KEY 换成 Defapi 的 Key,同时把 OPENAI_BASE_URL 指向 https://api.defapi.com/v1 即可。
安装依赖:
bun install
Step 3:运行 Dexter 交互模式
启动交互式 CLI:
bun start
你会在终端里看到一个基于 Ink 渲染的彩色界面。直接输入你的金融问题,比如:
AAPL 过去 5 年营收增长情况如何?当前的 DCF 内在价值是多少?
Dexter 会自动开始工作:拆解任务 → 查财务数据 → 读 SEC 文件 → 跑 DCF 技能 → 汇总结论。每一轮工具调用都会实时显示在界面上。
如果你想边改代码边调试,用 watch 模式:
bun dev
Step 4:切换模型 / 提供商
在 CLI 内输入 /model 命令,可以切换 LLM 提供商和模型。Dexter 支持以下前缀自动识别:
| 前缀 | 提供商 | 示例模型 |
|---|---|---|
| 无前缀 | OpenAI(默认) | gpt-5.4 |
claude- | Anthropic | claude-sonnet-4-7 |
gemini- | gemini-2.5-pro | |
ollama: | Ollama(本地) | ollama:qwen2.5 |
deepseek: | DeepSeek | deepseek-chat |
例如切换到 Claude:
/model claude-sonnet-4-7
TIP
如果你接入了 Defapi,直接用默认的 gpt-5.4 即可,流量自动走 Defapi 转发,不会消耗 OpenAI 官方配额。
Step 5:使用金融工具查询股票
Dexter 的核心是 financial_search 工具,它会根据你的问题自动委托给最合适的子工具。以下是一些典型查询示例:
查询收入与利润:
给我查询 TSLA 最近 3 年的营收、净利润和自由现金流
Dexter 会调用 get_income_statements(利润表)和 get_cash_flow_statements(现金流量表),整理成表格返回。
查询资产负债表:
NVDA 的最新资产负债率是多少?现金及等价物有多少?
读取 SEC 文件:
帮我读一下 AAPL 最新 10-K 中的"Risk Factors"章节
Dexter 会调用 read_filings 工具抓取 10-K 内容,定位到对应章节。
查内部交易:
最近一个季度 FAANG 股票的内部人士交易情况如何?
所有工具调用的原始数据都会记录在 .dexter/scratchpad/ 目录下的 JSONL 文件里,方便你事后审计。
Step 6:触发 DCF 估值技能
DCF(现金流折现)估值是 Dexter 内置的技能之一。当你的问题涉及"内在价值"或"估值"时,Agent 会自动调用 skill 工具加载 src/skills/dcf/SKILL.md,按步骤运行:
- 获取公司历史自由现金流(FCF)
- 估算未来 5-10 年增长率假设
- 计算加权平均资本成本(WACC)
- 折现到当前时点
- 输出最终估值区间 + 敏感性分析
示例查询:
MSFT 的 DCF 内在价值是多少?请给出保守、基准、乐观三种假设下的结果
WARNING
DCF 输出的是参考区间,不是投资建议。Dexter 会明确标注每个假设的置信度,这一点符合它的设计哲学——不包装确定性,不回避不确定性。
Step 7:调试与查看 Scratchpad 日志
Dexter 的每一次查询都会在 .dexter/scratchpad/ 生成一个 JSONL 文件,文件名格式为:
YYYY-MM-DD-HHMMSS_<session_id>.jsonl
每行是一条结构化记录:
{"type":"init","timestamp":"2026-03-27T10:00:00.000Z","query":"AAPL 的 DCF 内在价值是多少?"}
{"type":"tool_start","timestamp":"2026-03-27T10:00:01.000Z","toolName":"get_cash_flow_statements","args":{"ticker":"AAPL","period":"annual","limit":5}}
{"type":"tool_result","timestamp":"2026-03-27T10:00:03.000Z","toolName":"get_cash_flow_statements","result":{"freeCashFlow":[67800000000, 73000000000, ...]},"llmSummary":"AAPL 过去 5 年自由现金流持续增长,复合增长率约 9.2%"}
{"type":"thinking","timestamp":"2026-03-27T10:00:05.000Z","content":"已获取 FCF 数据,现在需要获取分析师预期增长率和 WACC 参数..."}
如果你发现某个工具调用结果不对,直接打开这个文件就能定位问题。也可以用 jq 做快速过滤:
# 只看工具调用结果
cat .dexter/scratchpad/2026-03-27-*.jsonl | jq 'select(.type == "tool_result")'
# 看 Agent 的推理过程
cat .dexter/scratchpad/2026-03-27-*.jsonl | jq 'select(.type == "thinking")'
常见问题排查
1. 运行时提示 OPENAI_API_KEY not found
这是最常见的错误。检查 .env 文件是否存在且路径正确:
ls -la .env
确认文件内有 OPENAI_API_KEY=... 或 OPENAI_API_KEY + OPENAI_BASE_URL 组合。如果用了 Defapi,两者必须同时存在。
2. 金融数据返回空结果
Financial Datasets 的免费数据仅限 AAPL、NVDA、MSFT。如果查询其他股票,会返回空结果。你可以:
- 在 financialdatasets.ai 查看你的订阅计划
- 确认
FINANCIAL_DATASETS_API_KEY已正确填入.env
3. 模型调用超时
Anthropic 和 Google 的 API 超时默认 60 秒。如果网络到海外服务不稳定,可以在 src/model/llm.ts 里调整 maxAttempts 和重试等待时间。如果长期使用,推荐通过 Defapi 接入,走国内优化线路更稳定。
4. Agent 陷入无限循环
Dexter 内置了 maxIterations(默认 10 步)保护。如果一个任务需要更多步数,可以在 src/agent/agent.ts 里调整这个参数。当步数耗尽时,Agent 会把当前的中间结论作为最终结果返回,而不是继续空转。
5. 工具调用返回的数据不完整
Financial Datasets 的 limit 参数控制返回的年份数量,默认可能只返回 1 年。查询时可以让 Dexter 明确指定 limit=5 或 limit=10。
6. Scratchpad 文件为空或不生成
Scratchpad 由 src/agent/scratchpad.ts 管理。如果 SKIP_SCRATCHPAD=true 环境变量被设置,文件不会被写入。确认 .env 中没有这个变量。另外,每次新查询会创建新文件,旧查询的文件不会追加。
扩展阅读 / 进阶方向
接入 WhatsApp 实现移动端研究助手
Dexter 支持通过 WhatsApp Gateway 接收消息。只要你的手机和 Dexter 在同一网络下:
# 扫码绑定 WhatsApp 账号
bun run gateway:login
# 启动 Gateway
bun run gateway
然后在 WhatsApp 里给自己发消息,Dexter 就会回复。这样你可以在通勤时查询持仓公司的最新财务数据。
详细配置参考 src/gateway/channels/whatsapp/README.md。
运行评测套件验证 Agent 准确率
Dexter 内置了一套 LangSmith 驱动的评测框架:
# 在全部测试题上跑评测
bun run src/evals/run.ts
# 随机抽 10 道题
bun run src/evals/run.ts --sample 10
评测用 LLM-as-Judge 方式评分,结果会上传到 LangSmith Dashboard。如果你对财务指标计算做了改动,可以用这套评测验证改动的质量。
接入 Ollama 使用本地模型
如果你希望完全不依赖外部 API:
# 启动 Ollama(需要提前安装)
ollama serve
# 在 .env 中配置
OLLAMA_BASE_URL=http://127.0.0.1:11434
然后在 CLI 内切换到 ollama:qwen2.5 或其他本地模型。注意:本地模型的工具调用能力可能不如 GPT-5.4 或 Claude Sonnet 稳定,建议在需要低延迟、低成本的场景使用。
自定义 SKILL.md 编写新技能
Dexter 的技能通过 SKILL.md 定义,每个技能包含 YAML frontmatter(名称、描述)和 markdown 格式的指令。创建一个新技能只需:
- 在
src/skills/下新建目录,例如src/skills/dupont/ - 编写
SKILL.md:
---
name: dupont-analysis
description: 杜邦分析 - 将 ROE 拆解为净利润率、资产周转率和权益乘数
---
# 杜邦分析技能
你是一个财务分析师。请对输入的 ticker 执行以下步骤:
1. 获取公司的净利润、营业收入、总资产和股东权益
2. 计算三个分解指标:
- 净利润率 = 净利润 / 营业收入
- 资产周转率 = 营业收入 / 总资产
- 权益乘数 = 总资产 / 股东权益
3. 计算 ROE = 三个指标的乘积
4. 对比行业平均水平,给出评分(1-10)
- 重启 Dexter,新技能会自动被发现并注入系统提示词
接入 Defapi 降低 API 成本
对于需要高频调用 LLM 的使用场景(自动盯盘、定期报告生成),API 成本不可忽视。通过 Defapi 接入可以节省约 50% 的费用:
# .env
OPENAI_API_KEY=your-defapi-api-key
OPENAI_BASE_URL=https://api.defapi.com/v1
Defapi 兼容所有 v1/chat/completions 接口的模型,Dexter 无需修改任何代码,只需替换密钥和 base URL。