
基于 CrewAI 與 CopilotKit AG-UI 協議的實時股票組合分析 Agent 實戰指南【免費下載鏈接】ai-engineering-hubIn-depth tutorials on LLMs, RAGs and real-world AI agent applications.項目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-hub導讀本文圍繞 ai-engineering-hub 倉庫中的stock-portfolio-analysis-agent項目完整講解如何構建一個實時流式輸出分析流程的 AI 股票組合分析 Agent后端使用 CrewAI 編排多階段分析工作流意圖解析 → 行情拉取 → 組合分配 → 牛熊洞察前端使用 React/Next.js 搭建可交互圖表界面并通過 CopilotKit 的AG-UI Protocol將工具調用、進度日志與中間結果以事件流SSE方式實時推送到瀏覽器。讀完本文你將掌握 AG-UI 事件驅動的 Agent 流式架構、CrewAI Flow 編排方法、基于 yfinance 的投資回測/分配模擬實現以及一套可直接復制運行的前后端聯調方案。項目總覽與技術棧該項目演示了一條完整的AI Agent 實時可視化鏈路用戶在前端輸入一句自然語言投資請求例如 Analyze AAPL and MSFT with $10k eachAgent 立即開始工作——拉取歷史行情、計算組合分配、生成牛熊分析——而這一切都以事件流的形式實時呈現在 UI 上用戶無需等待最終結果可以看著 Agent 干活。核心技術棧依據 README.md 與 pyproject.toml層級技術職責前端 UIReact Next.js 15交互式投資儀表盤與聊天面板后端 APIFastAPI Uvicorn提供/crewai-agent流式接口流式協議CopilotKit AG-UI Protocol實時傳輸 Agent 事件SSEAgent 編排CrewAI Flow多階段工作流調度市場數據yfinance pandas/numpy行情下載與收益計算后端依賴在 pyproject.toml 中鎖定crewai0.140.0、copilotkit0.1.52、ag-ui-protocol0.1.7、fastapi0.115.14、yfinance0.2.64、pandas2.3.0Python 版本要求3.12,3.13。環境搭建與運行1. 安裝依賴項目使用uv管理 Python 依賴前端使用 npm 管理 Node 依賴# 在倉庫根目錄安裝后端依賴 uv sync # 安裝前端依賴 cd frontend npm install cd ..提示stock-portfolio-analysis-agent目錄下同時存在uv.lock與pnpm-lock.yamlREADME 推薦使用npm install安裝前端依賴若你偏好 pnpm也可使用pnpm install并基于 frontend/package.json 中的腳本運行。2. 配置環境變量需要兩個.env文件分別供后端與前端使用后端agent/.envOPENAI_API_KEYyour-key前端frontend/.envOPENAI_API_KEYyour-openai-key NEXT_PUBLIC_CREWAI_URLhttp://127.0.0.1:8000/crewai-agent其中NEXT_PUBLIC_CREWAI_URL告訴前端代理層后端流式接口的位置。在 frontend/src/app/api/copilotkit/route.ts 中HttpAgent會讀取該變量并回退到默認值http://0.0.0.0:8000/crewai-agentconst crewaiAgent new HttpAgent({ url: process.env.NEXT_PUBLIC_CREWAI_URL || http://0.0.0.0:8000/crewai-agent, });3. 啟動應用# 終端一啟動后端默認端口 8000 uv run python agent/main.py # 終端二啟動前端默認端口 3000 cd frontend npm run dev后端入口 agent/main.py 中main()讀取環境變量PORT默認8000并以host0.0.0.0、開發熱重載reloadTrue啟動 Uvicorn。4. 調整后端地址可選README 明確提示前端默認假定后端運行在本機。若你修改了后端 host/port需要同步更新前端 API 調用配置即上面的NEXT_PUBLIC_CREWAI_URL否則前端無法建立到后端的代理連接。后端架構FastAPI AG-UI 事件流5. 狀態管理繼承 CopilotKitState后端用自定義的AgentState貫穿整個分析流程它繼承自CopilotKitState后者進一步繼承 LangGraph 的MessagesState見 agent/main.pyclass AgentState(CopilotKitState): tools: list messages: list be_stock_data: Any # 拉取到的行情 DataFrame be_arguments: dict # 從用戶輸入中解析出的投資參數 available_cash: int # 可用現金 investment_summary: dict # 分配/收益/基準對比結果 tool_logs: list # 供 UI 展示的進度日志這份狀態在/crewai-agent接口中初始化并在工作流各階段被持續讀寫最終回流到前端用于渲染。6. 流式接口事件生成器與 SSE核心接口POST /crewai-agent接收前端傳來的RunAgentInput含用戶消息、工具、thread_id/run_id、當前 state并返回media_typetext/event-stream的StreamingResponse見 agent/main.py。整個事件流由異步生成器event_generator()驅動其關鍵機制如下事件編碼EventEncoder將 AG-UI 事件編碼為 SSE 格式事件隊列asyncio.Queue作為工作流與流式循環之間的橋梁工作流通過emit_event回調把StateDeltaEvent等事件put_nowait入隊異步編排asyncio.create_task(StockAnalysisFlow().kickoff_async(...))在后臺運行 CrewAI 工作流主循環以asyncio.wait_for(event_queue.get(), timeout0.1)輪詢隊列并逐條轉發。事件流生命周期包含以下 AG-UI 事件類型見 agent/main.pyRunStartedEvent通知客戶端一次運行開始攜帶 thread_id/run_idStateSnapshotEvent推送初始快照available_cash、investment_summary、investment_portfolio并清空 tool_logsStateDeltaEvent工作流推進時增量更新/tool_logs、/investment_portfolio等路徑ToolCallStartEvent/ToolCallArgsEvent/ToolCallEndEvent渲染圖表工具render_standard_charts_and_table的調用與參數內含完整的investment_summaryTextMessageStartEvent/TextMessageContentEvent/TextMessageEndEvent普通文本回復內容被切成最多 100 個分片、每片間隔 50ms 推送形成打字機效果RunFinishedEvent標記運行結束。7. 智能節流先出圖表、后出洞察值得注意的一個工程細節主循環中實現了事件節流邏輯agent/main.py目的是先讓圖表數據完整送達再放行后續洞察內容避免 UI 渲染抖動當檢測到/tool_logs某條日志被替換為completed或檢測到TOOL_CALL_ARGS中包含render_standard_charts_and_table時標記chart_data_sent True此后/investment_portfolio的更新繼續放行而包含insights/processing/extracting的增量事件被攔截若圖表已發送而工作流仍在生成洞察則短暫 sleep 后提前結束流讓圖表先進入可交互狀態。這個設計說明流式 Agent 不僅要能推送事件還要能按用戶感知的優先級編排事件順序這是該示例區別于普通聊天流的關鍵點。Agent 工作流CrewAI Flow 的六個階段工作流主體是 agent/stock_analysis.py 中的StockAnalysisFlow使用 CrewAI Flow 的start、listen、or_裝飾器串聯start → chat → simulation → allocation → insights → end └──────────── chat未解析出投資參數時直通 end各階段職責與關鍵實現如下。階段一start——注入組合上下文start()方法stock_analysis.py將當前投資組合 JSON 替換進系統提示詞模板中的{PORTFOLIO_DATA_PLACEHOLDER}占位符提示詞見 agent/prompts.py使 LLM 從一開始就知道用戶已經持有哪些股票從而正確處理追加買入而非替換持倉。階段二chat——意圖解析與結構化提取chat()stock_analysis.py負責把自然語言翻譯成結構化投資參數在tool_logs中追加 Analyzing user query 日志并通過StateDeltaEventop: add,path: /tool_logs/-推送給 UI調用 OpenAIgpt-4o-mini并掛載函數調用工具extract_relevant_data_from_user_prompt若finish_reason tool_calls將工具調用轉換為內部格式convert_tool_call追加AssistantMessage與ToolMessage返回simulation進入下一階段若沒有觸發工具調用說明用戶只是在閑聊追加普通助手消息并返回end直接收尾。extract_relevant_data_from_user_prompt工具stock_analysis.py的參數 schema 是理解整個系統的關鍵參數類型說明ticker_symbolsstring[]股票代碼列表如[AAPL, GOOGL]必填investment_datestring (date)投資起始日期如2023-01-01必填amount_of_dollars_to_be_investednumber[]每只股票的投入金額與 ticker 列表一一對應必填interval_of_investmentenum1d/5d/7d/1mo/3mo/6mo/1y/2y/3y/4y/5y/single_shot未指定時默認single_shotto_be_added_in_portfolioboolean是否加入真實組合false 表示進入沙盒組合必填同時agent/prompts.py 中的系統提示詞對工具調用行為做了強約束一次調用傳入多個 ticker而不是每個 ticker 調用一次對于組合修改增/刪/替換分別規定返回完整最新列表 / 剔除后的列表 / 僅新股票列表。階段三simulation——行情拉取simulation()stock_analysis.py負責真實市場數據的獲取與預處理解析上一階段遺留的be_arguments將新投資與既有組合做加性合并existing_portfolio new_investments并通過StateDeltaEventop: replace,path: /investment_portfolio實時更新前端日期校驗投資日期距今超過 4 年則自動修正為當前年-4-01-01yfinance 數據可得性限制并據此推導history_period如1y、2y……用yf.download(all_tickers, start..., end..., interval3mo)拉取全部 ticker含既有持倉的季度收盤價存儲到self.be_stock_datadata[Close]DataFrame若數據為空則直接return end兜底否則繼續到 allocation。注意一個產品約束README 與前端初始話術prompt-panel.tsx都明確提示AI agent 只能訪問過去 4 年的行情數據——這與源碼中的 4 年截斷邏輯一致。階段四allocation——組合分配與收益模擬allocation()stock_analysis.py是整個系統最核心的算錢環節包含以下要點兩種投資策略由interval_of_investment決定single_shot一次性買入僅取行情第一個日期為每個 ticker 用allocated // price整數除法買入整股現金不足時記錄add_funds_datesDCA定投遍歷行情所有日期只要有可用現金就按total_cash // price盡可能買入逐筆寫入investment_log若用戶只給了一個金額但包含多個 ticker代碼會自動等額拆分amount_per_ticker amounts[0] / len(tickers)。收益與分配指標對每個 ticker 計算已投入金額、持倉市值、絕對收益、百分比分配invested / total_invested * 100與百分比收益(holding_value - invested) / invested * 100匯總成investment_summary包含holdings、final_prices、cash、returns、total_value、investment_log、add_funds_needed、add_funds_dates、total_invested_per_stock、percent_allocation_per_stock、percent_return_per_stock等字段。SPY 基準對比下載同期 SPY標普 500 ETF日線數據用與組合相同的策略single-shot 一次買入或 DCA 等額分批模擬投入同等資金逐日期計算組合凈值與 SPY 凈值生成performanceData: [{date, portfolio, spy}, ...]為前端折線圖提供對比數據。源碼對日期對齊做了處理SPY 起始日早于組合數據時將 stock_data 截斷到 SPY 首個可用日期并用reindex(..., methodffill)前向填充取數失敗時回退為占位 Series。圖表觸發本階段末尾工作流在messages中追加一條攜帶render_standard_charts_and_table工具調用的AssistantMessage參數為完整investment_summary這一工具調用隨后被后端流式循環轉換為ToolCallStart/Args/End事件推給前端從而觸發 UI 渲染圖表。階段五insights——牛熊洞察生成insights()stock_analysis.py調用gpt-4o-mini并掛載generate_insights工具為當前 ticker 列表生成平衡的多空觀點generate_insights工具stock_analysis.py要求輸出bullInsights與bearInsights兩組結構化數據每組項包含title、description、emoji三個必填字段拿到洞察后將其合并進圖表工具調用的參數args_dict[insights] ...這樣圖表渲染和洞察可以在同一次工具調用參數中一起到達前端失敗兜底洞察生成異常時置空self.state[state][insights] {}。階段六end——收尾end()監聽or_(chat, insights)stock_analysis.py無論是chat 階段未解析出投資參數還是insights 階段完成都會進入此步返回完整 state隨后由主循環清空 tool_logs 并發送RunFinishedEvent。前端架構CopilotKit 驅動的實時畫布8. 前端數據流前端入口 frontend/src/app/page.tsx 通過 CopilotKit React 核心 Hook 與后端 Agent 建立雙向連接useCoAgent聲明 Agent 名稱crewaiAgent并注入初始狀態available_cash: 1000000、空investment_summary、空investment_portfolio見 page.tsxuseCoAgentStateRender訂閱后端流式推送的狀態渲染ToolLogs組件將 Analyzing user query / Gathering Stock Data / Allocating cash / Extracting Key insights 等實時進度以動態卡片呈現見 tool-logs.tsxprocessing 態為黃色脈沖動畫、completed 態為綠色對勾useCopilotAction聲明render_standard_charts_and_table與render_custom_charts兩個前端動作前者渲染折線圖 柱狀圖 分配表并提供 Accept/Reject 交互按鈕page.tsx后者用于沙盒組合的自定義圖表對比useCopilotReadable把當前investment_portfolio暴露給 Copilot 上下文讓對話模型看得到組合狀態page.tsxuseCopilotChatSuggestions基于 frontend/src/utils/prompts.ts 中的INVESTMENT_SUGGESTION_PROMPT生成 35 條可點擊的投資建議增持/減持/替換格式金額范圍 5,00050,000 美元建議日期不早于 2020 年且距今至少 6 個月。9. 界面布局與可視化組件頁面采用三欄布局page.tsx左欄 PromptPanelCopilotChat 聊天面板展示可用現金與初始化引導語prompt-panel.tsx中欄 GenerativeCanvas渲染 Performance折線圖、Allocation分配表、Returns柱狀圖、Market Insights牛/熊洞察卡片與 Custom Charts 區塊generative-canvas.tsx頂欄 CashPanel展示并支持編輯 Total Cash、Invested、Portfolio Value、4-Year Return 與 Portfolio Allocation 進度條cash-panel.tsx。圖表組件基于Rechartsrecharts^3.0.2見 frontend/package.json位于frontend/src/app/components/chart-components/line-chart.tsx組合 vs SPY 凈值曲線、bar-chart.tsx各 ticker 收益、allocation-table.tsxTicker/% /Value/Return 表格、insight-card.tsx牛熊卡片。10. Next.js 代理路由frontend/src/app/api/copilotkit/route.ts 中前端通過CopilotRuntime注冊crewaiAgent的HttpAgent并借助copilotRuntimeNextJSAppRouterEndpoint把/api/copilotkit端點與OpenAIAdapter組合起來實現瀏覽器 → Next.js 路由 → FastAPI 后端的請求轉發與 SSE 回流。端到端使用流程打開 UI瀏覽器訪問http://localhost:3000左側聊天面板會顯示 Agent 的自我介紹與示例引導Invest in Apple with 10k dollars since Jan 2023并注明僅支持過去 4 年數據發起分析在輸入框提交類似Analyze AAPL and MSFT with $10k each的投資請求??捎^察以下實時事件流ToolLogs 依次出現并點亮 Analyzing user query → Gathering Stock Data → Allocating cash → Extracting Key insights組合面板的 investment_portfolio 被增量更新新 ticker 追加圖表工具調用到達后Performance 折線圖組合 vs SPY、Returns 柱狀圖、Allocation 表格渲染完成并出現 Accept/Reject 按鈕供用戶確認page.tsx接受后牛/熊洞察卡片顯示在 Market Insights 區塊CashPanel 更新總現金、已投入與 4 年回報查看結果若投資參數未被解析例如純閑聊消息Agent 會以打字機效果輸出普通文本回復不觸發任何圖表。開發注意事項與擴展方向解釋器環境若編輯器報缺失導入請確保其指向安裝了依賴的同一 Python 環境uv、venv、conda均可README 推薦在倉庫根目錄執行uv sync。FastAPI 應用位于agent/main.py核心工作流邏輯位于agent/stock_analysis.py。模型配置意圖解析與洞察生成硬編碼使用gpt-4o-mini見 stock_analysis.py 與 #L978-L986依賴OPENAI_API_KEY如需更換模型修改這兩處model參數即可但需確認目標模型兼容 OpenAI 函數調用格式。數據邊界行情僅覆蓋最近 4 年、粒度為季度interval3moSPY 基準使用日線如需更精細回測可調整 simulation 階段 的 interval 參數??蓴U展方向從源碼結構看前端已預留render_custom_charts動作與sandBoxPortfolio狀態可以在此基礎上擴展沙盒組合 vs 真實組合的對比分析也可以將extract_relevant_data_from_user_prompt的 enum 值擴展更多投資頻率??偨Ystock-portfolio-analysis-agent是一個值得完整研讀的端到端示例它把AG-UI 事件協議事件類型、SSE 編碼、增量狀態、CrewAI Flow 多階段編排、yfinance 行情模擬與 SPY 基準對比、CopilotKit React 前端渲染四層技術無縫串聯并額外展示了事件節流優先渲染圖表這類貼近真實產品體驗的工程技巧。無論你是要構建實時可觀測的 Agent 應用還是需要一套可復用的金融分析 Agent 參考實現都可以從 agent/main.py、agent/stock_analysis.py 與 frontend/src/app/page.tsx 這三處源碼入手逐步拆解其設計并遷移到自己的項目中?!久赓M下載鏈接】ai-engineering-hubIn-depth tutorials on LLMs, RAGs and real-world AI agent applications.項目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-hub創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考