Exp3-WIX算法:利用噪声侧观测与反馈图优化在线决策

1. 项目背景:当在线学习遇上“带噪声的旁听”

在机器学习,特别是强化学习和在线决策领域,我们常常面临一个经典问题:智能体(Agent)需要在与环境的持续交互中,通过获得的反馈(Reward)来学习最优策略。想象一下,你是一个每天要决定投资哪只股票的操盘手,每次选择后,你只能看到自己买入的那只股票的涨跌(即时奖励),而对其他成千上万只股票的当日表现一无所知。这就是典型的**赌博机(Bandit)**问题——你只能获得所选动作的反馈,信息极其有限。

然而,现实世界往往比这更“嘈杂”和“慷慨”。有时,即使你没有选择某个动作,也能间接地、模糊地感知到它的表现。这就是“噪声侧观测(Noisy Side Observations)”的核心场景。继续用股票的例子,你可能订阅了某个行业分析简报,里面会模糊地提到“今日科技板块整体承压”,虽然你没买某只具体的科技股,但这个信息让你对“买入科技股”这个动作的潜在收益有了一个带有噪声的估计。这个观测不是直接的、精确的,但它包含了有价值的信息。

为了有效利用这种间接的、带噪声的信息,研究者引入了**反馈图(Feedback Graph)**模型。这个图定义了动作(或“臂”,Arm)之间的观测关系。如果图中从动作 A 到动作 B 有一条有向边,那么当智能体选择动作 A 时,它不仅能获得 A 的奖励,还能获得一个关于动作 B 的、带有随机噪声的观测值。这个模型极大地扩展了经典赌博机问题的适用范围,使其能够建模社交网络学习、广告投放(看到竞争对手广告的近似效果)、网络路由探测等复杂场景。

但问题来了:如何设计一个算法,既能利用这些额外的、含噪的侧观测信息来加速学习、减少遗憾(Regret,即与始终选择最优动作相比的累计收益损失),又能保证在噪声干扰下的理论性能边界?这就是Exp3-WIX 算法所要回答的问题。它是在经典指数权重算法(Exp3)基础上,针对带有反馈图结构的噪声侧观测环境的一次重要演进。WIX 代表了其核心的权重更新机制,能够更稳健地处理观测噪声。

2. 反馈图模型:定义信息流动的“高速公路网”

在深入算法之前,我们必须先厘清反馈图模型,它是整个问题的基石。理解了这个模型,才能明白 Exp3-WIX 到底在优化什么。

2.1 模型的形式化定义

假设我们有 K 个动作,编号为 1 到 K。在每一轮 t(t=1, 2, …, T):

  1. 智能体选择:算法基于历史信息,选择一个动作 A_t(例如,选择播放第5个视频)。
  2. 环境生成奖励:环境(或对手)为每个动作 i 生成一个奖励 X_t(i)。这个奖励通常是未知的,可能来自某个随机分布,也可能由对抗性环境决定。
  3. 智能体接收反馈:智能体获得两部分信息:
    • 直接奖励:它收到自己所选动作 A_t 的真实奖励 X_t(A_t)。
    • 侧观测:对于所有满足“从 A_t 到 j 存在有向边”的动作 j,智能体会收到一个观测值 Y_t(j)。这个观测值不等于真实奖励 X_t(j),而是带有加性噪声:Y_t(j) = X_t(j) + η_t(j)。其中 η_t(j) 是噪声项,通常假设其均值为零,方差有界。

这里的有向图 G = (V, E)就是反馈图。顶点集 V 对应 K 个动作。边集 E 定义了观测关系:如果 (i, j) ∈ E,那么选择动作 i 时,可以观测到动作 j 的带噪奖励。

2.2 图的拓扑结构如何影响学习难度

