基于大模型的播客RAG系统搭建攻略(三):开源代码和后续计划

前文链接:

仓库地址https://github.com/liujinmarshall/podcast_rag

首先插播一条新闻。在两周之前,我常用的播客客户端小宇宙推出了会员plus计划:

我们的会员产品“小宇宙PLUS”现已上线,提供「AI播客总结」「收藏时点」「会员周报」「个性图标」「多彩主题色」等多个功能,一起来看看!

小宇宙PLUS会员,现已包含以下权益 ——

· AI播客总结
服务于播客重度用户的一些高信息密度节目场景。例如:你可以通过AI播客总结判断一期没有shownotes的节目是否值得听,也可以高效得到一期财经、商业、科技等领域节目的内容速报。更多使用场景,期待你的探索。

· 收藏时点
你可以通过「收藏时点」功能,随时标记最感兴趣的时点,记录此刻的私人笔记,并在【我的收藏】中查看汇总。即使正处于锁屏状态下也无需担心,iOS系统中,无需解锁也可以通过左下角的收藏按钮进行收藏时点的操作,一键收藏此刻的吉光片羽。

· 会员周报
每周一中午12:00左右,我们将为会员用户送上专属会员周报,并为你自动汇总并总结你可能错过的精彩节目,为你持续挖掘更多的兴趣内容。欢迎在【个人-会员入口】处进入查看。

· 个性图标与多彩主题色
看腻了你的小宇宙?成为小宇宙PLUS会员,即刻更换你的小宇宙图标和主题色,深空、毛绒、键帽、粉白、薄荷、深蓝……超多可选,让你的小宇宙与众不同。

当中第一项AI播客总结正好完美契合这个项目的功能,虽然我强烈怀疑这个会员是否真的值一年120元。因此我也在程序中加上了单集总结的功能。实现非常简单,通过发送提示词+播客转录稿实现。

计划中的功能列表:

  • 支持英文播客:加入英文提示词,并根据播客语言选择对应的提示词。
  • 切换embedding:现在使用的OpenAI text embedding的开销,对于个人用户来说不算很大,但也不小。需要切换到更便宜的版本或者本地推理的text embedding。目前计划使用MTEB榜单中排名较为靠前但显存需求不大的gte-Qwen2-1.5B-instruct
  • 一键运行所有任务:当前程序被分为不同的子程序,需要统一一个运行入口。
  • 新增播客总结:对于每次增量更新的内容进行小结。

以下是中文版的使用说明:

仓库地址https://github.com/liujinmarshall/podcast_rag

使用 RAG (检索增强生成) 技术来理解播客并提问

已测试 Python 版本:3.9 (应该也适用于更新的版本和不太旧的版本)

前提条件

  • Python 环境以及并了解如何运行 Python 程序
  • Google Gemini API 密钥和 OpenAI API 密钥

步骤

  1. 克隆此 Github 仓库;
  2. 创建一个名为 “data” 的目录;
  3. 将 podcasts.example.csv 复制到 data/podcasts.csv,并添加 RSS URL 条目;
  4. 通过 requirements.txt 安装 Python 依赖 (pip install -r requirments.txt);
  5. 将 Google Gemini API 密钥导出为 GEMINI_API_KEY,并将 OpenAI API 密钥导出为 OPENAI_API_KEY;
  6. 运行以下脚本以实现以下功能(使用 python xxx.py):
    1. download.py: 将播客音频媒体文件以增量模式下载到本地。每个播客一个目录。
    2. transcribe.py: 将音频媒体文件转录成文本。每个播客一个目录。
    3. index.py: 将转录文本分块并索引到向量数据库 (ChromaDB) 中。
    4. query.py: 启动一个聊天机器人来查询问题:
      • 运行程序;
        • 在浏览器中打开链接并开始提问 。
    5. summarize.py: 将转录文本总结成简洁的摘要。每个播客一个目录。
    6. delete_files.py: 删除音频媒体文件(超过 24 小时的文件),以防文件上传超出配额。上传超过 48 小时的文件将被自动清除

语言支持

  • 中文
  • 英语 (待添加)

注意

请遵守播客提供商的用户协议。此仓库仅供个人研究使用。

基于大模型的播客RAG系统搭建攻略(二):进阶之路与避坑指南

第一部分:https://onlymarshall.com/2025/01/05/build-personal-podcast-rag/

第三部分:https://onlymarshall.com/2025/01/26/build-personal-podcast-rag-part-3/

(注:本文在Gemini模型协助下完成。不得不感慨大模型很多时候思考的比人类周全,人类只要提供一些基本元素,大模型就可以把内容打磨地得非常完善)

上一篇我们介绍了播客搜索问答系统的基本架构和初步选型,特别是在语音转录方面的一些尝试和思考。今天我们继续深入,聊聊在系统搭建过程中遇到的更具体的技术挑战以及一些解决方案。

索引/检索的优化与挑战

上一篇我们提到索引和检索环节主要依赖文本向量模型和向量数据库。看似简单,但真正落地会遇到不少问题,尤其是在播客这种持续更新的内容源上。

增量更新:让知识库保持新鲜

