MoreRSS

site iconRay Xiong | 四火修改

熊燚,平台软件工程师,华为 - Amazon - Oracle,从漂泊南京、北京,到目前定居西雅图。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Ray Xiong | 四火的 RSS 预览

为什么我不买大盘,只坚持投资个股

2026-09-14 13:33:00

投资美股已经有些年了,之前也基于自己的体会和理解陆陆续续写了一些文章,每个持续投资的人都会有自己的理念和方法论,我也不例外。今天想来谈论一个有意思的话题,为什么我美股投资,对于我主要的资金(401k 以外的),多年来都不买大盘(标普 500),只投资个股,并且是坚持持续地投资个股。

巴菲特曾经说过,对于大多数人来说,标普 500 指数,是一个最佳的选择。一些在争论是不是应该投资大盘的时候,经常听到这样的回答——“费那么大劲,还不如直接买标普 500 呢”。这其实是一个普遍的问题,但是不见得参与讨论的人都说得清楚。如果某段时间的投资收益高于标普,尚且会被如此评论,如果这段时间的收益低于标普,那就更得被奚落了。但是我思考了几次这个问题,我觉得对于个股的投资,于我来说,有着诸多清晰且不可替代的好处。

首先,要理解的一点是,为什么投资标普 500 那么值得推崇?

投资大盘的逻辑其实很简单,就是相信未来,相信这最具代表性的五百家企业,同时,在相信的同时也接受平庸。

我非常同意这就是大多数人的最佳选择。因为买了标普,就放弃了超越市场获取α收益的可能性,获得的是根上市场平均收益β的确定性。对于没有时间去研究板块和公司的人来说,这是最省心、也是在得到市场收益的前提下,最不容易亏钱的途径。

具体来说,买标普 500 就意味着:

  1. 不用去选股,因为大多数人都无法具备专业投资机构的选股能力。
  2. 不用去紧跟行业潮流,因为指数带有优胜劣汰机制。
  3. 不用去花时间研究生意和财务,因为市场已经用脚投票。
  4. 抵消掉单一公司的风险,只接受系统性风险。

听起来很美好,对以上几条我也没有异议。但是,我一直都有一些对于闭眼买大盘的疑虑,并且这些疑虑逐年加深。

首先,买大盘就放弃了个体投资者的认知优势。

是的,通常我们说群体优势,但并非任何事情都是群体比个体更有优势的,特定领域的认知就是一个例子。我认为,很多人都是有自己独特眼光的。比方说,我虽然看不懂能源公司,我看不懂医疗赛道,我却研究过某些科技公司,甚至某几家科技公司自己就曾经工作过,有过比一般人更多一些的认识。我有自己熟悉的领域,我认为,对于某些商业模式的理解,相较于那些只看财报和数据的分析师,我更相信我的判断。我也有医生朋友,他对于医疗领域就有很多研究,这是一样的道理。

需要说明的是,每个人的认知是有局限性的,很难能够在广泛程度上打败市场,但在特定的少数几家公司和几个生意上,却是有可能击败大众共识的。

为什么要在谈论投资的时候首先谈论认知?因为投资回报,本质上就是认知的变现。

其次,买自己理解的公司,心里更踏实,睡觉更安心。

踏实和安心,说的其实就两件事情:

  1. 是不是能够理解投资对象的具体内容和逻辑
  2. 是不是能够看懂和接受投资的风险

难道不是标普大盘更踏实、更安心吗?我并不这么认为,市场的平均并不能取代对于公司和商业模式的理解。一篮子的公司,大部分我都是不了解的,却让我把大量的资金押注在它们上面,逻辑上的矛盾始终都在,我也不太能长期接受。

从我的角度来说,越是觉得自己理解的公司,我就越愿意用一个更大的仓位去长期持有,把资金集中到具备最优秀商业模式和最宽阔护城河的公司投资上面。

能理解一家公司,需要考察方方面面,但是要排除一家公司,只要挑一个刺就可以了。特别是商业模式,能找到优秀的并且自己能理解和认可的,实在是凤毛麟角。对于那些有着明显缺陷的生意,我就是压根不想参与。

再次,市场有时会疯狂,而市场的疯狂会被写进大盘指数里。

标普 500 是市值加权指数。如果一家公司因为短期狂热而被炒高,指数基金会激进地买入,而反之则会减少持有比例,甚至,这和 “卖在人声鼎沸时,买在无人问津处” 这样的逻辑恰恰是相反的。

我认为标普 500 就代表了一种大众群体的共识,而这种共识就一定会包含群体的狂热。如果想远离它,就要远离标普指数。勒庞写过一本讲大众心理学和社会学的书,叫做《乌合之众》,里面有一句话说得好:“群体只会干两种事——锦上添花或落井下石”。

最后,个股投资可以让我接近投资的本质:找到一个好生意,在一个好价格买入它,做时间的朋友,去兑现复利的价值。

我认为一家公司的基本面当中,最重要的就是生意模式,它也是 “好生意” 最重要的部分。坚持投资个股,就迫使我去研究一家公司的生意,这件其实是一件很有意思的事情。买标普 500,我十之八九不会有这个动力去做这件事情。

投资当中,带来回报有很多种方式,但是最让我开心的一种方式,是在和市场有分歧的时候买入,静待春暖花开,市场逐渐认可自己的观点。这件事并不容易,但是它却能带来无比的快乐。