反馈图的连接性质直接决定了侧观测信息的丰富程度,从而影响了算法能达到的最优遗憾界。

  • 完全图:这是最理想的情况,选择任何一个动作,都能观测到所有其他动作的带噪信息。学习速度可以非常快,遗憾界可以低至 O(√T) 甚至对数级别(取决于噪声和奖励假设)。
  • 空图:即没有边。这就是经典的赌博机问题,只能获得所选动作的反馈。这是最困难的情况,遗憾下界是 Ω(√(KT))。
  • 非对称图:这是最一般也最有趣的情况。观测关系可能是单向的。例如,在社交网络中,一个大V(动作A)发帖,他的粉丝(动作B)能看到其效果(A->B有边),但粉丝发帖大V却看不到(B->A无边)。这种不对称性要求算法能处理信息流动的不均衡。
  • 独立集与图着色的关联:一个关键概念是图的独立集。独立集中的顶点两两之间没有边相连。这意味着,如果你选择的动作属于某个独立集,那么你无法通过侧观测获得该集合内其他动作的任何信息。图的染色数χ(G) 是将顶点着色使得相邻点颜色不同的最少颜色数,它等价于将图划分成 χ(G) 个独立集。这个数 χ(G) 深刻影响了最优遗憾界,因为它代表了信息获取的“瓶颈”。

提示:在实际建模时,构建一个合理的反馈图至关重要。你需要问自己:选择动作A,究竟能“照亮”哪些其他动作的状态?这种照亮是精确的还是模糊的?这个图的稀疏性(边数多少)和对称性,直接决定了你能从数据中挖掘多少额外信息。

2.3 为什么侧观测是“噪声”的?

这是一个非常现实的假设。在股票例子中,行业简报是分析师对整体情况的概括和解读,必然丢失个股细节并引入主观噪声。在网络广告中,通过第三方数据平台估算竞争对手广告的点击率,肯定存在测量误差和统计偏差。在推荐系统中,通过用户相似性来推断其对未曝光商品的喜好,更是一个充满噪声的估计过程。

算法不能假设 Y_t(j) = X_t(j)。它必须设计得对噪声 η_t(j) 具有鲁棒性。如果算法过于信任噪声观测,可能会被误导;如果完全忽略它们,又浪费了信息。Exp3-WIX 的核心创新之一,就在于其权重更新公式巧妙地平衡了直接奖励和噪声侧观测的信赖度。

3. Exp3-WIX 算法核心:稳健的权重更新与探索策略

Exp3-WIX 并非凭空创造,它建立在两大基石之上:一是用于对抗性赌博机的Exp3 算法,二是用于带反馈图赌博机的Exp3-IX 算法。WIX 中的 “W” 暗示了其对噪声的稳健(Weighted/ Robust)处理。

3.1 回顾 Exp3 与 Exp3-IX

  • Exp3(Exponential-weight for Exploration and Exploitation):这是解决对抗性多臂赌博机问题的标杆算法。它为每个动作 i 维护一个权重 w_t(i)。每一轮,它根据权重计算一个概率分布 p_t(i) ∝ w_t(i) 来选择动作。收到奖励后,它用奖励的估计值(通过重要性采样得到)来更新权重:w_{t+1}(i) = w_t(i) * exp(η * 估计奖励)。这里的 η 是学习率。IX(Implicit Exploration)是 Exp3 的一个变种,它在计算概率分布时引入了一个小的常数 γ,使得 p_t(i) = (1-γ)*(w_t(i)/sum_w) + γ/K,这保证了最小探索概率,从而能得到更紧的遗憾界,特别是在反馈图环境下。

  • Exp3-IX:它将 Exp3-IX 扩展到了反馈图设置。其核心思想是,当选择动作 A_t 时,不仅更新 A_t 的权重,也利用侧观测(假设无噪声)来更新所有可观测动作 j 的权重。其奖励估计器设计为:对于可观测的动作 j,估计奖励 = 观测值 / (p_t(A_t) + γ),这里的分母是为了抵消选择概率低带来的估计方差。Exp3-IX 在无噪声侧观测的假设下,达到了接近最优的遗憾界 O(√(α(G)T)),其中 α(G) 是图 G 的独立数,是图复杂性的一个度量。

3.2 Exp3-WIX 的关键改进:处理噪声

Exp3-IX 在 Y_t(j) = X_t(j) 时表现完美。但一旦观测带有噪声,即 Y_t(j) = X_t(j) + η_t(j),直接使用 Y_t(j) 进行更新就会出问题。噪声 η_t(j) 的期望为零,但方差不为零。在 Exp3-IX 的更新规则下,噪声项会被除以一个很小的概率 p_t(A_t) + γ,这可能会剧烈放大噪声的方差,导致权重更新极不稳定,算法可能被随机噪声“带偏”。