播客的一大特点是持续更新。每周甚至每天都会有新的内容产生。如果每次更新都重新处理所有播客数据,那将是巨大的资源浪费。因此,增量更新是必须要考虑的。我们的目标是只处理新增的播客和更新的播客。这需要我们在“播客下载/爬虫”阶段做一些改进:

  • 记录已处理的播客和音频文件: 我们需要一个机制来记录哪些播客和对应的音频文件已经被处理过了。一个简单的做法是维护一个数据库(或者是简单的CSV文件),记录播客的feed URL以及每个episode的发布时间或唯一的GUID。
  • 对比更新时间或文件大小: 在爬取时,对于已经记录的播客,我们可以通过HEAD请求获取最新的episode信息,对比发布时间或GUID。对于新的episode,或者发布时间有更新的episode,再进行下载和后续处理。
  • 文件大小与HEAD请求的妙用: 除了对比发布时间,我们还可以利用HTTP HEAD请求来获取音频文件的大小。如果新爬取的音频文件大小与之前记录的不同,则说明文件可能被修改过,需要重新下载和处理。这对于一些播客会修改音频描述或者替换音频文件的情况很有用。HEAD请求相比于直接下载整个文件要高效得多,大大节省了网络资源。
  • 处理删除的播客: 有些播客可能会下架某集播客。我们需要定期检查已处理的播客列表,对比最新的feed内容,将已删除的播客集从向量数据库中移除,保持数据的一致性。
  • 保留时间:播客毕竟是音频文件,几百期的内容加起来也有几十个GB,如果总是保留所有的冷文件,特别是对于个人来说,存储的成本也没有必要。

有了以上这些功能,我们每天只要定时跑任务就可以自动完成对比、下载、转录、处理以及更新数据库的工作。

大模型转录的“后遗症”:重复文字问题

上一篇我们提到利用大模型的长上下文能力进行音频转录非常方便。但实际使用中,我们发现一个潜在的问题:重复文字和错误退出。

问题示例

尤其是在音频质量不高、语速较快或者多人对话的场景下,大模型有时会重复生成一些片段的文字。这可能是由于模型对音频的理解不够准确,或者在拼接长文本时出现偏差。

如何解决重复文字问题?

  • 检测错误并重新转录:这种情况有点像代码中因为并发造成的bug,而大模型运行本身也有一定的随机性,所以很大概率重新转录就可以解决这个问题。
  • 更精细的音频切分: 虽然我们避免了为了输入长度而进行的粗暴切分,但适当的、基于语义的切分仍然有必要。例如,可以根据静音段落或者明显的语意停顿进行切分,这样可以减少模型处理长音频的压力,降低重复的概率。
  • 后处理去重: 在得到转录文本后,可以进行一些后处理操作。例如,可以设定一个滑动窗口,如果窗口内的文本重复出现,则进行删除。当然,这需要谨慎操作,避免误删有效信息。
  • Prompt优化: 在给大模型下达转录指令时,可以加入一些提示,例如“请勿重复生成已出现过的文字”,虽然效果可能有限,但有时也能起到一定的作用。
  • 尝试不同的模型参数或模型: 不同的模型或者相同的模型在不同的参数设置下,表现可能会有差异。可以尝试调整解码策略或者使用更擅长处理此类问题的模型。

Text Embedding的中文选择:Gemini的踩坑

上一篇我们提到在文本向量模型上“跌了个跟头”。这里就来展开说说。

最初,我们可能自然而然地会选择一些通用的、在英文领域表现优秀的Embedding模型。既然Gemini也提供了文本Embedding,我们自然也选择这个模型。

但是在生成Embedding、存入数据库,再通过查询的Embedding进行检索之后,我发现了一个严重的问题:Gemini的文本模型似乎完全没办法理解中文

以下面的例子看,我们通过Gemini text-embedding-004模型,完全不同问题产生的embedding前10维完全一样。如果加上了一些英文字母的扰动,生成的结果就完全不一样。推测原因应该是tokenization的阶段把所有的非英文字符全部映射成了<UNK>,所以结果没有区别。

解决的方案也很简单:换成OpenAI的Embedding模型(text-embedding-3-small),因为使用了ChromaDB的代码,切换embedding function只要改动几行代码就可以实现。

后注:最终在某个文档页面发现了这个模型并不是多语言的版本,但似乎在GenAI embedContent的API里只能调用embedding-001和text-embedding-004,如果要调用多语言模型需要换到其他API。

Chunk大小的权衡

将长篇的转录文本切分成更小的chunk(块)是进行向量化的必要步骤。 Chunk的大小直接影响着检索的准确性和效率。

  • Chunk太小: 可能无法包含完整的语义信息,导致检索时丢失上下文,返回的结果不够相关。例如,一句关于“苹果公司新发布的手机”的信息被切分成“苹果公司”和“新发布的手机”两个chunk,单独检索“苹果公司”时,可能返回大量无关的结果。
  • Chunk太大: 虽然包含了更多的上下文,但会增加向量的计算成本和存储成本。同时,如果一个chunk内包含多个主题,可能会导致检索时返回与用户问题不太相关的部分。
  • Embedding模型限制:大部分embedding模型限制输入在几个K token左右,比如Gemini GenAI是输入上限2K,输出768维,OpenAI输入是8k,输出1536维

如何选择合适的Chunk大小?

这是一个需要根据实际播客内容和模型能力进行实验和调整的过程。一些可以参考的策略:

  • 基于句子或段落切分: 这是比较常用的方法,可以保证chunk的语义完整性。
  • 固定大小切分并加上重叠: 将文本按照固定token数量切分,并在相邻的chunk之间添加一定的重叠部分,以保留上下文信息。例如,一个chunk包含100个token,重叠20个token,那么下一个chunk从第81个token开始。
  • 利用语义切分工具: 一些工具可以根据语义相似性来切分文本,使得chunk内部的语义更加连贯。

在我们的实践中,我们尝试了不同的chunk大小,并结合向量检索的效果进行评估。 出于简单的考虑我们选择了固定大小切分并加上重叠。参数是2000个token一个chunk,重叠是200个token,通过tiktoken的包进行本地的计算(因为不知道embedding模型的tokenzier配置,所以这里只是近似)

小结

这篇博文我们深入探讨了播客RAG系统搭建过程中的一些关键技术点和挑战,包括增量更新、大模型转录的重复问题、中文Embedding模型的选择以及chunk大小的权衡。虽然已经有了大模型的加持可以很快编写核心骨架代码(大概降低了一半的时间),但是需求的不断迭代和看到结果后目标不停的调整,还是有相当大量的人为介入。编程门槛的降低,可以让非专业人士和专业人士摆脱一些低级的信息查找,把时间投入更有效率的地方。