求学,是十几年的事;工作,是半辈子的事;投资,是一生的事。

而你的投资回报,是你认知的变现。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

Run:ai 学习记录

2026-08-07 06:10:11

工作上的原因,最近学习了一下 Run:ai,也考察了一下它的替代技术。在这里记录一下。

Run:ai 功能特性

Nvidia 当年收购 Run:ai,还是很有前瞻性的。并且它并没有阻拦开源版本的继续演进,只不过,商业分支提供了更强大的能力。

Run:ai 是一个企业级的 AI 基础设施编排和管理平台,核心能力就是最大化 GPU 的资源利用和调度能力,在它的主页上,列出了四大特性:

  • AI-Native Workload Orchestration
  • Dynamic GPU Allocation
  • Policy-Driven Governance
  • Open Architecture

抛开那些商业宣传和拥抱开源等等方面,我们只讨论技术层面,我觉得拥有核心竞争力的 feature 主要是:

  • Dynamic Quotas and Pooling,因为原生 Kubernetes 的资源分配是静态的,有一个简单的排队机制。但是 Run:ai 的 scheduling 支持一个复杂得多的规则系统,比如可以保证每一个 team 或者 project 的基础配合,但是也可以超额借用,而对于资源竞争的情况,还允许定义 preemption 的方式,把低优先级的任务踢掉。
  • Factional GPU and Hard Isolation,单个 GPU 可以被切分成多个虚拟的 GPU,这个非常实用;而底层硬隔离是商业版本的卖点——Kai Scheduler 是 Run:ai 调度逻辑的开源版本,但是它只能做到 Kubernetes 层面上资源的软隔离,而 Run:ai 深入到底层 virtualization,能够做到物理级别的 CUDA 调用拦截,无论是 GPU 还是 memory,都可以设置硬 quota。
  • Advanced AI Scheduling,比如它支持需要多个 Pods 的任务,同时获得多个 Pod,或者等待,避免获取部分 Pods 是饿死情况出现;它支持 Bin Packing 的装箱算法和碎片整理,把碎片化的 GPU 能力拼合成一个大的;还有 Topology Awareness,把频繁通信的分布式训练任务放到物理距离更近的 GPU 上,这也是和硬件层面更紧密的结合。

Run:ai 的架构

Run:ai 的官方文档上这张组件图是最好的 overview 的材料:

从远处看,Run:ai 分成 control plane 和 cluster 这样两个部分,一般说来,一个 control plane,一个或多个 cluster。这让我想起了前段时间学习过的 Flyte 的架构,类似的部署方式。值得一提的是,出于安全等原因的考虑,没有从 control plane 主动去连接和发送请求到 cluster 的情况,只有从 cluster 发起去读取 control plane 的情况。

  • Control Plane 是指挥和回应用户的,提供包括 resource management,用户侧 RBAC,处理工作提交和监控分析 cluster 的功能;
  • Cluster 是真正做事的,负责 scheduling 和 cluster 内 workload 的管理。

除了官方文档,DeepWiki 上面也有很有用的材料可以学习,比如下面这张组件图:

在 Control Plane,scheduling 等 metadata 是存放在 PostgreSQL 里面的;而每个 cluster 则是扩展 Kubernetes,数据存放在 Etcd。

部署方式上,其中的 Control Plane 可以部署在用户自己这里,甚至包括 docker registry(Air-Gapped 模式),也可以使用 Nvidia 提供的远程服务(SaaS 模式)。很多公司出于安全考虑都是使用本地部署的。

接着,从和 Kubernetes 结合的机制上去理解 Run:ai:

  • 当有一个 job 部署到已经集成 Run:ai 的 Kubernetes cluster 上的时候,Mutating Admission Webhook 会介入,部署好的 MutatingWebhookConfiguration 会被触发,强制改写资源的 schedulerName 为 runai-scheduler,从而把它从 Kubernetes 的默认调度器接管过来。
  • 如果是 factional GPU 的任务,Webhook 还会往容器配置中挂载特定的系统目录,并注入环境变量,让容器启动的时候,把 Run:ai 的 CUDA 拦截动态链接库塞进 Python 环境中。

在运行的时候,我们能够从 job 资源的 labels 和 annotations 上面看到被 Run:ai 劫持后的标记。

KAI Scheduler

Run:ai 是收费的,KAI Scheduler 是一定程度上 Run:ai 调度模块的平替,它是 Kubernetes 原生的调度器。功能实现的层面不太一样,总体来说 Run:ai 要更强大一些。

  • 对于 Dynamic Quotas and Pooling 部分,Run:ai 支持多集群的算力池化控制和调度,但是 KAI Scheduler 自身只支持单一集群内部。
  • 对于 Factional GPU and Hard Isolation 部分,GPU 切分没问题,但是 Hard Isolation 只有 Run:ai 支持。KAI 只能在 Kubernetes 层面做逻辑控制,尤其对于 multi-tenancy 的情况,如果某个容器超额占用,会影响到同一张显卡上的其它 tenant。
  • 对于 Advanced AI Scheduling 部分,Run:ai 的功能覆盖面更广,比如任务的全生命周期覆盖等等。

