初识 FinceptTerminal
开源金融智能终端——用 C++20 和 AI 重塑专业级金融分析
FinceptTerminal 是什么?
想象 Bloomberg Terminal 的能力——实时行情、AI 分析、多资产交易、全球数据——但完全免费、开源,而且跑在你自己电脑上。这就是 FinceptTerminal。
传统专业金融终端年费 $20,000+,市场数据订阅同样 $20,000+/年。FinceptTerminal 的愿景是:100% 免费开源、接入 100+ 数据源、AI 驱动分析、C++ 原生性能——由社区共建,为社区服务。
多资产分析
DCF 估值、投资组合优化、风险指标(VaR、Sharpe)、衍生品定价——覆盖股票、债券、衍生品、另类投资。
37 个 AI 智能体
巴菲特、格雷厄姆、林奇等投资大师风格智能体,经济分析、地缘政治框架——支持本地 LLM、多供应商。
100+ 数据连接器
从 Yahoo Finance 到 IMF、世界银行、各国政府 API——覆盖股票、加密、外汇、经济、新闻全品类。
原生性能
C++20 + Qt6 单一二进制文件,无 Electron/JS 开销,无浏览器运行时——毫秒级响应,极致流畅。
技术栈全景:为什么选 C++20 + Qt6?
FinceptTerminal v4 是一个纯原生 C++20 桌面应用。不是 Electron、不是 Web 应用、不是 Python GUI——而是一个编译后的原生二进制文件。这个选择背后有深思熟虑的理由。
用户界面层
应用层
基础设施层
数据的旅程:从点击"获取 AAPL 报价"到界面更新
FinceptTerminal 遵循严格的 Screen/Service 分离 模式。来看看数据如何在组件之间流转:
代码翻译:读懂应用程序入口
这是 main.cpp 的核心逻辑。左边是 C++ 原始代码,右边是逐行中文解释:
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
app.setApplicationName(
"FinceptTerminal");
app.setStyle("Fusion");
Theme::applyObsidian();
MainWindow window;
window.show();
return app.exec();
}
程序入口——argc 是参数个数,argv 是参数数组
创建 QApplication——Qt 的"大管家",管理整个 GUI 事件循环(鼠标点击、键盘输入、定时器等)
设置应用名称为 "FinceptTerminal"——显示在窗口标题栏和任务管理器中
使用 Fusion 风格——Qt 内置的跨平台统一风格,确保 Windows/Mac/Linux 外观一致
应用 Obsidian 主题——自定义的深色专业金融终端主题(颜色、字体、样式表)
创建 MainWindow——主窗口,包含导航栏、ScreenRouter(屏幕切换器)和状态栏
显示窗口——调用 show() 让窗口出现在屏幕上
启动事件循环——exec() 进入 Qt 事件循环,程序开始响应用户操作,直到窗口关闭
金融终端需要同时处理实时行情推送(WebSocket)、复杂图表渲染、数据库查询和 Python 脚本调用。C++ 的零成本抽象让这些操作并行运行而不卡顿;Qt6 的信号/槽机制天然支持异步事件驱动。编译后的二进制启动不到 1 秒,内存占用远低于 Electron。
项目目录结构
FinceptTerminal 的代码库像一个组织严密的金融机构——每个部门(目录)都有明确的职责:
5 分钟从源码到运行
FinceptTerminal 的构建系统使用 CMake Presets——三条命令就能从源码构建出可执行文件:
git clone https://github.com/Fincept-Corporation/FinceptTerminal.git
cmake --preset macos-release && cmake --build --preset macos-release
macOS 用 macos-release,Linux 用 linux-release,Windows 用 win-release
./build/macos-release/FinceptTerminal.app/Contents/MacOS/FinceptTerminal
点击 "Continue as Guest" 即可开始——无需注册
编译器版本是强制锁定的:CMake 3.27.7、Ninja 1.11.1、Qt 6.8.3、Python 3.11.9。CMake 会用 FATAL_ERROR 级别检查版本——不匹配就直接拒绝构建。
检验你的理解
FinceptTerminal 的 Screen(界面)可以直接调用 HTTP 接口获取数据吗?
FinceptTerminal 内嵌 Python 的方式是什么?
相比 Electron/Web 技术栈,C++20 + Qt6 最大的优势是什么?
C++20 + Qt6 核心架构
深入理解 Screen/Service 分离、事件总线、Result<T> 和 Qt 信号/槽
Screen/Service 分离:金融终端的"前后端"
FinceptTerminal 中每个功能都遵循一个铁律:Screen 只管 UI,Service 只管数据。就像 Web 开发中的前后端分离——但它们跑在同一个 C++ 进程里,通过 Qt 的 信号/槽 机制通信。
Screen(屏幕)
QWidget 子类,只负责渲染 UI。监听用户操作,发射 signal 请求服务;接收 service 的 signal 更新界面。零 HTTP 调用,零数据库访问。
Service(服务)
业务逻辑核心。接收 Screen 的请求 signal,调用 HttpClient/PythonRunner/Database 获取数据,处理完毕后发射 dataReady signal。
Signal/Slot 桥梁
connect(screen, &Screen::requestQuote, service, &Service::onRequestQuote) —— 类型安全的连接,编译期检查参数匹配。
核心基础设施:四个工具让代码更安全
FinceptTerminal 的 src/core/ 目录提供了四个关键工具——它们是整个项目的"基础设施层",被所有 Screen 和 Service 使用:
替代异常和错误码。函数返回 Result<Quote>——要么是成功的 Quote 数据,要么是错误信息。调用者必须处理两种情况,不会遗漏错误。
跨模块通信的"广播站"。任何地方 EventBus::publish("market_data_updated", data) 发消息,所有订阅者自动收到。解耦模块依赖。
LOG_INFO("markets", "Fetched " + count + " quotes") ——统一格式、带标签、写入文件。调试生产问题时的第一工具。
AppConfig::api_base_url() 获取 API 地址——没有魔法字符串(硬编码的 URL),所有常量集中管理。
代码翻译:Result<T> 让错误无处藏身
传统 C++ 用返回码(-1 表示错误)或异常处理错误。FinceptTerminal 用 Result<T>——灵感来自 Rust 的 Result 类型。来看看它怎么工作:
// Service 层返回 Result
Result<Quote> fetchQuote(
const QString& symbol) {
auto reply = http.get(
"/api/quote/" + symbol);
if (!reply.ok) {
return Result<Quote>::err(
"HTTP " + reply.status);
}
auto quote = Quote::fromJson(
reply.body);
return Result<Quote>::ok(
std::move(quote));
}
注释:Service 层返回 Result 类型
函数签名:fetchQuote 接受股票代码,返回 Result<Quote>
通过 HttpClient 发送 GET 请求获取报价数据
如果 HTTP 请求失败(如网络错误、404)
返回错误 Result——包含错误描述,不包含 Quote 数据
如果请求成功,解析 JSON 为 Quote 对象
返回成功 Result——包含 Quote 数据,调用者可以安全使用
std::move 避免 Quote 数据的额外拷贝——零成本抽象
C++ 异常在嵌入式和高性能场景中有性能争议。更重要的是,异常可以在任何地方被抛出、在任何地方被捕获——控制流不透明。Result<T> 让错误处理显式化:你看函数签名就知道它可能失败,必须处理错误才能拿到数据。
对话还原:MarketsScreen 和 MarketDataService 的协作
当你点击 Markets 标签页时,Screen 和 Service 之间的"对话"如下。就像餐厅里顾客(Screen)和服务员(Service)的配合:
线程模型:UI 线程只有一个
Qt 有一个严格的规则:UI 操作只能在主线程。FinceptTerminal 如何在保持 UI 流畅的同时做耗时操作?
Bug 挑战:找出代码中的错误
下面这段代码试图在后台线程更新 UI,但它违反了 Qt 的线程规则。找出哪一行有 Bug:
这段代码会导致什么问题?
QThread* thread = QThread::create([]() {
auto data = httpClient.get("/api/quotes");
tableWidget->setItem(0, 0, new QTableWidgetItem(data));
});
thread->start();
检验你的理解
如果交易引擎需要通知仪表盘"订单已成交",但它们不在同一个 Screen 里,应该用什么机制?
在 FinceptTerminal 中,HTTP 请求是同步阻塞还是异步非阻塞的?
以下哪个操作在 Screen 类中是允许的?
AI 智能体与量化引擎
37 个投资大师智能体、Alpha Arena 竞技场、QuantLib 量化套件
37 个 AI 智能体:每个都是投资大师的"数字分身"
FinceptTerminal 内置了 37 个 AI 智能体,分为三大类:交易员/投资者(巴菲特、格雷厄姆、林奇等)、经济分析师、地缘政治分析师。每个智能体都有独特的投资框架和分析视角。
Warren Buffett
价值投资——寻找有"护城河"的伟大企业,以合理价格买入,长期持有
Benjamin Graham
安全边际——只在股价远低于内在价值时买入,严格防御型投资
Peter Lynch
成长投资——"买你了解的",从日常生活中发现十倍股
Charlie Munger
理性投资——用多学科思维模型做决策,避免心理偏差
Seth Klarman
绝对收益——关注下行保护,在市场中寻找被错误定价的机会
Howard Marks
周期投资——理解市场周期,在别人恐惧时贪婪
智能体支持多个 LLM 供应商:OpenAI、Anthropic、Gemini、Groq、DeepSeek、MiniMax、OpenRouter、Ollama(本地 LLM)。你可以选择用云端的 GPT-4 做深度分析,或者用本地的 Ollama 模型做快速判断——数据不会离开你的电脑。
智能体架构:从 Python 到 C++ 的桥梁
AI 智能体系统由 Python 编写(在 scripts/agents/finagent_core/),但通过 PythonRunner 桥接到 C++ 界面。来看看核心组件:
C++ 界面层
Python 智能体引擎
代码翻译:投资大师角色的"DNA"
每个智能体都有一个 Persona 定义。来看看巴菲特智能体是怎么被定义的:
{
"name": "Warren Buffett",
"category": "trader_investor",
"framework": "value_investing",
"system_prompt": """
You are Warren Buffett.
Focus on: ROE, debt-to-equity,
competitive moat, margin of
safety. Think long-term.
""",
"analysis_steps": [
"assess_business_quality",
"evaluate_moat",
"calculate_intrinsic_value",
"determine_safety_margin"
]
}
智能体名称——沃伦·巴菲特
类别:交易员/投资者(区别于经济分析师、地缘政治分析师)
投资框架:价值投资——巴菲特的核心理念
系统提示词——定义智能体的"人格"和思维方式
你是巴菲特。关注:净资产收益率、资产负债率……
竞争优势的"护城河"、安全边际。长期思维。
分析步骤——智能体按此顺序执行分析
步骤 1:评估业务质量(是否是好生意)
步骤 2:评估护城河(竞争优势是否持久)
步骤 3:计算内在价值(这家公司"值多少钱")
步骤 4:确定安全边际(当前价格比内在价值低多少)
Alpha Arena:AI 智能体的"角斗场"
FinceptTerminal 有一个独特的功能——Alpha Arena。它让多个 AI 智能体在真实市场数据上竞争,tick by tick,用加密审计保证可回放。
Nof1 风格竞技
4 种信号(buy_to_enter / sell_to_enter / hold / close)、3 种模式(Baseline / Monk / Situational),忠实复现 Nof1 S1 规则。
6 个加密永续合约
BTC、ETH、SOL、BNB、DOGE、XRP——来自 Hyperliquid 的真实市场数据,20x 杠杆上限,2% 单笔风险。
加密审计回放
每个 tick 的 prompt、决策、订单、成交都写入 SQLite(WAL 模式)。任何时刻的比赛状态都可以从数据库精确重建。
多层安全开关
KILL ALL 一键平仓、每智能体独立停止、自动断路器(3 次连续解析失败 / 50% 回撤自动停止)。实盘模式需签名确认。
QuantLib 量化套件:18 个专业分析模块
FinceptTerminal 内置了 18 个量化分析模块,覆盖金融工程的四大领域:
期权定价(Black-Scholes、二叉树)、债券定价、互换定价——计算金融衍生品的"公允价值"。
VaR(风险价值)、CVaR、Greeks(Delta/Gamma/Theta/Vega)、压力测试——量化"最坏情况会亏多少"。
蒙特卡洛模拟、随机波动率模型(Heston)、跳跃扩散——用数学模拟未来可能的价格路径。
收益率曲线构建、久期/凸性计算、债券组合分析——管理利率风险。
量化计算由 Python 脚本(scripts/Analytics/)执行——利用 numpy、scipy、pandas 等成熟的金融库。计算结果以 JSON 返回 C++,由 Qt Charts 渲染成专业图表。Python 负责数学,C++ 负责性能和 UI——各取所长。
动手练习:将投资大师匹配到他们的核心理念
把左侧的投资大师拖拽到右侧对应的核心理念上:
检验你的理解
Alpha Arena 竞技场使用的是虚拟数据还是真实市场数据?
如果你不想让金融数据发送到外部 API(如 OpenAI),FinceptTerminal 提供了什么方案?
FinceptTerminal 的量化分析模块(QuantLib 套件)是如何实现的?
交易引擎与数据中枢
16+ 券商接入、Paper Trading 模拟引擎、100+ 数据连接器、SQLite 存储
交易引擎:一个 BrokerInterface,16+ 券商接入
FinceptTerminal 的交易系统采用 插件模式——一个 IBroker 抽象接口,每个券商一个实现类。目前支持 16+ 个券商,覆盖印度、美国、欧洲市场。
印度券商 (10+)
Zerodha、Angel One、Upstox、Fyers、Dhan、Groww、Kotak、IIFL、5paisa、AliceBlue、Shoonya、Motilal——覆盖印度主要券商。
美国券商
IBKR(盈透证券)、Alpaca、Tradier——支持美股交易。Alpaca 还提供原生 Paper Trading 环境。
欧洲券商
Saxo Bank(盛宝银行)——欧洲市场接入,支持多币种、多交易所。
加密货币
Kraken(REST+WebSocket)、HyperLiquid(永续合约)——实时加密货币交易,WebSocket 推送毫秒级行情。
代码翻译:IBroker——所有券商的"合同"
所有券商都必须实现 IBroker 接口——这是它们和交易引擎的"合同"。来看看这份合同规定了什么:
class IBroker {
public:
virtual ~IBroker() = default;
virtual BrokerId id()
const = 0;
virtual const char* name()
const = 0;
virtual const char* base_url()
const = 0;
virtual BrokerProfile
profile() const = 0;
virtual void placeOrder(
const Order&) = 0;
virtual void cancelOrder(
const QString&) = 0;
virtual void getPositions()
= 0;
};
IBroker 是抽象基类——不能直接实例化,只能被继承
虚析构函数——确保删除子类对象时正确清理资源
id() —— 返回券商唯一标识,如 "alpaca"、"zerodha"
name() —— 返回显示名称,如 "Alpaca"、"Zerodha"
base_url() —— 返回 API 基础 URL,如 "https://api.alpaca.markets"
profile() —— 返回券商配置(支持的市场、订单类型、凭据字段等)
placeOrder() —— 下单!传入 Order 对象(股票代码、方向、数量、价格)
cancelOrder() —— 取消指定订单
getPositions() —— 获取当前持仓列表
= 0 表示纯虚函数——子类必须实现所有这些方法
Paper Trading:零风险的"战场演习"
不想用真金白银?Paper Trading 引擎让你在真实市场数据上测试策略,零资金风险。
数据中枢:100+ 连接器如何喂饱金融终端
金融终端的核心价值在于数据。FinceptTerminal 通过 100+ 个 Python 脚本连接全球数据源——每个脚本遵循统一的模式:CLI 参数 → JSON 输出。
yfinance_data.py
雅虎财经——股票报价、历史数据、财务报表(最常用)
coingecko.py
CoinGecko——加密货币实时价格、市值、交易量
fmp_extra_data.py
Financial Modeling Prep——美股财务数据、DCF 模型输入
akshare_index.py
AkShare——A 股指数、期货、宏观数据(中国数据首选)
glassnode_data.py
Glassnode——区块链链上数据(活跃地址、交易所流入流出)
nber_data.py
NBER——美国经济研究局经济周期数据(衰退/扩张时间线)
adb_data.py
亚洲开发银行——亚太地区经济指标
intrinio_data.py
Intrinio——美股历史 EOD 数据、技术指标
所有 100+ 脚本遵循相同的契约:python xxx_data.py command arg1 arg2 → JSON 输出到 stdout。C++ 的 PythonRunner 调用脚本、捕获 stdout、解析 JSON。新增数据源只需写一个新的 Python 脚本,C++ 代码零修改。
代码翻译:数据获取脚本的"模板"
每个数据获取脚本都遵循同一个模式。以 yfinance_data.py 为例:
import sys, json, yfinance
def quote(symbol):
ticker = yfinance.Ticker(symbol)
info = ticker.info
result = {
"symbol": symbol,
"price": info["regularMarketPrice"],
"change": info["regularMarketChangePercent"],
"volume": info["regularMarketVolume"]
}
return result
if __name__ == "__main__":
cmd = sys.argv[1]
if cmd == "quote":
data = quote(sys.argv[2])
print(json.dumps(data))
导入标准库和 yfinance(雅虎财经 Python 库)
定义 quote 函数——获取股票实时报价
创建 Ticker 对象——代表一只股票
获取股票信息字典
构造结果字典——只提取我们需要的字段
股票代码,如 "AAPL"
当前价格
涨跌幅百分比
成交量
返回结果字典
脚本入口——当从命令行运行时执行
读取第一个参数作为命令(如 "quote")
如果是 "quote" 命令,调用 quote 函数
将结果序列化为 JSON 并打印到 stdout——C++ 端 PythonRunner 捕获这行输出
存储层:13 个 Repository 和加密凭据存储
FinceptTerminal 使用 SQLite 作为本地存储引擎,通过 13 个 Repository 类提供数据访问。
核心存储
SettingsRepository(应用设置)、WatchlistRepository(自选股列表)、ChatRepository(聊天记录)——用户个性化数据的持久化。
加密存储
SecureStorage 使用平台密钥链(macOS Keychain / Windows Credential Manager)或 AES 加密存储 API Key、券商凭据——绝不明文保存。
缓存数据库
CacheDatabase 使用 SQLite WAL 模式——多线程并发读写不阻塞。TTL(过期时间)自动清理旧数据,避免缓存无限膨胀。
检验你的理解
如果你想给 FinceptTerminal 添加一个新的券商(如 Interactive Brokers),需要修改哪些代码?
100+ 个 Python 数据脚本和 C++ 之间的数据交换格式是什么?
Paper Trading 模拟引擎的订单撮合(匹配)发生在哪里?
MCP 工具集成与实战贡献
MCP 协议让 AI 操作终端、节点编辑器可视化工作流、如何贡献代码
MCP:让 AI "操控" 金融终端
MCP(Model Context Protocol) 是 FinceptTerminal 最强大的 AI 集成机制。它让 AI 不只是"建议你做什么",而是直接操作终端——获取数据、分析图表、甚至下单。
普通 AI 聊天:你问"苹果股票怎么样?" → AI 回复一段分析文字。
FinceptTerminal MCP:你问同样的问题 → AI 自动调用 MarketsTools 获取实时数据、调用 PortfolioTools 分析你的持仓、调用 NewsTools 抓取最新新闻——然后给出基于真实数据的分析。
MarketsTools
AI 直接获取股票报价、历史数据、技术指标——不需要你手动搜索。
NewsTools
AI 抓取最新新闻、分析舆情、聚类相关报道——信息聚合零延迟。
PortfolioTools
AI 读取你的投资组合、计算风险指标、建议调仓——你的私人 AI 基金经理。
PaperTradingTools
AI 在模拟环境中执行交易策略——自动买卖、跟踪绩效、回测验证。
EdgarTools
AI 直接读取 SEC 财报文件(10-K、10-Q)——自动分析公司财务健康度。
20+ 更多工具
DataHubTools、WatchlistTools、SettingsTools、PythonTools、ReportBuilderTools……覆盖终端所有功能。
MCP 架构:AI 请求如何变成终端操作
当你对 AI 说"分析一下我的 AAPL 持仓"时,MCP 系统内部发生了什么?来看看数据流:
节点编辑器:用可视化管道构建自动化工作流
FinceptTerminal 有一个强大的 节点编辑器——让你通过拖拽连接数据管道,不需要写一行代码就能构建自动化工作流。
节点编辑器三大区域
示例工作流:市场数据 → 技术分析 → 交易信号
安全架构:金融终端的"保险库"
处理金融数据的终端必须把安全放在第一位。FinceptTerminal 从四个层面保护你的数据和资金:
所有 HTTPS 连接使用 Qt TLS 加密。WebSocket 行情推送同样走 WSS(加密 WebSocket)。零明文传输。
SecureStorage 使用平台原生密钥链(macOS Keychain / Windows Credential Manager)或 AES-256 加密存储 API Key。源码中零密钥。
JWT 认证 + SessionGuard 自动登出(检测到 401 响应立即清除会话)。PIN 码保护(可选)。不活跃超时自动锁定。
所有外部输入(API 响应、用户输入)在系统边界做净化(sanitization),防止注入攻击。SchemaValidator 确保 MCP 工具返回的数据格式正确。
如何为 FinceptTerminal 贡献代码
FinceptTerminal 是开源项目(AGPL-3.0),欢迎社区贡献。根据你的技能和时间,有四条路径:
修正 docs/ 目录下任何 .md 文件中的错别字或不清楚的描述。这是最好的入门方式——熟悉项目结构。
按照 scripts/yfinance_data.py 的模式(CLI 参数 → JSON stdout),写一个新的免费 API 数据获取器。参考 docs/PYTHON_CONTRIBUTOR_GUIDE.md。
在 src/screens/ 下新建目录,创建 QWidget 子类,添加到 CMakeLists.txt,在 MainWindow 注册。参考 src/screens/dashboard/ 作为模板。
继承 IBroker 接口,实现所有纯虚函数,在 BrokerRegistry 注册。参考 src/trading/brokers/alpaca/ 作为模板。
4 空格缩进、120 列宽限制。函数/变量用 snake_case,类型/类用 PascalCase。成员变量加后缀下划线(data_)。所有 QObject 子类必须包含 Q_OBJECT 宏。用新的指针到成员语法连接 signal/slot。
代码翻译:如何新增一个 MCP 工具
新增 MCP 工具需要两个文件:一个 .h 头文件声明工具,一个 .cpp 文件实现工具逻辑。来看看 MarketsTools 的核心结构:
// MarketsTools.h
class MarketsTools : public QObject {
Q_OBJECT
public:
static void registerTools(
McpManager& mgr) {
mgr.registerTool(
"market_quote",
// Schema: 参数定义
{"symbol", "string",
"Stock symbol"},
// Handler: 执行逻辑
[](QJsonObject args) {
auto s = service();
return s.getQuote(
args["symbol"]
.toString());
});
}
};
MarketsTools 是一个 QObject 子类(Qt 对象系统要求)
Q_OBJECT 宏——启用 signal/slot 和元对象系统
静态方法 registerTools——在应用启动时调用,注册所有工具
接收 McpManager 引用——工具注册中心
注册一个名为 "market_quote" 的工具
工具参数定义(Schema)——告诉 AI 这个工具需要一个 string 类型的 symbol 参数
参数名 "symbol"
参数类型 "string"
参数描述 "Stock symbol"——AI 看到这个描述就知道该传什么
执行处理器(Handler)——当 AI 调用工具时执行的 Lambda 函数
获取 MarketDataService 实例
调用 getQuote 并传入 AI 提供的 symbol 参数
返回结果给 AI——AI 拿到报价数据后继续分析
最终检验:FinceptTerminal 全课程回顾
MCP 协议让 FinceptTerminal 的 AI 智能体和普通 AI 聊天的最大区别是什么?
FinceptTerminal 如何保护你的 API Key 和券商凭据?
贯穿 FinceptTerminal 所有功能的核心设计模式是什么?
课程总结:你的 FinceptTerminal 知识地图
恭喜你完成了 FinceptTerminal 的完整学习旅程!来回顾一下你掌握的核心知识:
C++20 + Qt6 原生架构、Screen/Service 分离、信号/槽通信、Python Bridge 子进程桥接。
Result<T> 错误处理、EventBus 事件总线、Logger 日志、AppConfig 配置——四大工具让代码更安全。
37 个投资大师角色、Persona 系统定义、Alpha Arena 竞技场、QuantLib 18 个量化模块。
IBroker 插件模式、16+ 券商、Paper Trading 模拟、100+ Python 数据连接器、SQLite 13 个 Repository。
MCP 协议让 AI 操作终端、节点编辑器可视化工作流、安全架构四层防护、社区贡献四条路径。
代码在 GitHub:https://github.com/Fincept-Corporation/FinceptTerminal。从 Issue 列表中选一个新手友好(good first issue)的任务开始——15 分钟的文档改进就是最好的第一步。加入 Discord 社区获取帮助,或通过 GitHub Discussions 提问。