后续我会整理一下代码之后发布开源(现在大部分都在notebook里)。

基于大模型的播客RAG系统搭建攻略(一):缘起,架构和选型

声明:本文仅介绍如何通过技术手段搭建系统,请遵守各个播客的用户协议。

第二部分:https://onlymarshall.com/2025/01/11/build-personal-podcast-rag-part-2/

第三部分:https://onlymarshall.com/2025/01/26/build-personal-podcast-rag-part-3/

缘起

开始听播客是在2016年初,那个时候刚拥有了人生第一辆车,也搬到了郊区自己的房子里,有比较固定的时间和空间。不知道是什么原因知道了在喜马拉雅上遇到了机核网的播客,那会儿已经开播了好几年,如获至宝,在两个月内把Gadio Pro栏目(特别是麦教授和四十二参与的)从第一期开始听完。之后随着机核的发展,转战机核App,直到2020年播客爆发,App也换成了小宇宙(意外发现就在五角场创智天地的前公司马路对面),形成了固定的收听习惯,订阅几十个中外栏目。

订阅的这些播客栏目,有些还是有相当的信息量。因为产品的音频形态,信息检索比较麻烦,有些播客即便刚刚听过,想回过头来找忘记或者漏掉的信息,也和很难定位到具体的时间点位重听。或者新接触一个播客,想知道以前聊过的内容里有没有自己感兴趣的话题可以快速加入收听列表。

架构

信息检索系统与搜索引擎

信息检索本质上可以分解成三个模块:

  • 下载/爬虫
  • 处理/索引
  • 检索/响应服务

传统的搜索引擎,这三部分对应了:

  • 爬虫系统:按照超链接把互联网的网页(文档)下载到本地
  • 索引系统:清洗数据,提取关键词,建立倒排索引(关键词->文档),索引更新
  • 检索系统:查询分析、排序结果文档

之所以要构建这三个系统,特别是爬虫和索引系统,主要原因在于整个互联网数据量太大,因此需要提前把文本内容下载并存储成检索友好的格式,这样用户通过关键词搜索就可以在几百毫秒之内得到结果。

Source: ByteByteGo https://blog.bytebytego.com/p/ep104-how-do-search-engines-work

RAG

随着大模型的出现,语义搜索也有了新的思路。这两年比较流行的方案是RAG(Retrieval Augementation Generation,检索增强生成,一个很拗口的名字)。我们也将采用这个方案。

RAG主要影响索引系统和检索系统,尤其是后者。传统的信息检索系统通过关键词匹配的方式搜索,直接把结果文档推给用户(再加上匹配到的关键词以及上下文高亮),但用户还需要自行处理加工。用户本质上是带着问题来的,比如“鸡蛋会增加胆固醇吗?”,“如何申请延迟提交报税表格”,关键词查询往往离最后的答案还有一定距离。

RAG利用大模型出色的语义处理能力,通过向量搜索(因为查询不再是关键词而是一个问题,传统的关键词查找加上倒排索引无法完成任务)查找到相关的文档,然后交给大模型去回答问题。RAG可以胜任语义搜索/问答的任务,但相对地使系统开销大大增加(10x),响应速度明显变慢(10x)。

来源:https://www.gptsecurity.info/2024/05/26/RAG/

播客搜索/问答架构

回到一开始的问题,我们搭建的系统也是由这几个模块组成:

  • 播客下载/爬虫:通过公开的RSS爬取播客音频和介绍信息;
  • 播客转录:把音频和介绍信息发送给语音到文字的引擎,变成文字稿,同时将文字稿分割处理向量化,放进向量数据库;
  • 播客搜索:搭建RAG系统,把问题转成向量进行向量搜索得到相关的文字稿,再把文字稿作为上下文和问题一起发送给大模型,得到最终回答并返回给用户。

选型

开发工具

最重要的开发工具是用来生成代码的大模型,这个年代做这种原型开发似乎已经没人从零开始写代码,尤其是还需要很多查找文档或者调试的工作。这次开发没有用很火的Cursor(舍不得花20刀月费)或者Github Copilot(公司有,但自己的设备也要花钱),而是体验阶段的Gemini 2.0 Flash Thinking Experimental搭配Google AI Studio。另外只是自己使用,暂时没有上线的需求,所以只在Jupyter Notebook里运行。

Google AI Studio写需求生成代码

语音转录

一开始想直接用OpenAI的whisper,价格如果嫌贵(一分钟$0.006刀,对应1集1个小时$0.36,100集要36刀也不是很便宜),也可以考虑本地host(但没有具体benchmark手头的4080可以跑多快)。主要的限制有两个:

  • 模型比较旧,处理prompt(比如时间轴,嘉宾识别)的能力不强;
  • 最大处理能力25MB,一个小时的音频大概是50~70MB,需要把音频切块。可以使用mp3lst等开源工具在段落切分(根据dB),但是不同音频的切分threshold可能不同,切分如果太细也会影响转录的精度。

前期工具调研在这一步卡了几天,后来想到可以直接用长上下文的大模型进行转录。尝试了市面上主流的几个模型以后,发现Google Gemini Flash 1.5非常合适:

  • 转录效果不错,可以基本正确生成时间轴,识别讲话的嘉宾;
  • 上下文窗口足够大,1M token可以容纳超过5个小时的音频(最大支持9.5小时);
    • 免费!免费档每天1500次配额,一集播客大概1-3次请求即可完成转录,转录一集大概3分钟完成,正好足够单线程处理);后面的收费档,一集一小时播客的成本大概$0.18(更正应为 $0.018,比官方价格贵因为上下文长且有好几次的对话),是whisper的一半(更正:应为5%),如果使用1.5 Flash 8B价格还能再减半(效果差点)。

