推广 热搜: 采购方式  甲带  滤芯  气动隔膜泵  减速机型号  减速机  履带  带式称重给煤机  链式给煤机  无级变速机 

遇見 Dexter:當 AI 學會自己查財報

   日期:2026-02-09 00:54:00     来源:网络整理    作者:本站编辑    评论:0    
遇見 Dexter:當 AI 學會自己查財報

偶然在 GitHub 上刷到一個專案,看了一下發現有點意思。這是一個 CLI 工具,你給它一個自然語言的問題,它會自己規劃步驟、調用工具、查數據,最後給你一個答案。就像有個金融分析師助理在幫你幹活。


先看看效果

你不需要告訴它該查什麼接口,不需要寫代碼,直接用自然語言問就行了。


整體架構

先看整體架構,不算複雜,但設計得挺乾淨:

核心思路就是:讓 LLM 來決定下一步該做什麼,而不是硬編碼一個流程。


代理循環:讓它自己思考

最有趣的是這個代理循環的設計。它不是一次性把活幹完,而是一步步來:

為什麼要這樣設計?

因為有些問題不是一步能搞定的。比如你問「分析一下蘋果的投資價值」,它可能需要:

  1. 先查財務數據
  2. 看完數據後發現還需要查一下行業對比
  3. 發現還缺少最新的新聞
  4. 最後綜合所有信息給出結論

如果一次性把所有可能的工具都調用一遍,既浪費錢又不一定有用。讓它自己判斷下一步需要什麼,會更靈活。

關鍵代碼邏輯

// 簡化的代理循環while (iteration < maxIterations) {  // 1. 調用 LLM 做決策  const response = await callModel(currentPrompt);  // 2. 沒有 tool_calls?說明準備生成答案了  if (!hasToolCalls(response)) {    return generateFinalAnswer(scratchpad.getFullContext());  }  // 3. 有 tool_calls?執行工具並收集結果  for (const toolCall of response.tool_calls) {    const result = await executeTool(toolCall);    scratchpad.addResult(result);  // 記錄到筆記本  }  // 4. 上下文太長?清理舊的結果  if (estimateTokens(context) > THRESHOLD) {    scratchpad.clearOldestResults(KEEP_COUNT);  }  // 5. 構建下一次迭代的提示  currentPrompt = buildIterationPrompt(scratchpad.getResults());}

Scratchpad:它的「筆記本」

每次查詢,Dexter 都會創建一個 Scratchpad,就像給 AI 配了一個筆記本。這個筆記本記錄了:

  • 一開始問了什麼問題
  • 調用了哪些工具
  • 每個工具返回了什麼結果
  • AI 中間有過哪些思考

持久化格式:每個查詢生成一個 JSONL 文件,每行一條記錄:

{"type":"init","content":"蘋果和特斯拉哪個更值得投資?","timestamp":"2026-02-08T..."}{"type":"tool_result","toolName":"financial_search","args":{"query":"AAPL TSLA 財務數據"},"result":{...},"timestamp":"..."}{"type":"thinking","content":"讓我對比一下兩家公司的估值指標...","timestamp":"..."}

三大能力

  1. 防重試:通過 Jaccard 相似度檢測,不會重複查一樣的東西
  2. 控成本:當上下文太長時,自動清理舊結果
  3. 可追溯:每次查詢都有完整記錄,出問題能查日誌

去重邏輯

// 檢測相似查詢findSimilarQuery(newQuery, previousQueries) {  const newWords = tokenize(newQuery);  // 分詞  for (const prev of previousQueries) {    const similarity = jaccard(newWords, tokenize(prev));    if (similarity >= 0.7return prev;  // 相似度閾值  }  return null;}

工具系統:三層架構

工具系統分了三層,每層職責清晰:

為什麼需要路由層?

因為用戶的提問是自然語言,不是結構化的 API 調用。比如你說「看看蘋果最近表現如何」,它需要理解:

  • 「表現」可能指股價,也可能指財務
  • 「最近」是多長時間?
  • 需要調用哪些具體的 API?

路由層用另一個 LLM 來做這件事,把自然語言翻譯成具體的工具調用:

// 路由層工作流程func: async (input) => {  // 1. 用 LLM 理解用戶意圖  const { response } = await callLlm(input.query, {    tools: ALL_FINANCE_TOOLS,  // 綁定所有金融工具  });  // 2. 提取工具調用  const toolCalls = response.tool_calls;  // 3. 並行執行(多個工具可以同時跑)  const results = await Promise.all(    toolCalls.map(tc => FINANCE_TOOL_MAP.get(tc.name).invoke(tc.args))  );  // 4. 合併結果  return combineResults(results);}

金融工具詳解

Dexter 最大的價值在於它集成了豐富的金融數據工具。這些工具都是對 Financial Datasets API 的封裝,讓 AI 能夠像分析師一樣查數據。

工具全景圖

價格數據工具

get_price_snapshot - 獲取最新價格

// 調用示例get_price_snapshot({ ticker"AAPL" })// 返回數據{  "price"178.52,  "change"2.35,  "change_percent"1.33,  "volume"52340000,  "open"176.80,  "high"179.12,  "low"176.20}

get_prices - 歷史價格數據

// 調用示例get_prices({  ticker"AAPL",  start_date"2024-01-01",  end_date"2024-01-31",  interval"day"})// 返回數據[  { "date""2024-01-02""open"182.5"high"185.0"low"181.2"close"184.3"volume"52000000 },  { "date""2024-01-03""open"184.0"high"186.1"low"183.5"close"185.9"volume"48000000 },  // ...]

財務報表工具

get_income_statements - 利潤表

// 調用示例get_income_statements({  ticker"AAPL",  period"annual",  // annual / quarterly / ttm  limit5})// 返回數據(5年年度利潤表)[  {    "fiscal_date""2023-09-30",    "revenue"383285000000,    "cost_of_revenue"214137000000,    "gross_profit"169148000000,    "operating_income"114301000000,    "net_income"96995000000,    // ...  },  // ... 歷史數據]

get_balance_sheets - 資產負債表 get_cash_flow_statements - 現金流量表 get_all_financial_statements - 一次性獲取三張報表(效率更高)

估值指標工具

get_key_ratios_snapshot - 最新估值指標

// 調用示例get_key_ratios_snapshot({ ticker"AAPL" })// 返回數據{  "market_cap"2800000000000,  "pe_ratio"28.5,  "pb_ratio"45.2,  "dividend_yield"0.5,  "eps"6.16,  "revenue_per_share"24.5,  "enterprise_value"2750000000000}

get_key_ratios - 歷史估值指標(用於趨勢分析)

SEC 文件工具

get_filings - 獲取 SEC 文件元數據

// 調用示例get_filings({  ticker"AAPL",  filing_type"10-K",  // 10-K / 10-Q / 8-K  limit5})// 返回數據[  {    "accession_number""0000320193-23-000108",    "filing_type""10-K",    "filing_date""2023-11-03",    "report_date""2023-09-30",    "url""https://www.sec.gov/..."  },  // ...]

get_10K_filing_items - 讀取 10-K 的具體章節

// 調用示例get_10K_filing_items({  ticker"AAPL",  accession_number"0000320193-23-000108",  items: ["Item-1""Item-1A""Item-7"]  // Item-1: Business  // Item-1A: Risk Factors  // Item-7: MD&A})// 返回數據{  "Item-1""Apple Inc. designs, manufactures...",  "Item-1A""The Company's business is subject to...",  "Item-7""Results of Operations..."}

get_10Q_filing_items - 季報章節 get_8K_filing_items - 重大事件公告

其他工具

get_news - 公司新聞 get_insider_trades - 內部交易(高管買賣記錄) get_analyst_estimates - 分析師預期和目標價 get_segmented_revenues - 分業務收入


如何使用 Dexter

安裝

# 1. 克隆專案git clone https://github.com/virattt/dexter.gitcd dexter# 2. 安裝依賴(需要 Bun)bun install# 3. 配置環境變量cp env.example .env# 編輯 .env,填入 API 密鑰

運行

# 啟動交互模式bun start# 開發模式(自動重載)bun dev

支持的模型

Dexter 支持多個 LLM 提供商,通過模型名稱前綴自動識別:

前綴
提供商
示例模型
claude-
Anthropic
claude-3.5-sonnet
gemini-
Google
gemini-2.5-flash
grok-
xAI
grok-beta
ollama:
本地
ollama:llama3
無前綴
OpenAI
gpt-4o(默認)