说说其中最核心的软隔离和硬隔离的问题。如果使用 KAI Scheduler,如果说用户提交一个 PyTorch 任务,上面申请了一定量的显存,但是如果 PyTorch 任务的实际代码中,用户申请更大的显存,KAI Scheduler 根本不会去阻止。这就会引发 Noisy Neighbor 的问题。这个问题不只是显存层面,在 GPU 层面也有,KAI Scheduler 的调度逻辑能把任务安排到相应的显卡上,但是没法强制设置某一张显卡部分使用时的百分比上限。

对此,如果要寻找解决方法:

  • 如果是新的企业级 GPU 显卡,可以使用 Nvidia 的 MIG(Multi-Instance GPU)显卡硬件支持的技术,一张显卡可以切割成最多 7 张小显卡(并非任意分隔单元)。
  • 或者使用 Nvidia 的 MPS(Multi-Process Service)模式,这是把时间切片改成基于 CUDA 进程的资源切片。
  • 或者配合 HAMi-core,它可以做到显存的指定容量分割,不过它不管 GPU。
  • 再有就是纯软件工程上来缓解这个问题,使用一个 Kubernetes Mutating Webhook,给用户的容器外面包一层(比如可以做 Python 运行库或者 C/C++动态链接库级别的拦截),来控制资源获取操作。这种方法存在被恶意绕过的可能。

总之,没有完美的办法,大概这也是 Nvidia 把 Run:ai 的商用 licence 卖那么贵的原因吧。

此外,除了上面这个软隔离和硬隔离的问题,还有一些其它的差异,比如:

  • 没有原生的 multi-cluster 的 scheduling 和 governance,
  • 也没有 Run:ai 的 memory swap 技术可以让数据根据把 inactive 的数据从 GPU memory 中交换到 host memory,从而减少资源占用。

在 KAI Scheduler 的 GitHub 页面上,有一个很有帮助的 presentation 列表和一个 key features 列表。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

笔记:在 Mac Mini 本地跑 LLM 大模型

2026-06-01 12:03:31

这些笔记是在自己的 Mac Mini 上面折腾了一些记录,主要是安装一些重要的大模型工具,把这些工具连接起来,建立自己的私有本地知识库等等,以备查阅。后续不定时更新。

安装 OrbStack

OrbStack 是专门为 MacOS 设计的快速、轻量级的虚拟化工具,可以作为本地 Docker、K8s 和 Linux VM 的超容易替代品。因为它丢掉了跨平台的包袱,直接在系统内核级别支持虚拟机指令,动态分配内存等等做法,让它变得超快。就以 Docker 为例,它可以把冷启动速度从几十秒优化到一两秒。

我是在 Apple M4 芯片的 Mac mini 上面折腾的,首先要保证我的应用全部都是 M4 芯片直接支持的,而不是通过 Rosetta 2 兼容性转换过来的。在检查 Homebrew 的时候,发现 brew 命令的路径在/usr/local/bin/brew,这就是说 brew 在 Intel CPU 的模拟路径上,因此重新安装了 Homebrew,修改 PATH 以后检测发现 brew 已经在 ARM 的原生路径上了:/opt/homebrew/bin/brew。

这再安装 OrbStack 就行了:

brew install --cask orbstack

使用 orb 命令启动的时候,OrbStack 列出了三大核心功能:Docker、K8s 和 Linux VM,基本上足以完成我日常折腾的最核心需要了。

安装以后,docker 的命令就完全支持了,启动一下看看:

docker run -p 80:80 docker/getting-started

安装 Cursor

我在公司里代码编辑器使用的是 Intellij 和 Windsurf,后者是真正的 AI 原生 IDE。不过现在打算安装 Cursor,作为 Windsurf 的竞品,它有更优秀的综合体验。

安装 Miniforge

首先要安装 Conda,有很多其他的库管理系统,但因为 Conda 是一个更通用的环境管家,不仅限于 Python,包括 Python 库底层的 C++一并搞定。

Miniforge 把 Conda 工具包装了一下,并且针对 Mac 定制化了一下。Conda 的定制化有很多,Miniforge 是其中之一,开源免费,支持原生 ARM。

安装 Ollama

Ollama 是一个可以在本地电脑上运行 LLM 的工具。然后可以跑 Llama 模型了:

ollama run llama3.2