解决了输入长度的问题,下一步卡在了输出这一步。为了避免单次请求占用过多的GPU资源,大部分模型的输出卡在了4k/8k,大概只够放半个小时的音频转录内容。难道又要回到音频切分的老路?其实解决办法很简单,在与大模型对话中继续提示:“请根据上面已经生成的内容继续生成转录文字稿。”,就会在上次停下的地方继续转录,直到完成所有的转录。这也是大模型编程神奇的地方:通过自然语言下发指令,而不是严格定义的编程规格/接口。

利用大模型的长上下文来做转录固然比较方便,但是这会导致需要下一次请求附带整个对话(之前转录的内容加上音频),成本直接翻N倍(如果是N次输出)。如果考虑成本的话,进行切分再拼起来是更好的选择。

索引/检索

这块没有特别的要求,基本上各厂商的文本对话大模型和文本向量模型就能满足需求。不过后面在文本向量模型上跌了个大跟头,后面的文章细说。

本地向量数据库选用了ChromaDB,直接让大模型替我做了选择。

附录:问问小宇宙

小宇宙官方也有类似的应用问问小宇宙,UI挺特别的,但是似乎产品一直没有迭代,召回也比较一般(似乎是基于每篇播客的AI总结做的,因此漏掉很多细节)。

An Incomplete Guide to the Bay Area Public Library System – Overview

(Note: This is a translation from riginal Chinese Edition 湾区公共图书馆系统不完全指南——概览篇 with the help from Google Gemini AI)

It was exactly ten years ago that I published “An Incomplete Guide to the Shanghai Library” (Parts-1, Part-2, and Part-3) on this blog. Having been in the Bay Area for a year now, visiting the library has become an important part of my daily life. On the one hand, I’m impressed by the abundance of resources, and on the other hand, I’ve also witnessed the various well-established usage systems, making me feel that the tax money was well spent.

P.S. There might be a chance to add a sequel to “An Incomplete Guide to the Shanghai Library” to record some of the new libraries I’ve visited in recent years (such as several suburban branches and the East Branch) and the significant changes.

System

What differs from the Shanghai library system I’m more familiar with is that the Bay Area library system embodies a more bottom-up, multi-level autonomy concept. This also fully reflects the differences in the political and economic systems between the two countries.

The Shanghai library system consists of three levels (municipal library, district library, and street/town library). Although it’s not a vertically managed system (I would guess the funding is also supported separately by each level of government), from the perspective of resources and allocation, the resources of the higher level are significantly better than the lower level. After several years of integration, Shanghai has basically incorporated all public libraries into one system, achieving a unified library card for borrowing from all levels of libraries across the city. This is quite convenient for readers, as you only need to register once to borrow from hundreds of branches throughout the city.

The introduction to the Bay Area libraries in this article is primarily focused on the South Bay and Peninsula areas, with the addition of online access to the San Francisco Public Library. Alameda in the East Bay restricts non-county residents from obtaining library cards. Firstly, these areas are not a single administrative region but rather three counties—Santa Clara, San Mateo, and San Francisco.

Within these three counties, SF and SC both have county-level (SF is both city and county) library systems with branches in various cities or neighborhoods. The SF library also has a main branch located in the city center.

SFPL Main Branch near SF Civic Center

Regarding the San Mateo County Library (SMCL), the situation is more complex. For example, while the libraries in this link are all within San Mateo County, they do not belong to the county library system. Generally, they are established independently by cities or neighborhoods.

The situation in Santa Clara County is the most complicated. First, the county-level library is the Santa Clara County Library District, SCCLD, which has branches in the following 8-9 cities. Among them, some major cities have built their own independent library systems, such as Sunnyvale, Santa Clara (City), Mountain View, Palo Alto, and Los Gatos.

Santa Clara县图书馆分散的馆址

Although San Jose is just one city, due to its large area and population, the scale of SJPL (San Jose Public Library) itself is even larger than the Santa Clara County Library, including 25 branches, with the Dr. Martin Luther King, Jr. Library as its main library. It is also shared with SJSU (San Jose State University). In terms of size, it’s not smaller than the main branch of SFPL (and the advantage of sharing with the university is that it opens very early, at 8 am; except for Sunday mornings, which are exclusively for students).

Dr. Martin Luther King, Jr Library in downtown San Jose is the main library of SJPL as well as library for SJSU

The advantage of the distributed branch system is that it increases the opportunity for the majority of people to access libraries, and books can circulate among these branches, greatly increasing the variety of books.

Many libraries are located near City Hall, Civic Center, or Community Center. If it’s not in a downtown area, there is usually free parking. The opening hours are also relatively friendly, usually open until 7-9 pm on weekdays and 5-6 pm on weekends. As they are established with public funds, entering and reading within these libraries doesn’t require any procedures, only a card is needed to borrow materials.

This article mainly introduces several major library systems in the Bay Area. The following articles will introduce library card registration, borrowing, searching, and e-library functions.

2024年终小结

时间转眼到了2024年底,今年的Blog写作数量一般,包括本文一共5篇。也给2025立个小OKR(需要很用力才能够到的目标)——一个月一篇,全年12篇,再过一年看看完成了百分之多少。

工作生活

在现在的公司度过了第7年,管理岗位的第5年。前几天突然想到我在现在的公司正好搜广推(搜索、推荐、广告)都做过,虽然搜索和广告不是核心的流量端,但这种遇不可求的机会,说不定哪天就来了。还没来得及盘点今年的工作,个人总体上马马虎虎,团队有小部分的亮点,但也有很多不足。经过一些招聘和离职,和团队的磨合也告一段落。相比于一开始的文化和管理挑战,开始习惯和适应当前的节奏。