Exp3-WIX 的解决方案是引入一个稳健的奖励估计器。它不再直接使用观测值 Y_t(j),而是对其进行“收缩”或“截断”处理,以防止过大的噪声值主导更新。具体来说,它采用了一种加权或稳健统计的思想。

一个典型的设计(具体公式可能因论文而异,但思想一致)是使用一个置信区间阈值。算法维护对每个动作奖励的估计均值和方差(或二阶矩)。当收到侧观测 Y_t(j) 时,先检查它是否落在基于历史数据计算的合理区间内。如果落在区间内,则认为它相对可靠,可用于更新;如果严重偏离,则对其进行截断或赋予较小的权重。

数学上,这常常体现为在损失函数或更新项中加入一个正则项,或者使用像Huber损失截断估计量这样的稳健统计工具。WIX 中的 “W” 可以理解为对观测值进行了稳健加权(Weighting),降低异常噪声观测的影响。

3.3 算法步骤拆解

让我们勾勒出 Exp3-WIX 算法一回合的核心步骤:

  1. 初始化:为每个动作 i 设置初始权重 w_1(i) = 1。设定学习率参数 η, 探索参数 γ, 以及稳健化参数 λ(用于控制对噪声的容忍度)。
  2. 对于每一轮 t = 1 to T: a.计算选择概率:对于所有动作 i,计算 p_t(i) = (1-γ) * [w_t(i) / Σ_j w_t(j)] + γ/K。这保证了至少 γ/K 的探索概率。 b.采样动作:根据概率分布 p_t 随机选择一个动作 A_t。 c.接收反馈:获得直接奖励 X_t(A_t),以及对于所有满足 (A_t, j) ∈ E 的动作 j,获得带噪侧观测 Y_t(j)。 d.构建稳健奖励估计:对于每个动作 i,构建一个估计值 ĝ_t(i)。 * 如果 i == A_t(所选动作):ĝ_t(i) = X_t(A_t) / (p_t(A_t) + γ)。(直接奖励的重要性采样估计,与Exp3-IX相同)。 * 如果 (A_t, i) ∈ E(可侧观测的动作):计算一个稳健化后的观测值 Ȳ_t(i)。例如,Ȳ_t(i) = sign(Y_t(i)) * min(|Y_t(i)|, U_t(i)),其中 U_t(i) 是一个基于历史方差估计的动态上界。然后,ĝ_t(i) = Ȳ_t(i) / (p_t(A_t) + γ)。 * 其他情况:ĝ_t(i) = 0。(无任何信息)。 e.更新权重:对于所有动作 i,更新权重:w_{t+1}(i) = w_t(i) * exp( η * ĝ_t(i) )。这里的关键是,对于侧观测动作,ĝ_t(i) 使用的是经过稳健处理的 Ȳ_t(i),而非原始的 Y_t(i)。

3.4 参数选择与理论保证

  • 学习率 η:通常设置为 η ∝ √(logK / (T * α(G)))。学习率控制了更新步长,需要根据总回合数 T 和图复杂度 α(G) 调整。T 越大,η 应越小以保证收敛。
  • 探索参数 γ:通常 γ ∝ η。它保证了足够的探索,避免过早收敛到次优动作。
  • 稳健化参数 λ 或 U_t(i):这与噪声的方差上界 σ² 有关。如果已知噪声方差边界,可以据此设置截断阈值。在实际中,可能需要在线估计噪声的尺度。

在满足噪声 η_t(j) 独立、零均值、方差有界(Var[η_t(j)] ≤ σ²)的假设下,Exp3-WIX 能够证明其遗憾上界为O( √(α(G) T logK) + σ * PolyLog Terms )。与 Exp3-IX 的无噪声界相比,多出了一个与噪声标准差 σ 成正比的项。这直观地表明:噪声越大,学习越慢,但算法依然能保证性能不会崩溃。

4. 实战模拟:用Python实现Exp3-WIX并验证其优势

理论再完美,也需要代码来验证。下面我们用一个简化的模拟实验来展示 Exp3-WIX 如何处理噪声侧观测,并与 Exp3-IX 在噪声环境下的表现进行对比。

4.1 环境设置