用 Cursor 写一段小程序来调用它:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class LocalLLMClient {

    public static void main(String[] args) {
        String endpoint = "http://localhost:11434/api/generate";

        String jsonPayload = "{"
            + "\"model\": \"llama3.2\","
            + "\"prompt\": \"Who are you?\","
            + "\"stream\": false"
            + "}";

        HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(10))
                .build();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(endpoint))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
                .build();

        try {
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            System.out.println("HTTP status code: " + response.statusCode());
            System.out.println(response.body());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行它,可以得到:

HTTP status code: 200
{"model":"llama3.2","created_at":"2026-03-29T23:54:11.011864Z","response":"I'm an artificial intelligence model known as Llama. Llama stands for \"Large Language Model Meta AI.\"","done":true,"done_reason":"stop","context":[128006,9125,128007,271,38766,1303,33025,2696,25,6790,220,2366,18,271,128009,128006,882,128007,271,15546,527,499,30,128009,128006,78191,128007,271,40,2846,459,21075,11478,1646,3967,439,445,81101,13,445,81101,13656,369,330,35353,11688,5008,16197,15592,1210],"total_duration":868990167,"load_duration":99794167,"prompt_eval_count":29,"prompt_eval_duration":263381208,"eval_count":23,"eval_duration":497184294}

Ollama 这个工具是最核心的部分,其他很多工具都需要连接在 Ollama 上面跑的大模型来完成。

安装 LM Studio

LM Studio 基本上就是本地的大模型图形化工具,和 Ollama 在功能上是有重叠的。一般说来,Ollama 可以用作后台程序运行和工程化调用,但是 LM Studio 适合选型和调试。

模型文件都比较大,已经使用 Ollama 下载了的,就不需要 LM Studio 再下载一遍了。模型都被下载到了~/.ollama/models/blobs/sha256-xxx,根据文件大小可以找到那个实际的模型文件。

然后创建 gguf 的软链接,比如:ln -s ~/.ollama/models/blobs/sha256-3e4cb14174460404e7a233e531675303b2fbf7749c02f91864fe311ab6344e4f ~/AI/models/LM_Models/Ollama/qwen3-4b/model.gguf,这样在加载以后,这个文件就能够被识别了:

安装 Claude

我们可以配置 /Users/ray/Library/Application Support/Claude 来允许 Ollama 来访问 Claude 的 MCP 接口:

{
  "preferences": {
    "coworkWebSearchEnabled": true,
    "coworkScheduledTasksEnabled": false,
    "ccdScheduledTasksEnabled": false
  },
  "mcpServers": {
    "local_ollama": {
      "command": "/usr/local/bin/npx",
      "args": [
        "-y",
        "ollama-mcp-server",
        "http://localhost:11434"
      ]
    }
  }
}

再去问 Claude 的时候,它就能访问 Ollama 并得到安装的模型了:

它的这个操作,其实是和本地运行 curl http://localhost:11434/api/tags 或者 ollama list 是一样的。

为了能更方便地使用,最好打开语音操作支持。在 Mac 的设置里面,找到 keyboard,语言列表里面需要把中文英文都勾上:

并且还可以设置为双击 Command 按键就可以调出语音输入。

在 general 的语言和地区设置里面,加上中文:

再配置好 Gmail 的 connector,就可以让 Claude 做一些更有意义的工作了。比如,我让它分析最近看的房子,生成一份详细的报告发到家人的邮箱里。

安装 AnythingLLM

下载安装 AnythingLLM,下面使用它来选择本地模型,选择远程网站或者本地文件,并进行本地 RAG(检索增强生成,Retrieval-Augmented Generation),生成属于自己的私有/本地知识库。

设置里面,先选择推理模型(LLM Preference):

再选择嵌入模型(Embedding Preference):

最后选择向量数据库 (Vector Database),保持默认。

使用 Bulk Link Scraper 这个 Data Connector 可以去扒拉网站上的内容:

运行 tail -f ~/Library/Application\ Support/anythingllm-desktop/storage/logs/collector*.log 可以看到抓取的详细信息。

抓取完成后,回到 Documents 页就可以把抓到的内容加到 Workspace 里面去:Move to Workspace -> Save and Embed。

除了抓取网页,也可以上传一些本地的文件给它。

不过,文件较多的时候,它的可用性就比较差了。我们需要一些其他的工具。

搭建 Dify 环境

为了解决前述问题,下面搭建搭建 Dify + 本地 Ollama 的组合。Dify 是一个 “Agentic Workflow Builder”,它底层集成了非结构化数据解析引擎,可以把各种格式的文件转成文本。

首先修改 Ollama 的环境变量,使其监听所有网卡:

launchctl setenv OLLAMA_HOST "0.0.0.0"

这一步需要重启 Ollama。

现在本地有的 qwen3 和 llama3 都是 chat 模型,还需要专属的 Embedding 向量模型:

ollama pull nomic-embed-text

Dify 官方提供了完整的 Docker 编排文件,包含前端、后端、PostgreSQL 数据库、Redis 缓存以及向量索引组件。

git clone https://github.com/langgenius/dify.git
cd dify/docker
cp .env.example .env

再把上面.env 文件的 EXPOSE_NGINX_PORT 这一项端口从 80 改成 8080,以避免冲突。

还需要加上这样的配置以放宽文件上传限制:

UPLOAD_FILE_SIZE_LIMIT=10000
UPLOAD_FILE_BATCH_LIMIT=20000

环境配置文件准备好以后,就可以启动所有容器组件了。

docker compose up -d

于是乎,pull 了一大堆 image:

启动了一堆 container。以后要启动和停止,以及看日志,使用:

docker compose down
docker compose up -d
docker compose logs -f

访问 http://localhost:8080/ 并创建用户。

接着 Settings 里面添加 Ollama 的 plugin,

先配置 LLM 的 llama3 模型,再配置 Text Embedded 的 nomic-embed-text 模型。这其中的 Base URL 不能用 localhost,而是要使用 host.docker.internal,因为 Dify 在 Docker 内部运行。

之后,就选中一个知识库,然后分批追加文件。因为软件一次性没法导入一个太大的文件夹,否则页面会卡死,所以这一点需要注意。

之后,还可以把网站等其它形式的数据导进来,这样自己的知识库就会更加全面。如果是爬网站的话,可以去 Firecrawl 注册一个账号,得到一个 API Key(免费版好像是最多只有 2 active browsers 一起工作,单月 1000 个 credit,不过对我来说也够了),填到 Dify 的 Firecrawl 插件配置中:

然后就可以去爬网站了。

最后,在 Studio 菜单里创建一个 Chatbot 或 Agent,在右侧的 “上下文” 中关联这个知识库。

这样,后续问它任何问题,都可以从这个具备个人信息的知识库中进行检索。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

笔记:把新域名应用到 Blog 和 Email 上

2026-05-25 08:04:10

raychase.net 这个域名是好些年前申请的,最近申请了个更适合作为我个人标签的 rayxiong.me,简单记录下我把新域名应用到 blog(新、老域名都可以访问 blog),以及创建并使用新域名的邮件地址收发邮件的操作。

Blog 配置

在 Squarespace 上面配置好 DNS 的两个 A 记录:

其中 @表示不带任何前缀,它和 www 前缀这样被视为两条独立的记录。没法再简单了,不过需要等几个钟头生效。

在网站的 Nginx 配置文件上面添加:

server_name www.rayxiong.me rayxiong.me;

以及:

    if ($host = rayxiong.me) {
        return 301 https://$host$request_uri;
    }
    if ($host = www.rayxiong.me) {
        return 301 https://$host$request_uri;
    }

做完之后检查一下有没有语法错误:

/usr/local/nginx/sbin/nginx -t

我已经忘记之前证书怎么处理的了,重新安装 acme.sh:

curl https://get.acme.sh | sh -s [email protected]

使用 acme.sh 来申请多域名证书:

~/.acme.sh/acme.sh --issue --nginx -d raychase.net -d www.raychase.net -d rayxiong.me -d www.rayxiong.me -w /home/www.raychase.net

如果不想牵扯 Nginx 的瓜葛,因为已经指定了网站根目录,也可以使用 letsencrypt 的 server 来完成:

~/.acme.sh/acme.sh --issue \
-d raychase.net -d www.raychase.net \
-d rayxiong.me -d www.rayxiong.me \
-w /home/www.raychase.net \
--server letsencrypt --force

再把证书部署一下:

~/.acme.sh/acme.sh --install-cert -d raychase.net -d rayxiong.me\
--key-file /etc/letsencrypt/live/www.raychase.net/privkey.pem \
--fullchain-file /etc/letsencrypt/live/www.raychase.net/fullchain.pem \
--reloadcmd "/usr/local/nginx/sbin/nginx -s reload"

完工。访问网站看看证书的情况,再检查一下定时任务是不是已经顺利加上了:

crontab -l

Blog 的文章里面,不能有写死域名的链接,全部要使用相对路径。接着就是给 wp-config.php 添加动态设置 Home 和 SiteURL,否则首页到不同栏目的链接都还是老地址:

if (isset($_SERVER['HTTP_HOST'])) {
define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST']);
}

设置了之后,WordPress 的管理台的 General Settings 里面,这两个变量会置灰:

此外,考虑到两个域名包含相同的内容,需要告诉搜索引擎谁才是 canonical 的版本,否则搜索引擎可能会做出负面的判定。在 WordPress 菜单的 Apperance->Theme File Editor->Theme Functions (functions.php) 的尾部,写上:

remove_action( 'wp_head', 'rel_canonical' );

add_action( 'wp_head', function() {
echo '<link rel="canonical" href="https://www.raychase.net' . esc_url( $_SERVER['REQUEST_URI'] ) . '" />' . "\n";
});

Email 配置

有了新的域名,打算搞一个个人标识鲜明的邮件地址 [email protected]。但是我打算只是创建一个邮件地址,邮箱服务依然使用 Gmail。

先配置收信,收信比较简单,保证 email 转发到原有邮件地址:

得花些时间生效,测试一下,发送到这个新邮件地址一旦成功,那收信路径就通了。

接着是发送。这需要 Resend 这样的工具。

建立一个 rayxiong.me 的 domain,然后添加如下的 DNS 记录:

  1. DKIM:Domain Keys Identified Mail,用以防止 email 冒用和伪造,有了这个发送的邮件就不会被直接标记为垃圾邮件。
  2. SPF:Sender Policy Framework,两条记录,一条是 TXT 记录,它来申明 email 从 Amazon SES 走的渠道是合法认证的;还有一条是 MX 记录,用来接受回执,以得知邮件是否发送成功。

把这些 records 拷贝到 Squarespace 的 DNS 设置里面,然后再回到 Resend 上面来验证,确保验证通过。

如果失败了,可以去 Logs 页面看错误信息。

现在,去 Sender 的 API keys 里面,给配一个 Gmail-SMTP 的 API Key:

接着就可以给 Google 邮箱配置这个新的 email 地址了:

SMTP 服务器是 smtp.resend.com,这里需要使用到前面配置的 API key:

手机上面配置起来有点麻烦,需要创建一个新账户。

收邮件的部分,host name 写 imap.gmail.com,用户名写原本的 gmail 邮箱名,密码的话需要去 Google 的 App passwords 创建一个只能查看一次的密码,填在这里。

发邮件的部分,配置 SMTP 为 smtp.resend.com,用户名是 resend,密码就是前面的 API key。

configuration

此外,Resend 的 DNS records 目前只配置了 sending,并没有 receiving。因为现在邮件的 receiving 是通过 Squarespace 的 Mailgun forwarding 来实现的,如果要配置 Resend 的 receiving,那是用于把邮件内容转成 JSON 数据并根据配置的 Webhook 来调用 API 只用了,目前不需要。

除了 blog 和 email,对于这样一个个人标签浓厚的域名,不知道还有哪些有趣的事情可以做。我想到的几个包括:

  • 我已经在我的 Apple mini M4 上面部署了本地运行的大模型,也许可以把界面部署到 chat.rayxiong.me 这样的地址上来;
  • 把一些个人标签浓厚的资源,比如简历、课程之类的放到一个 rayxiong.me 的直接子域名上;
  • 还有就是加上自己的一些文档、材料管理,甚至家里面的各种智能控制系统查看等等,这样访问也比较方便。

只是我的一些想法,不知道还有什么有意思的主意。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

写在暗黑 2 术士资料片发售一个多月之际

2026-03-23 07:38:30

作为一个老暗黑粉,二十年前,写过一点关于它的碎文。那时候我还在读书,《暗黑破坏神 2》应该是对我影响最大的一款游戏。还记得第一次接触到暗黑的那天——在家乡暑假的某个阴沉的下午,窗外雨绵绵,一进入游戏,第一幕的罗格营地,就被呼应的下雨细节打动,音乐、雨滴声,还有可以追随地散布的鸡,一切都让我觉得有巨大的沉浸感。于是我一遍又一遍地杀到城外去,杀到地下洞穴去。暗黑游戏的视觉效果我相信不是最好的,但是游戏性和耐玩度却是顶级的。在这以后,也玩过不少类暗黑的游戏,比如《流放之路》(那时候还写过一点关于它游戏中通货膨胀的思考),再没有一款能给我带来那样的体验。

后来我慢慢知道,原来有这样感受的不止我一人。《暗黑破坏神 2》是整个电子游戏历史上具里程碑意义的作品,它几乎凭借一己之力奠定了整个 ARPG 的游戏框架和标准,如今的 ARPG 砍杀的游戏方式,就是从它开始的。暗黑 2 的装备系统、技能树,还有怪物系统等等,在当时都是首创,并且都引领了后来的游戏发展方向。比方说,从暗黑 2 开始,装备的颜色分级制和词缀系统开始流行开来,也是从暗黑 2 开始,一类被称为 “刷子游戏” 的游戏类型,也开始被玩家逐渐认识;再比方说,技能树和后来资料片引入的技能加成系统,也逐渐演化出了游戏角色流派构建的理论。

暴雪的暗黑 3、暗黑 4,尤其是暗黑手游版,口碑时好时坏,但拿暗黑 2 的标准来比,可真是不怎么样。其实,对于一款过于成功的游戏,推出续作总是充满挑战,甚至可以说凶多吉少。不过,暗黑 2 之后的续作充满故事的张力——暗黑 3 一开始是糟糕的,尤其是那个著名的拍卖行,彻底让游戏失去了原有的平衡,之后《夺魂之镰》的资料片,挽回了一定的名声。再是暗黑 4,一开始黑暗压抑的美术风格获得了好评,但在游戏性,尤其是可重复玩性上大不如前几作,后来才在装备系统的改革等变更中逐步挽回名声。但无论如何,我觉得和暗黑 2 的那种哥特式氛围,装备驱动的打怪逻辑,还有高自由度的角色培养系统这些方面比起来,如若拿巅峰之作和优秀作品类比一样,这两者完全不可同日而语。

说起来,2021 年,暗黑 2 曾出了高清重制版,让那些二十年前的充满情怀的老玩家,得已不借助非官方的高清分辨率补丁,在如今的高配置机器上重温暗黑 2。回想起来,其实这样炒冷饭的做法也不算特别,印象中不少以前一样感动一票玩家的游戏,比如《最终幻想》系列的好几款游戏,都出过重制版。不过,在暗黑 2 发售的将近 25 年后,居然再推出一个完整的新角色 “术士”——《术士君临》资料片,却是真正让所有人都大吃一惊。

从商业上看,这次试一次非常精明的商业决策,整个过程保密性做得非常好,间隔超过 25 年的产品营销,这冷饭炒得也可以说登峰造极了。同时,也算对玩家社区给足情面了,之前暴雪被微软收购,微软是下了一步绝好的棋,但是玩家群体之间的口碑需要建立起来,这次看起来是一次非常成功的操作。无论如何,从数据上看,日活玩家增长超过了 50%,这是一个非常正面的信号,这些玩家的粘性可比一般游戏高得多。别忘了,这个资料片只是增加了一个角色,它并没有增加任何主线故事情节上的内容,它卖得并不能算便宜。

现在,我好奇的是暴雪下一步会如何打算。如果往回倒退几年,你问暗黑 2 还会出资料片吗,那一定会被喷痴人说梦。但是现在随着术士资料片的上线,我觉得暗黑 2 再续写下去,看起来完全合理。如果我们再回想到 25 年前,很明显暗黑 2 的第四幕是明显缩短的,有一种讲故事草草收尾的感觉,而且分辨率那时候也只有 640×480,于是一年之后的 2001 年,暗黑 2 资料片《毁灭之王》就以一个内容足量的第五幕弥补了玩家的遗憾,并且带来了更高分辨率、引入技能加成、引入符文和宝石系统等等巨量变更。可是想一想,一款成功到载入史册的游戏,从游戏内容上看,有什么理由会只出这么两部资料片,尤其是只有第一部是有 “主线剧情” 的,无论是从商业上考量还是情怀上考量,完全可以制作第六幕啊。

如果是一个新玩家接触暗黑 2,他的视角会是怎样的?我觉得暗黑 2 的视觉效果肯定不算好,虽说重制版让它和当年相比有了改进——可是话说回来,暗黑 2 从来都不是一个以画面取胜的游戏,它的可重复玩的游戏性无可匹敌,它的社区有一群坚持原教旨主义的硬核支持者,它在这个游戏史上写下了独一无二、浓墨重彩的一笔,而我觉得,二十五年过去了,这一笔却还远没有写完。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

AI 到底会怎样取代我们的工作

2026-02-16 13:09:33

这是一个很多人都讨论的大问题。

我一直在思考,也一直没有一个足够确信的答案。去年这个时候,写了一点体会,如今的体会更深了。但是我觉得,我可以把凌乱的内容整理出来。

一些事件

在一两周前,Google Genie 3 出来的时候,因为 demo 展示了它可以很容易地生成一整个可以游玩的世界,游戏引擎 Unity 的投资者就被吓坏了,疯狂抛售,一天就跌了二、三成。Unity 的 CEO 站出来喊话,核心观点还是——AI 再强大它也是概率性的,而 Unity 程序员的工作,却是追求确定性的。因此 AI 应该是软件开发的加速器,帮助提升创作的真实性和速度,而非替代者。

朋友推荐我这篇 《The Eternal Return of Abstraction: Why Programming Was Never About Code》,这篇读起来有些费劲,不过它的核心思想大概是,编程一直以来的本质是什么?它的本质是把人的意图转化为机器可以理解的形式。它的意义比代码高多了,因为代码只不过是表达这个意图的一种形式而已,还有什么形式?有了 AI,自然语言就可以是这个新的形式。大语言模型的一个功绩在于提升了抽象级别,以前我们必须要准确地使用编程语法来告诉机器应该怎么做,现在不是了,自然语言就是基于概率的描述,这个不确定性的问题是从根上就有的。

今年初的 SaaS 软件板块抛售潮,伴随着一系列事件,被称为 SaaSpocalypse,所谓的 SaaS 末日。它缘起于市场突然意识到 AI 不再仅仅是程序员的工具,而是可能称为自主运行整个 SaaS 程序编写,并完成复杂流程的 “数字员工”。这其中包括 Anthropic 发布的 Claude Cowork,它可以直接操作软件界面,这被认为很多 SaaS 的按人头付费的模式崩塌;Klarna 公开宣布,决定停止使用 Salesforce 和 Workday 这样的 SaaS 服务,因为他们启用了 AI,这让市场怀疑起 SaaS 的护城河硬度;再有早些时候的 Chegg,使用率锐减,主要是 AI 都可以直接、免费地获取答案了,学生们不再需要它了;还有 Adobe 因为 Sora 的发布而受到质疑,虽然专业用户的门槛不好说,但是大众用户的视频和图像生成似乎已经可以通过说几句话就完成了。

如果看看 SaaS 公司的财报,似乎是另一番光景。比如 ServiceNow,Q4 的营收增长超过了 20%。似乎,能看得到的事情是,面对科技行业的大幅裁员,更少的程序员可以做更多的事情,这也是市场担心的一个主要由来。那么反过来想,如果是按照按人头卖的形式,显然 SaaS 的收入会大幅下降。不过,如果定价按照解决的问题、feature 使用的次数和使用 AI 能力的 token 来收钱,这也许就完全不是那么回事了。我们目前能看到一些收费方式的变化(也看到了一些抵触,比如很多企业不喜欢这样的新方式,因为缺乏财务上的可预测性),但是市场需要看到更多。

对 SaaS 行业的影响

好,现在冷静下来想想,到底哪些 SaaS 商业模式会出局?

首先想到的,知识库似乎会出局,因为 AI 可以非常方便地给出结论;其次,是文字组织和润色类工具,因为 AI 的文字能力比一般人都出色;再次,就是一些数据、声音、视频分析类的工具,这种把数据可视化,让人更容易从中找规律的软件,AI 也基本可以比较容易地代替。如果尝试泛化一些,似乎容易出局的软件模式是:需要的答案已经有了,只是要把它们从大量的内容中找出来,这种为了寻找答案而使用的专业工具,可能会被 AI 这种能够接受人类语言的特性所替代。换言之,如果提供的服务,没有硬核的、实质上的不可替代性,只有 “便捷性”,那就可能被踢出局。

那么,哪些 SaaS 商业模式很难被踢出局?

第一种,大概是拥有不可替代的数据。这样的 SaaS 软件拥有私有的、历史的和被视作宝贵资源的数据,而不是公开的、简单的和比较容易获得的数据。前面说的 Chegg 拥有的其实就是公开的数据,比如所谓的习题,还有像是 LeetCode 题解这样的也差不多;而 ServiceNow、Salesforce,以及 Atlassian 等等,这些企业专有的数据,让你没有办法直接使用一个公有的 AI 服务来直接替代掉。

第二种,就是高度复杂化和专业性的,AI 可以充当一个外行,但是没有办法触及最核心的精确性的。这包括某些媒体内容的制作,AI 可以提供丰富的素材,动画的画师可以使用 AI,但是主干必须要手动主导和干预,AI 可能能够生成关键帧之间的连接。

第三种,大概就是脱离软件的虚拟世界,和真实世界有着紧密的连接。比方说,对于很多 IoT 应用,通过各种各样的特定传感器来获知状态并连接。这些硬件的 “眼睛”、“耳朵” 和 “嘴” 需要特定的驱动程序,或是说,特定的软件才能工作。

还有一些 SaaS 应用,居于二者之间——可能能够暂时活一段时间,但是长远看,护城河也会被侵蚀。

第一种,复杂流程已经根植入企业人事流程的。这种只是代价高,但并非有那么强的不可替代性。

第二种,已经发展出专业技能的。有些学校里面都会教。比如 Unity 的技能和 Adobe 的技能等等。

第三种,那就是生态。比如 Jira 就有插件生态等等,生态意味着有很多为了方便提供某些特性而做出的定制化。

对软件工程师的影响

在说软件工程师之前,先跳出来想一下,哪些行业更容易被 AI 革命?

初级(简单劳动)的白领,是最容易被革命的。“简单劳动” 很容易理解,但是 “白领” 被淘汰是 AI 时代的特殊之处。如果说工业革命初期受到最大影响的是 “蓝领”,那 AI 革命初期受到最大影响的就是 “白领” 了。这一类初级白领,就是看似坐在电脑前工作,但是工作却是一些复制粘贴、流程安排和文字组织等等简单的活动,比方说翻译、秘书等等。

相应地,我记得李开复的《AI·未来》书上也讲到的,需要和真实世界的人交互的行业,影响可能是最小的。比如养老护理,体育竞技等等。还有一些行业,是蓝领,但是目前的 AI 和硬件设备的结合还要慢一步,比如汽车修理等等——AI 又没有手,因此这样的行业暂时也算安全,只不过随着机器人等强烈依赖硬件行业跟上来,这些也依然有被淘汰的风险。

好,接着再来看软件工程师。软件工程师,算是白领,但是算是 “初级” 白领吗?

其实,大家似乎比较容易能够达成共识的是,单纯编码,就是一个很容易就被 AI 淘汰的工种了。想起来其实也很容易理解,编码,说到底和英语或者任何其他人类语言的 “翻译” 到底有多大区别?可能区别也不过是,交流的对象从活生生的人变成了冷冰冰的机器,还是需要语义、语法,还是需要语言逻辑。如果从这样的角度来看,似乎 “编码员”(coder)可替代性真的太高了。

再深入一步,是用的更为广泛的 “程序员”(programmer)。这意味着,再代码的基础上,程序员设计逻辑、算法,从而把一个具体问题实现为程序代码。程序员也会关心程序员生命周期的其他活动,比如 bug 修改、feature 添加等等,但是核心依然是代码。程序员似乎比编码员好一点,但是 AI 的可替代性依然很高。

再来,就是软件工程师。我认为软件工程师是一群能够利用一定系统和规范的方法,来把软件工程化的专业人员。这就意味着他们解决的问题是实际世界的问题,需要把问题抽象成为软件可解的问题,以工程的方式实现,并且维护整个软件生命周期。

渐渐地,整个行业会有更加成熟的方法来知道 AI 实现需求,但是软件工程师依然会需要 “亲自阅卷”,他们也许会大大减少亲自实现的代码量,但会花更多时间评审 AI 的代码实现,寻找其中的问题,评估其中的风险等等。在整个软件工程流程上,也需要分析和思考用户的需求,敲定大体的方案,把大块复杂的任务拆分成小块的任务,交给 AI 来实现等等。总而言之,AI 成为了助手,或者是团队中的 “初级程序员”。传统观念上软件工程师的核心能力有了些许区别,比如说,如何提问 AI 的表述能力会被放到更加重要的位置。

这么看来,“初级软件工程师” 似乎非常容易被替代。比如说,初级软件工程师,经常会拿到设计方案,然后去实现。这在如今的互联网大厂是常态,大的 feature 或者系统,不太会完全丢给一个没什么经验的新兵来实现,这样的角色确实是比较容易被 AI 替代的。可是,成长是要有过程的,如果这个阶段不给足时间,那么初级软件工程师就不能成长为高级软件工程师,如果 AI 替代了这个阶段,势必会造成人才的断层。从长远来看,这才是让我最为忧心的。

如果我们仔细思考 AI 的擅长与不擅长,AI 目前还是有很大的局限性的。比方说,AI 还是更适合做具体的、明确的工作,对于一个复杂系统,对于用户的痛点感知,还是需要软件工程师开动大脑来分析思考,基本上这种活动都需要比较长的时间和比较丰富的积累。再有一个,AI 现在的两大问题,一个是 hallucination,就是 “一本正经说瞎话”;另一个是 sycophancy,就是在一些决策上面没有啥 backbone,很容易倒向谄媚的一侧。我可以想象,几年以后,AI 做更多的执行和辅助,然后把信息提炼、分析以后交给软件工程师,而软件工程师会做更多的思考和决策,并为结果负责。

我们还在这个时代变革的开头,这些观念只能说是目前的思考,两三年之后,它们还有效吗,我可以说完全没有什么信心。不过我确定的是,我们不能回避,要拥抱这个时代;既然选择了这一行,就要尽量保持开放,去倾听和接触新鲜事物,持续学习,那种抱着自认为 “经得起考验” 的过往成功的经验不放的自称 “老派” 的家伙,可能会吃大亏。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》