缺憾:1)仍然没有找到一个有效的严格方法来度量各种模型的贡献;2)仍然没有对纯研究工作有独立贡献(但是可以提一些意见和想法)3)年初的一个想法,经多方推动,最后离上线老是差一点

收获:模型的推断有一些新的进步,包括LLM的推断优化和Ray的使用。没有放下一线的实践(比去年还多30%),抽空做做感兴趣的探索。

去过的地方

几次外出旅行——(西雅图一天一夜出差;单枪匹马自驾从北加到西雅图来回;春季和秋季趁着长周末分别刷了Kings Canyon和Sequoia National Park;南加感恩节家庭旅行)。

今年road trip是过足了瘾,把整个西海岸从北(Everett)到南(San Diego)走了个遍。

出差西雅图/Bellevue

到达西雅图机场
Bellevue我司所在的楼
匆匆回程

Sequoia红杉树国家公园

Memorial Day去的,人多车多,体验不是很好,很多时间在堵车等景区巴士找停车位,但是景色还是很不错的,前两张图是世界上最大的树(体积)——谢尔曼将军树。

自驾西雅图

老婆带着娃在六月中下旬回国探亲,难得偷闲的我在Juneteenth Day那周开始了蓄谋已接的road trip:

第一天:把家人们(这个词现在听上去怪怪的)送上飞机,从SFO出发到沿着101开到海边的Eureka小镇

第二天游览红木国家公园(Redwook National Park),晚上到达俄勒冈州首府波特兰。和水杉(Sequioa)相比,红杉(特别是海岸红杉)更高,而水杉体积更大。

市中心的Powell书店是世界上最大的独立书店

市区总体上还比较整洁,算是西海岸大城市里不错的

第三天是周一工作日,在几乎空无一人的公司波特兰Office里远程工作了一天,下班以后开赴西雅图(Bellevue)。波特兰办公室是见过我司最漂亮的,没有之一。而且一半以上的员工有独立的办公室(中间图,然而大家还是不太喜欢来)。晚上入住Airbnb,不同房间里住了不同的舍友。

Juneteenth Day公司放假,本来计划去Mount Rainier,连门票都预定好了,没想到一出门就碰到发动机故障灯,紧急联系了本地的dealer,虽然问题不大,也不用付钱,但Mount Rainier肯定是去不成了,中午和老同事吃了一顿饭,下午参观西雅图南郊的Museum of Flight和市中心随便走走。

西雅图市中心的水族馆和摩天轮,在《The Last of Us:Part 2》里来过。另外就是市中心的菜场和第一家星巴克。

周五休了一天假,首先预约参观波音总部Everett的工厂,可惜不能带任何的电子设备所以没有照片,拍的是Futer of Flight这个博物馆,包括工厂里停放的已经造好但还没取得适航证的777-9。

然后马不停蹄赶往Flying Heritage & Combat Armor Museum,是微软创始人保罗艾伦的个人军事收藏,都是真家伙(包括一辆切开的坦克),一点不比国家级别的博物馆差。

另外下午补了上次没参观完的Museum of Flight的室外展馆,第一次看到并登上了协和式的真机,空军一号(707版本)。晚上回到波特兰住宿,减少第二天赶路的里程。

周六从波特兰出发,游览火山口湖国家公园(Crater Lake National Park)。排队一个小时进山,山顶还都是大片的积雪,湖水异常湛蓝,非常震撼。晚上途径Mount Shasta山脚回到加州中央山谷最北边的Redding住宿,一下子从十多度的山顶到了39度的炙热。

Screenshot

最后一天,游览拉森火山国家公园(Lassen Vocalno National Park)。拉森火山上次大规模喷发还是在1914年,当年喷发的大石块还随处可见,山顶的高海拔还有大量积雪。

国王谷国家公园(King’s Canyon National Park)

某个周五趁着娃还没开学请了一天假去的,其实就在红杉树国家公园的隔壁,共用出入口。其中有世界上第三大的树——格兰特将军树。晚上打卡了Kingsman City的牛排馆,味道相当不错。

南加州/圣地亚哥感恩节之旅

继去年南加洛杉矶之旅,今年感恩节继续选择温暖的南加州,除了补上上次错过的衣阿华号战列舰,主要游览了圣地亚哥的几个主要景点。

震撼的三联装406mm主炮,仅次于大和号。

第一次摸到密集阵真家伙,人称R2D2

战斧巡航导弹的真家伙

继续军舰之旅——中途岛号航空母舰博物馆

第三天去了野生动物园,人生第一次坐了热气球。下午City Harbor Cruise,可惜风大还起雾,不过算第一次看到现役的航母卡尔文森号。

最后就是乐高乐园和海洋世界了

读过的书

今年大部分的Blog都是和书有关。

人在海外,看中文书主要通过:1)电子版;2)出差同事帮忙带;3)京东海外购。

《读库生鲜》是《读库》的青春版,内容相比《读库》主刊我更加喜欢(对于戏剧文学实在不太感兴趣。《读库》胜在电子版App,希望《读库生鲜》也能早日推出电子版)。

另外唯一看完的技术书是《Hands-on Large Language Model》,入门大模型深入浅出的好书,有大量的视觉化帮助理解。

现场体育比赛

MLB

沾了公司实习生的光,在公司的包厢里观看了MLB湾区德比——旧金山巨人队对战奥克兰竞技者(后者是《Moneyball》的主角球队,也是在湾区的最后一年)。

NBA

虽然只是季前赛,坐在最高的山顶,但是领到了库里的限量版美国队小金人!

有意思的事——开飞机!

花了200多美金带着娃(有点晕)体验了一下一个小时的塞斯纳172,包括起飞降落盘旋。希望明年可以真的开始学起来。费用在湾区大概要将近2w美金,大部分的费用是租赁飞机的价格(70小时*200美金/小时)。学飞行最大的障碍在我看来是通讯,嘈杂的环境,简练的术语,真的是怕听不懂。