使用示例

啟動後,直接輸入問題> 蘋果最新的財報怎麼樣?對比一下特斯拉和比亞迪的估值分析英偉達的投資價值,用 DCF 方法查一下最近有哪些科技公司在回購股票

技能系統

Dexter 支持自定義技能,比如內置的 DCF 估值技能:

---name: dcf-valuationdescription: DCF 估值分析---## DCF Valuation Skill### Workflow Checklist- [ ] Step 1: Gather financial data- [ ] Step 2: Calculate FCF growth rate- [ ] Step 3: Estimate WACC- [ ] Step 4: Project future cash flows- [ ] Step 5: Calculate present value...

你可以添加自己的技能到 ~/.dexter/skills/ 目錄,Dexter 會自動發現並加載。


技能系統:把專家知識寫成文檔

這個設計我覺得最巧妙。有些複雜任務(比如 DCF 估值)有一套固定流程,如果把流程硬編碼進代碼裡會很死板。

Dexter 的做法是:把流程寫成 Markdown 文件,LLM 可以直接讀懂並執行。

效果:你想加一個新的分析模型,只需要寫個 Markdown 文件,不需要改代碼。

技能目錄結構

~/.dexter/skills/├── dcf-valuation/   └── SKILL.md├── pe-analysis/   └── SKILL.md└── your-skill/    └── SKILL.md

CLI 界面:用 React 寫終端

這個也挺有意思的。它用的是 Ink(React for CLI),不是傳統的 chalk/ora。

事件驅動的狀態管理

// Hook 訂閱代理事件const handleEvent = (event) => {  switch (event.type) {    case 'thinking':      setWorkingState({ status: 'thinking' });      break;    case 'tool_start':      setWorkingState({ status: 'tool', toolName: event.tool });      break;    case 'tool_progress':      updateProgress(event.message);  // 實時更新進度      break;    case 'done':      setAnswer(event.answer);      break;  }};// 代理流式輸出事件forawait (constevent of agent.run(query)) {  handleEvent(event);}

好處

  • 組件化組織 UI,代碼清晰
  • 事件驅動,代理不關心 UI 怎麼渲染
  • 實時顯示進度,體驗更好

多模型支持與成本優化

Dexer 支持多個 LLM 提供商,還做了一些成本優化。

支持的提供商

// 通過前綴自動選擇提供商const MODEL_PROVIDERS = {  'claude-'ChatAnthropic,  'gemini-'ChatGoogleGenerativeAI,  'grok-'ChatOpenAI,  // xAI API  'openrouter:'ChatOpenAI,  // OpenRouter  'ollama:'ChatOllama,};

Anthropic 提示詞緩存

// 啟用系統提示詞緩存function buildAnthropicMessages(systemPrompt, userPrompt) {  return [    new SystemMessage({      content: [{        type'text',        text: systemPrompt,        cache_control: { type'ephemeral' }  // 關鍵!      }]    }),    new HumanMessage(userPrompt)  ];}

效果:系統提示詞緩存後,輸入成本降低約 90%。

快速模型分流

const FAST_MODELS = {  openai'gpt-4o-mini',  anthropic'claude-haiku-4-5',  google'gemini-2.5-flash',};

輕量級任務(如摘要)自動使用快速模型,節省成本。


能用在哪?

這個專案雖然是做金融的,但它的架構模式其實挺通用的:

實用價值

對於想學習 AI Agent 開發的開發者,這個專案是一個很好的參考。代碼質量不錯,結構清晰,容易改。而且它的金融工具封裝也可以直接用在其他項目裡。

如果你想自己動手改改看,可以:

  1. 換成其他數據源(比如你自己爬的數據)
  2. 加一些自定義技能(比如技術分析指標)
  3. 換成 Web UI(Ink 可以換成 React)
  4. 做成不同的領域(醫療、法律、電商)

專案地址:https://github.com/virattt/dexter

技術棧:Bun + TypeScript + LangChain + Ink + Financial Datasets API

所需 API

  • OpenAI API(或其他 LLM)
  • Financial Datasets API(金融數據)
  • Exa API(可選,網絡搜索)
 
打赏
 
更多>同类资讯
0相关评论

推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  皖ICP备20008326号-18
Powered By DESTOON