我们假设有 K=5 个动作。它们的真实平均奖励 μ = [0.9, 0.7, 0.5, 0.3, 0.1],最优动作是第1个。奖励 X_t(i) 以概率 μ[i] 为1,否则为0(伯努利奖励)。我们定义一个简单的有向反馈图:动作1可以观测到动作2和3;动作2可以观测到动作3和4;动作3可以观测到动作4和5;动作4和5只能观测自己。这是一个单向的信息流。

侧观测噪声 η_t(j) 我们假设服从均值为0,标准差为 σ 的高斯分布。我们将比较 σ=0(无噪声)、σ=0.2(轻度噪声)和 σ=0.5(重度噪声)三种情况。

4.2 代码实现核心部分

import numpy as np import matplotlib.pyplot as plt class Exp3WIX: def __init__(self, n_actions, graph, eta, gamma, noise_std=0.0, trunc_threshold=5.0): self.K = n_actions self.graph = graph # 邻接矩阵,graph[a][b]=1 表示选择a可观测b self.eta = eta self.gamma = gamma self.sigma = noise_std self.trunc = trunc_threshold # 简单的截断阈值 self.weights = np.ones(n_actions) self.cumulative_regret = 0 self.best_mean = None # 最优动作的平均奖励 def select_action(self): prob = (1 - self.gamma) * (self.weights / np.sum(self.weights)) + self.gamma / self.K return np.random.choice(self.K, p=prob), prob def update(self, chosen_action, prob_vec, rewards, observations): """ rewards: 所有动作的真实奖励(仅用于计算遗憾,算法未知) observations: 字典,key是可观测的动作j,value是带噪观测值 Y_t(j) """ # 计算遗憾 instant_regret = self.best_mean - rewards[chosen_action] self.cumulative_regret += instant_regret # 构建稳健奖励估计 g_hat g_hat = np.zeros(self.K) # 1. 所选动作的直接奖励估计 g_hat[chosen_action] = rewards[chosen_action] / (prob_vec[chosen_action] + self.gamma) # 2. 对可侧观测的动作进行稳健更新 for j, y_obs in observations.items(): # 稳健化处理:简单的软截断 robust_y = np.clip(y_obs, -self.trunc, self.trunc) g_hat[j] = robust_y / (prob_vec[chosen_action] + self.gamma) # 3. 权重更新 self.weights *= np.exp(self.eta * g_hat) # 防止权重溢出(数值稳定性) self.weights = np.clip(self.weights, 1e-10, 1e10) # 模拟实验主循环 def run_experiment(T, noise_std, algorithm_class, **algo_kwargs): K = 5 means = np.array([0.9, 0.7, 0.5, 0.3, 0.1]) best_mean = np.max(means) # 定义反馈图 (邻接矩阵) graph = np.zeros((K, K), dtype=int) edges = [(0,1), (0,2), (1,2), (1,3), (2,3), (2,4)] for i,j in edges: graph[i][j] = 1 # 每个动作至少能观测自己 for i in range(K): graph[i][i] = 1 algo = algorithm_class(n_actions=K, graph=graph, noise_std=noise_std, best_mean=best_mean, **algo_kwargs) algo.best_mean = best_mean cumulative_regrets = [] for t in range(T): # 算法选择动作 chosen_action, prob_vec = algo.select_action() # 环境生成奖励 rewards = np.random.binomial(1, means) # 生成带噪侧观测 observations = {} for j in range(K): if graph[chosen_action][j]: noise = np.random.normal(0, noise_std) observations[j] = rewards[j] + noise # 算法更新(注意:算法update内部用到了rewards计算遗憾,但更新权重时只用了observations) algo.update(chosen_action, prob_vec, rewards, observations) cumulative_regrets.append(algo.cumulative_regret) return cumulative_regrets # 参数设置 T = 5000 eta = 0.01 gamma = 0.05 trunc_threshold = 3.0 # 运行对比 noise_levels = [0.0, 0.2, 0.5] plt.figure(figsize=(12, 8)) for sigma in noise_levels: print(f"Running with noise std = {sigma}") # 使用稳健截断的WIX版本 regrets_wix = run_experiment(T, sigma, Exp3WIX, eta=eta, gamma=gamma, trunc_threshold=trunc_threshold) # 作为对比,一个“朴素”版本,不对噪声做处理(类似Exp3-IX在噪声下的表现) regrets_naive = run_experiment(T, sigma, Exp3WIX, eta=eta, gamma=gamma, trunc_threshold=100.0) # 很大的截断,相当于不截断 plt.plot(regrets_wix, label=f'Exp3-WIX (σ={sigma})', linewidth=2) plt.plot(regrets_naive, '--', label=f'Naive (No Trunc, σ={sigma})', alpha=0.7) plt.xlabel('Rounds (t)') plt.ylabel('Cumulative Regret') plt.title('Exp3-WIX vs Naive Approach under Different Noise Levels') plt.legend() plt.grid(True, alpha=0.3) plt.show()