2025展望

  • 一个月写一篇blog,并开始写作英文blog
  • 一个月看完一本书
  • 个人对生产系统有研究贡献
  • 继续在MLE方面有所实践
  • 能够出国一次;出差,旅游或者回国(取决于排期)
  • 看一场橄榄球和冰球,集齐美国四大体育的现场体验
  • Stretch:真的开始学开飞机

湾区公共图书馆系统不完全指南——概览篇

正好是十年前,我在这个博客里发表了《上海图书馆不完全指南》( )。到湾区一年来,拜访图书馆也日常生活中很重要的一部分。一方面感叹资源之丰富,同时也见识到了各种完善的使用制度,让人觉得这部分的税金没有白交。

另:《上海图书馆不完全指南》有机会也会再补充一个后续篇,记录一下后来几年的一些新拜访的场馆(比如几个郊区馆和东馆)和大的变化。

系统

和我比较熟悉的上海图书馆系统不一样的是,湾区图书馆系统更多体现了一个自下而上,多级自治的理念。这也完全反映了两个国家政治经济体制的差异。

上海的图书馆系统分为三级(市级馆、区级馆和街道/镇级馆),虽然并不是垂直管理(另外盲猜拨款应该也是有各级政府的分别支持),但是从资源和调度角度来看,上一级的资源是大大优于下一级的。经过几年的整合上海基本把所有的公共图书馆纳入了一个体系,实现了一卡通借全市各级馆,这一点对于读者来说相当方便,只要一次办证就可以在全市数百个分馆借阅。

本文对湾区图书馆的介绍基本仅限于南湾和半岛地区,加上线上访问旧金山图书馆。东湾的Alameda限制非本县居民办证。首先这些地方不是一个行政区域,而是三个县——Santa Clara, San Mateo和San Francisco。

这三个县当中,SF和SC都在县一级(SF是市县一体)建有图书馆系统并在一些city或者neigborhood设有分馆。SF图书馆另外在市中心有总馆。

SFPL在Civic Center旁边的总馆

对于San Mateo县图书馆(SMCL),情况复杂一些。比如这个链接里的图书馆虽然都在San Mateo县内,但是不属于县图书馆系统,一般都是由city或者neighborhood自己设立。

Santa Clara县的情况最为复杂。首先,县一级的图书馆是Santa Clara County Library District, SCCLD,在下面8-9个city设有分馆。当中有一些主要的city自己建设了独立的图书馆系统,比如大家比较熟悉的Sunnyvale, Santa Clara (City), Mountain View, Palo Alto和Los Gatos等等。

Santa Clara县图书馆分散的馆址

San Jose虽然只是一个市,但是由于面积大人口多,SJPL(San Jose Public Library)本身的规模甚至超过了Santa Clara County Library,包括了25个分馆,其中作为主馆的Dr. Martin Luther King, Jr. 图书馆还是和SJSU(圣何塞州立大学)共享,规模上不比SFPL的总馆规模小(而且和大学共享的优点是开门时间很早,早上8点;除了周日早上是学生独享时间)。

圣何塞市区的马丁路德金图书馆既是SJPL的主馆,也是SJSU的图书馆

分散馆址系统的好处是可以让大多数人接触图书馆的机会增加,而书籍可以在这些分馆里流通,大大增加了书籍的品类。

很多图书馆就设立在City Hall, Civic Center, Community Center附近,如果不是城区的话一般也会有免费停车场。开放时间也比较友好,平日开放到晚上7-9点,周末一般是5-6点。由于是通过公共资金设立,所以这些图书馆的进出和阅览都不需要任何手续,只有外借资料才需要办理证件。

本文主要介绍湾区的几个主要图书馆系统。接下来会分几篇文章介绍图书馆的办证、借阅、查找,以及电子图书馆功能。

The Bomber Mafia

刚看完Gladwell的”The Bomber Mafia”(中文译名《正战争与沉迷》,略有点莫名其妙)。二战前美国陆军航空队有部分专家精英痴心于精准轰炸,即通过准确打击敌方命脉(比如轴承厂),以达到瘫痪敌方的目的,人称“轰炸机黑手党”(六七十年代又出现了战斗机黑手党)。

特别是后来出现的诺顿投弹瞄准器,让轰炸机通过在高空输入各种参数(风向、高度、湿度、温度等)即完成万米投弹,而不必冒着对方防空火力承受大量损失。在此之前精准轰炸只能通过低空地方才有可能。轰炸机黑手党认为这样可以以双方最小的代价结束战争,而不需要牵扯到大量士兵厮杀和后方的平民损失。

在欧洲战场,轰炸机黑手党出师不利。一方面由于英国方面坚持使用夜间区域轰炸,另一方面投弹瞄准器的精度也不太够,只取得了不大的战果。而后在太平洋战场,美军占领了马里亚纳群岛以及B-29的服役,轰炸日本本土的大幕即将拉开,这也是轰炸机黑手党的又一次证明自己的机会。

在日本战场,轰炸机黑手党碰到的另外一个问题是高空气流导致精度无法保证。在几次战果寥寥的出击之后,黑手党代表人物汉塞尔被撤,换上了后来大名鼎鼎的李梅。这个时候正好碰上了凝固汽油弹(napalm)的诞生,日本本土的苦日子也开始了。

凝固汽油弹本质是胶状,液态汽油泼洒在固体表面难以附着持续燃烧,而凝固汽油可粘在目标上并产生上千度的高温,因此对物体和人员有强烈的杀伤。 李梅上任后改变战术,低空夜间区域轰炸,造成大量人员特别是平民的伤亡(最大的行动在一夜间造成10万人以上死亡,超过原子弹),具体可参考《天火焚魔》。

最后从战术战果上看,区域轰炸取得了胜利,但作者也对轰炸机黑手党也进行了高度褒扬。书中提到汉塞尔很喜欢《堂吉柯德》,他本身也是一个堂吉柯德式的人物,创新、敢于尝试和执着。李梅赢得了战斗,但汉塞尔赢得了战争。

《游戏结束》

《游戏结束》主要讲述的是任天堂在上世纪八九十年代,“雅达利大崩溃”之后的时代,如何重新树立行业和顾客对电子游戏(注意不是电脑游戏)的信心,并通过几个大作占领北美电子娱乐市场的故事。主要的产品包括NES(又名FC、红白机、8位机、卡带游戏机;当年中国流行的更多是以小霸王为主的兼容机)、超级NES和Game Boy。

这本书的副标题——“任天堂全球征服史”,主要着墨点在如何攻克北美市场。主人公则既不是公司二次创始人,三代社长山内溥,也不是马里奥的设计师宫本茂,而是山内的女婿荒川实和高级副总裁霍华德林肯,一手创建北美分公司并取得垄断性地位,以及后来和雅达利、世嘉、索尼市场争斗的前前后后。其中既有强大的产品、绝妙的营销手段,另外东半球最强法务也并非浪得虚名。

最精彩的地方还是如何获得《俄罗斯方块》掌机版权的故事,如果之前看过前两年上线的电影《俄罗斯方块》可以在本书中找到真实历史的走向。

本书成书于1994年,PS第一代刚刚发布。自然也没有后来的低潮期(N64),岩田聪时代(Wii + Switch)直到现在的御三家格局。有兴趣的可以看看《任天堂往事》系列5篇文章。

P.S. 向想了解游戏背后故事的朋友们推荐读库出品的御宅学系列

2024.5 书籍阅读记录

搬运自Twitter(不习惯叫X)的记录,不过不用拘泥于140字的限制。https://twitter.com/liujinmarshall/status/1789403530660368744

最近一个多月看书的进度还可以。实体书(国内同事带过来,以读库系列为主)看了《读库生鲜001》、《入关》、《像素工厂》、《奔袭》,电子书看了《我在上海开出租》以及《鹿鼎记》(对,你没看错)。