4.3 结果分析与实操要点

运行上述代码,你可能会观察到以下现象:

  1. 无噪声(σ=0)时:Exp3-WIX(由于截断阈值设置合理,未触发截断)和朴素版本的曲线几乎重合,且遗憾增长很慢。这说明在理想条件下,算法能有效利用侧观测信息快速找到最优动作。
  2. 轻度噪声(σ=0.2)时:Exp3-WIX 的遗憾曲线仍然保持较低的增长速度。而朴素版本的遗憾开始明显高于 WIX,尤其是在中期。这是因为放大的噪声干扰了权重的正确更新,导致算法需要更多轮次来纠正错误。
  3. 重度噪声(σ=0.5)时:差距最为明显。Exp3-WIX 的遗憾虽然也因噪声而升高,但增长相对可控。朴素版本的遗憾则可能急剧上升,算法表现几乎与忽略侧观测无异,甚至更差,因为它被噪声严重误导。

注意:这里的“朴素版本”只是为了对比演示而简化的。在实际的 Exp3-IX 理论中,它并未考虑噪声,在噪声环境下其理论保证不再成立。我们的模拟直观地展示了不处理噪声的危害。

实操心得与调参技巧

  • 截断阈值 U_t 的选择:这是 Exp3-WIX 的核心超参数。设置太小会损失有效信号,设置太大则无法抑制噪声。一个实用的启发式方法是:在初期可以设置得宽松一些,随着轮次增加,根据观测值的滚动方差或中位数绝对偏差(MAD)来动态调整 U_t。例如,U_t = median(|Y|) + 3 * MAD。
  • 探索参数 γ 的重要性:在噪声环境下,保持一定的探索率 γ 比在无噪声环境中更重要。因为噪声可能导致对某些次优动作的奖励估计暂时虚高,探索可以帮助算法跳出这些局部陷阱。通常 γ 与 η 同量级或稍大。
  • 图的先验知识:如果你知道反馈图是稠密的(如完全图),那么侧观测信息丰富,可以给 η 设置更大的值,学习更快。如果图很稀疏,则应保守一些。算法对图稀疏性的适应能力,体现在其遗憾界与独立数 α(G) 的关系上。
  • 数值稳定性:权重乘法更新可能导致数值上溢或下溢。代码中的np.clip是一个简单的保护措施。更稳健的做法是维护权重的对数(log-weights),在概率空间进行计算。

5. 超越理论:在实际场景中应用与挑战

Exp3-WIX 不仅是一个理论玩具,它在许多有噪声信息流的场景中都有用武之地。然而,将理论算法落地,总会遇到论文中未曾详述的挑战。

5.1 潜在应用场景

  1. 个性化推荐与广告排序:平台需要从海量商品/广告中选择一个展示给用户(选择动作)。用户点击/购买行为是直接奖励。同时,平台可能通过协同过滤模型、用户画像相似性,估算该用户对其他未展示商品的点击概率(带噪声的侧观测)。这些观测构成了一个以用户或商品为节点的复杂反馈图。Exp3-WIX 可以帮助平台在探索新商品和利用相似用户信息之间取得平衡,同时抵御推荐模型预测不准带来的噪声。
  2. 网络性能探测与路径选择:在内容分发网络(CDN)或数据中心网络中,需要选择服务器或路径(动作)。直接测量所选路径的延迟/丢包率是直接奖励。通过轻量级的网络遥测(如ICMP ping、间接链路状态推理)可以获得其他路径的近似性能指标(噪声侧观测)。反馈图由网络拓扑决定。算法可以更快地避开拥塞链路。
  3. 金融量化交易:交易员每天选择一篮子股票进行交易(动作)。所选篮子的收益是直接奖励。通过行业报告、新闻情绪分析、相关资产价格变动,可以对未直接交易的股票产生带有噪声的未来收益预测(侧观测)。这些股票间的关联性(如同行业、同产业链)构成了反馈图。
  4. 科学实验设计:在药物筛选或材料合成中,每次实验选择一种配方(动作),实验结果(如药效、材料强度)是直接奖励。基于配方在化学空间的距离或已知的构效关系模型,可以对未实验的配方进行性质预测(噪声观测)。这能大幅减少所需实验次数。