《读库生鲜001》我的理解是东东枪的读库青春版(并不是低配的意思。虽然都是非虚构,但《读库生鲜》的选题更适合年轻群体。比如谷大白话的《神秘咒语自制指南》里提到的《哈利波特》的咒语,和许岑的《自学自学》。唯一没看的是《侦探红楼梦》,因为我到现在也没读过《红楼梦》。

《奔袭》是在飞往西雅图的飞机上看完的。很早以前就知道的故事但是没想到还能写成一本书。在当前巴以冲突的语境下看更有不同的意味,只不过似乎舆论已经有些了反转。当年的反恐斗士的亲弟弟比比转眼已经成了恶龙。

《像素工厂》里不是简单的加班赶工最后做成爆款的励志故事,似乎成功的游戏背后都有不同的故事。第一次吃众筹螃蟹的“永恒之柱”,上线大崩溃的“暗黑破坏神3”,一人开发者的“星露谷物语”,再也不想做光环之后的成果“命运”,失去“帝国时代”转而开发“光环战争”。这个作者还有同类题材的《Press Reset》。另外今年十月份他还有一本关于暴雪的新书要出版,值得期待。

今天刚看完《入关》,讲述从努尔哈赤起兵到清兵入关的明清战争中最主要的几个节点——萨尔浒之战、宁锦大捷、袁毛之争、松锦之战、山海关大战。虽然明帝国拥有一亿人口、百万大军,但即便是最初的萨尔浒明军也不占有绝对优势。辽人集团在明清之间的摇摆以及最后被清军收服对战争的走向起了非常关键的因素。另外作者也顺便批判了“明朝中心主义”。明朝灭亡不仅仅是自己不行,清朝更强甚至更重要。

第一次看这边书是《读库2103》上的摘录,印象最深的是有女乘客搭车绕了一圈内环加半圈中环。当年我也分别绕过,骑自行车绕内环的道路和开车绕中环(为了让娃午睡)。比较令我感慨的是书中的上海街道,可能这也是我唯一还比较怀念的地方。当年魔都的熟悉街道现在还记得,不过现在驾照都过期了。

如果在金庸的14部武侠里选风格最特殊的,我觉得大部分会选这一部。除了当中神龙教影射红卫兵的那些桥段,其他部分恕难欣赏。基本上只是因为《鹿鼎记》名气大捏着鼻子读完了。单日阅读最久的3个小时17分钟是在国税局排队交材料。

我的 2023

窗外的雨点声把我的思绪一直拉回一年前的现在——那也是一个大雨交加的夜晚,我们抵达了旧金山国际机场。这一年的生活变化之大,是参加工作以来十多年未曾经历过的。回过头来也感慨自己的勇气,在人生步入中年,还做这么大的改变人生和家庭轨迹的决定。值得简单记录一下。

登陆(字面意义上的,不是“上岸”)

(出发前的各种戏剧性暂时按下不表,各种有惊无险和手忙脚乱,后面回想起来还是觉得很魔幻。当然从现在看2022年,即便仅仅过了一年,你都很难相信这些真实地发生过。可能这也是80/90后很难以想象六七十年代发生的事情吧。)

IMG_3781
当时还需要经停首尔的航班

在2022年的最后一天,拖着刚被新冠折磨过一周的身体,我们踏上了前往异国的航班。拜国际日期变更线所赐,2023的新年钟声听了两回,一次是在首尔的地面(那时候疫情还没完全放开,旧金山和上海之间的航班需要经停首尔),另一次是在湾区的酒店里。

即便之前来过不少次,但在半个地球之外的国度操着非母语完成本地居民的事务(租房、买车、上学、办水电网络),这种不确定性难免让人头皮发麻。还好这一切都比较顺利,在前两三周内都搞定了。一个多月后驾照也顺利考到了,基本算是settle down。

跑过了所有流程之后,花了2个多小时用Lucid Chart整理了一个流程图,分享给今年之后登陆的同事,也算是做了一件小好事。

Onboarding简要流程(每个步骤上面一些备注无法导出)

生活

首当其冲的是生活成本的上升。享受了多年的低廉劳务和生产成本以后,在心理上完成物价坐标系转换之前,生活成本的冲击是一道需要克服的障碍。之前在上海,一般的超市(除了Costco和山姆)和普通的饭馆(除了海鲜、米其林和精品日料),基本不怎么看价格,因为最多也就是一包零食和一道小荤菜最多也就几十甚至大几十人民币。而在湾区,普通超市如大华/Target,普通街边的饭馆,都要仔细看好价格,加上小费和税。一顿饭三个人吃一百多刀,只能说是一般的水平。

IMG_4763
周末日常徒步

之前都听说国外的生活是“好山好水好无聊”,自己体验过后,大约觉得对于年轻人和留学生也许是对的,但是有娃的家庭还不至于发出这样的感叹。不过这也有可能是在湾区的偏见,首先湾区比较鸡娃,所以可以很轻松找到通过娃把周末日程填满的活动(比如各种体育艺术活动或者就是辅导班),其次如果肯跑稍远一点(单程1个多小时以内),湾区周边还是有很多可以参观的博物馆、科技馆或者是自然景观(高山、海滩、草甸和平湖)。这还是我们一次都没参与后两项湾区三俗(徒步,摘草莓/樱桃,滑雪)的前提下。

IMG_5313
黄石大峡谷

IMG_5569

达成了人生之前的一个梦想——住在图书馆旁边,可以几乎每天去——还真的做到了。除了借书,更多的时间花在了看杂志上,比如《纽约客》、《大西洋月刊》、《国家地理》和《连线》。相对于读书,一来比较有时效性,第二选题比较合口味,第三篇幅合适,不是很短的几分钟阅读也不是很长的需要十几个小时。大概一两个晚上(每次半个小时)看完一篇长文。即便不去图书馆,也可以凭借借书证免费获取这些杂志的线上版。而国内似乎没太多类似的选择,中文严肃媒体似乎只剩下《财新》还值得一读,而且有着较高的收费门槛。

杂志看了很多,书虽然借了很多,但回顾一下完整看完的就两本(Cover to Cover)——罗伯特·卡普兰的《Earning the Rockies》(中文译名《成败落基山》)以及Vaclav Smil的《How the World Really Works》(简体中文译作暂未出版)。看了半本的有图灵者得主Pearl的因果效应通俗书《Book of Why》和游戏类小说《Tomorrow, Tomorrow and Tomorrow》(大概是《明日复明日》?)。

2023的大型游戏都是在PS上玩的,《战神4:诸神的黄昏》跨年跨国完成了。以普通难度打通了《瑞奇与叮当:倒转时空》、《GT7》、《暗黑破坏神4》和《2077:往日之影》,进度慢的发指。年底入了外星人和XGP,开始体验不一样的游戏。

对喜欢看体育比赛的我来说,有好消息也有坏消息。欧洲联赛改到了每天的早上和中午,早场的比赛看不上,但总体上重要场次还是有的。第一次看了欧冠决赛,因为周中的比赛在上班时间。F1基本就得早起,除了西半球的比赛。本地的体育转播是一个大问题,Live TV一个月60刀以上开通不划算,但一个个购买或者寻找资源也不方便,所以这些比赛改看赛后的精华,每次勇士队和49人的比赛一两个小时内基本可以保证看到。

如果说生活上很多地方都发生了巨变,那比较值得一提的就是没发生变化的那部分。私人娱乐还是电子游戏(PS5为主,年末入手了外星人R16),视频网站(之前视频一直主刷油管+奈飞,对B站无感)。虽然不看抖音/Tiktok和小红书,但还是会刷朋友圈、推特、微博以及知乎(纯娱乐部分),甚至一些国内的新闻。如果是在二十年前,不论是看新闻、电视、电影和体育比赛,似乎只有本地的选择——和国内的联系不能说没有,但除非是主动去获取,不然大概率比较难以获得。现在即便已经到了新的国度,还是可以精神上活在原来的圈子里。B站、抖音、小红书、微博、百度、朋友圈都可以继续,只是缺少了阿里、京东和美团。

工作

语言和沟通的门槛对于不同的角色是不同的。如果是IC工程师,特别是资历浅的岗位,其实国内好一点的学校本科平均水平也能对付,let the code talk。设计和分析岗位要求稍高一些。产品和管理岗位要求最高。

对于亚洲背景的一线管理者,另外一个挑战是更为平等的文化。做出的决定需要让团队成员心服口服,或者反复协商,才能有效地推行。而多元的背景加上散布全美甚至欧洲的地点,又上了一个难度。

对于我个人,四年前的岗位转化,到现在来看,也正好到了一个跳脱舒适圈的时候。

展望

去年虽然没有写小结,但是总体就一个不大不小的目标——适应生活,站稳脚跟。现在来看基本可以打个勾。这一切,也离不开老婆的大力支持,操持这个家。

新一年的期望:

  • 身份有一些进展(和个人努力无关)。
  • 家人们(包括身边和远方的)身体健康。有些小庆幸躲过了2023年这一大波免疫债,家人们也都还好,新一年继续好好保持。我自己也要降低2公斤的体重。
  • 发展个人的兴趣爱好,折腾一些side project
  • 工作上意外少一些,继续长一些技能和本领,适应后开始推动一些想法和项目。

Continue reading “我的 2023”