5.2 落地实施中的关键挑战与应对

  1. 反馈图的动态性与未知性:理论假设图 G 是静态且已知的。现实中,观测关系可能随时间变化(社交网络关系变化),或完全未知。解决方案:可以结合图学习技术。初期使用一个全连接或基于领域知识的初始图,然后根据观测数据的相关性,在线地、稀疏地更新图的邻接关系。例如,如果两个动作的侧观测值长期高度相关,则可以增加或强化它们之间的边。
  2. 非平稳奖励与观测噪声:奖励分布和噪声分布可能随时间漂移。解决方案:采用滑动窗口或指数衰减的权重更新。为历史数据赋予衰减的权重,让算法更关注近期经验。同时,稳健化参数 U_t 也需要能够自适应非平稳的噪声水平。
  3. 动作空间巨大(K很大):当动作数达到百万甚至千万级(如商品推荐),维护一个 K 维的权重向量并计算 softmax 概率是不现实的。解决方案:与 bandit 算法中的线性上下文、神经网络策略等方法结合。将动作表示为特征向量,维护一个参数化策略(如神经网络),权重更新转化为对策略参数的梯度更新。侧观测信息可以作为额外特征输入到网络中。
  4. 延迟反馈与部分观测:实际场景中,反馈(尤其是直接奖励)可能严重延迟。例如,广告点击可能发生在展示后很久,商品购买可能在下单几天后。解决方案:这超出了标准 Exp3-WIX 的范畴,需要与延迟反馈赌博机算法结合。一个思路是使用“伪奖励”和重要性采样的技术,对延迟的奖励进行无偏估计。
  5. 计算效率:每一轮需要为所有可观测动作计算稳健估计并更新权重。如果图很稠密,计算量是 O(K)。优化:对于超大规模场景,可以采用分布式更新,或只对权重排名靠前的部分动作进行精确更新,对长尾动作采用近似更新。

5.3 一个简化的推荐系统案例设想

假设我们有一个视频推荐系统,有1000个视频(动作)。用户 u 的特征向量为 f_u。

  • 直接奖励:用户点击了推荐的视频,奖励为1,否则为0。
  • 侧观测生成:我们有一个协同过滤模型 M。当给用户 u 推荐视频 i 时,模型 M 可以预测用户 u 对视频 j 的点击概率 p_{u,j}。我们将这个预测值作为对视频 j 的带噪侧观测 Y_t(j)。噪声来源于模型的不确定性。
  • 反馈图构建:我们定义,如果视频 i 和 j 的内容特征向量(如标签、嵌入)余弦相似度超过阈值 θ,则建立双向边 (i, j) 和 (j, i)。这意味着推荐一个视频,可以获得与其相似视频的预测信息。
  • 算法运行:系统使用 Exp3-WIX。每一轮,根据用户特征 f_u(可通过上下文赌博机框架融入),算法选择一个视频 i 推荐。收到点击反馈后,不仅更新视频 i 的权重,还利用模型 M 对所有与 i 相似的视频 j 的预测值 p_{u,j}(经过稳健化处理),来更新视频 j 的权重。

这样,系统不仅能从直接互动中学习,还能通过内容相似的“信息通道”,快速将知识传递到整个视频库,加速对新用户或冷门视频的学习过程,同时通过稳健化处理抵御推荐模型预测不准的噪声。

最后需要强调的是,Exp3-WIX 提供了一个强大的框架来思考如何利用结构化、带噪的额外信息。它的核心思想——在利用额外信息时,必须考虑其可靠性并进行稳健化处理——具有普遍的指导意义。在实际工程中,你可能不需要完全照搬其数学公式,但理解其原理将帮助你在设计在线学习系统时,做出更明智的架构选择。例如,是否以及如何引入外部信号?如何量化这些信号的置信度?如何防止低置信度信号污染核心模型?这些问题都可以从 Exp3-WIX 的设计哲学中找到启发。