2026年5月

周末在老家,看望家里老的,也是离开都市一下,换口气放松一下,最近几年回得多,每次回总期望自己可以早点退出“游戏”,AFK 是最好的选择。

本周观影

  • 我用4天,重走了这条曾经撑起一个国家命运的悲壮公路:滇缅公路,云南驿、飞虎队、机窝和惠通桥,之前没仔细了解过这段历史,听着博主的讲解,从昆明开始走一遍战时重要的运输线。重返滇西1944,我终于理解了一寸山河一寸血的历史分量:松山,激战的地方,中国远征军值得怀念和敬佩;腾冲,龙江大桥,滇西抗战纪念馆,腾冲战役;芒市,采访修路工的下一代,南侨机工,中缅国界畹町桥。这个博主很实在,拍的说的都很不错,推荐。
  • 合集·爸爸妹妹中国之行:今天看了好多这个中德夫妻的视频,这个系列是德国老爸和妹妹来中国,玩了北京和云南,是博主精心安排适合这个老爸和妹妹的路线,特别是在北京都是传统的路子,真好;也有带着老妈游中国的剧集,也挺好。

本周阅读

  • 《金融怪杰》:断断续续读完了,艾迪·塞柯塔、威廉·欧奈尔、大卫·瑞安和布莱恩·吉尔伯这四个人让我很有共鸣,对我个人有启发和帮助。
  • 《大唐双龙传》:读过好几次了,晚上醒来或平常想休息一下的时候,总会用 Kindle 读一下,我喜欢武侠的世界,大唐是我非常喜欢的一部,喜欢徐子陵和寇仲所经历的各种,特别是武学上的奇遇和进步,黄师的各种读了不少,最喜欢的还是大唐;我也喜欢金庸的《笑傲江湖》和《射雕英雄传》。

本周播客

E55 都说 A 股全是情绪、没有价值,是真的吗?|中国大类资产投资 2025 年报:数据说话,长期看一定是有确定性;每个人的投资风格还是取决于个人,我个人认同 Buy the Dip and Dollar-Cost Averaging (DCA) 结合,寻找确定性的标的加上指数方面的投入,但一定不要亏钱,用短期用不上的钱去投资,可以融资上杠杆,前提是自己可以扛得住风险。

随着持有时间越长,获取历史长期平均收益率的确定性越高。
四方法分解重要结论:

  1. 盈利增长是A股长期收益的核心动力;
  2. 长期持有权益资产能够获得合理的风险补偿;
  3. 股息收益率逐步提高,长期收益的稳定性与可持续性正在改善;
  4. A股长期收益与实体经济高度匹配。

关于白酒是周期见底还是永久衰退的一次审视:还没听完,学习一下白酒行业的分析,茅台虽然跌了不少,但一直是投资市场上的话题,段总也是一直推荐,有高股息和高确定性,成长性到了这个阶段可能是最不确定的了(回头 10 年来看是非常好,当下见底之后如何反弹,是不是后续还有一定机会,不乐观),今年五粮液改了去年财报的做法也是让市场对于这个行业有了更多的负面看法。

No.201 中国高铁简史:中国高铁的发展史,到底我们要怎样的发展,如果需要牺牲三代铁路人的话这是否值得?通过转让技术,获取自己的发展,再进行输出,这种路线是良性的吗?能赢得世界对我们的尊重吗?

本周胡思乱想

  • 要赚钱不要嫌麻烦和辛苦,所有的苦逼都是为了当下的自己和未来的不苦逼。
  • 周末还是有点焦虑和无聊的感觉,还是不懂如何享受孤独和无聊的时光,总是想着做点啥。写作和阅读对我一定有用,还要就是有意识的多出去走走,漫无目的的走路和骑车,消费点啥,放下心里的执念和任何电子设备,远离信息焦虑和一些执念。周日下午出去跑步走路,刻意离开了电子设备,以及出去走了走,好多了,就该这么过。
  • 投资来说,我觉得是个人生历练,非常好的一种悟道,对于锻炼自己的心性和认知也很有帮助;美股/A 股,可能风格不一样,投资手段和策略也不一样,但是有些核心东西,自己本身的投资理念和框架我觉得是可以互相复用的;有人也能做到 20~30 倍的收益,能做是太牛了,但还是取决于个人的情况,眼光、赌性和其他市场的因素,我个人的理念来说挺难做到的。
  • 回顾了一下最近的状态,早上有 FOMO 趋势,舍本逐末,看各种信息和资讯,投入太多了,早上就花费了大量精力,人反而早早陷入焦虑和疲惫的状态,容易出各种问题,调整一下。
  • 还是继续不断寻求新的可能,不要放弃。

本周投资

  • 坚持对 SaaS 的判读(企业一定需要,AI 能解决部分问题,但是企业内部的人、组织体系、年度要花钱和各种政治问题等决定了 SaaS 只是暂时低估,核心的当前剩余履约义务(cRPO)指标健康就是好的投资机会),继续做了一定的投入,目前看是对的一个判断;美股在科技板块不同方向持续轮动中,存储、光、SaaS、MAG7 外加特总的喊话(如:Dell),但同时巴菲特提的教堂和赌场,一直在我脑子里打转,我自己一直和自己在对话,是个修行的过程。
  • 基金方面做了一些调整,减了部分日经,加了部分科技方向的 QDII,不过 QDII 还是要考虑汇率方面的因素。
  • 下周看看软件方面被砸的洼地公司,看看基本面和核心财务指标,考虑抽取部分第一层资金往第三层放一放(违背了我自己的原则,第一层不卖出),如果有机会,不然也没其他资金了。
  • 国内我等着“大一点”的机会,看着板块轮动来轮动去,一波一波的,规律就在那,一般人不是全职的真的挺难抓得住,我的原则是不做右侧。

本周文章

How to set up an AI-native organization

Agent 之间的通讯,以及共享上下文(各种信息,包括统一的 tasks),实现多 Agent 协作很重要;文中分享了 Agent first 模版,有多 Agent 模版以及 handoff https://github.com/awebai/agent-first-company-template

也看到了这个视频 How to Build a Self-Improving Company with AI,如果要围绕 AI 去做当下的事情,组织架构以及工具平台的研究,包括方法论和体系的变革,都是必不可少,不然就是旧瓶装新酒,没啥本质的变化大,大部分公司就是干点提效的事情结束,只能走到这一步了;真正需要的是燃烧 Token 而不是人头,是 Token 账单让你心慌,尽可能的扁平化,IC 去除中间管理层,记录任何内容(潜在意思就是让 AI 可以更好理解)实现自我进化。

When the work is done by agents, the company’s coordination is between them and not just between the humans. A few things follow from that:

  • You stop being the relay between every internal communication.
  • The work has artifacts (tasks, decisions, handoffs, status files) that survive any single conversation.
  • The agents need identities and addresses so they can message each other and coordinate.
  • The agents need a shared taskboard.
  • The agents need a mechanism to learn.

Best practices for Amazon DynamoDB Global Tables – Part 1: Operational readiness
Best practices for Amazon DynamoDB Global Tables – Part 2: Failover strategies
Best practices for Amazon DynamoDB Global Tables – Part 3: Validating regional resilience with AWS Fault Injection Service

这三篇文章基本说清楚了,在 AWS 体系下如果实现 DynomoDB 的 DR 方案,包括数据同步策略 MRSC/MREC(跨区域强一致还是最终一致),如何实现问题检测和切换(Route53 ARC vs. DNS-based Route53),如何验证(利用 AWS FIS)。

结合最近工作看,AWS 实现统一的监控和切换,还是不容易的,有第三方有方案,但是没看过。

一个月Vibe Coding:我写了什么,又学到了什么

博主做了几个 Vibe Coding 的产品,给了一些不错的经验分享,在流程以及 AI 的一些局限方面,但没点到 AGENTS.md 以及 rules/changes/skills 方面的规范约束,其实说的流程方面我觉得通过 AGNETS.md 以及 changes 的规范可以解决,同时要让 AI 明白需要有来回的讨论。

之前我也看到过月刊(第34期):创造的快乐这篇,今天翻出来重新看一下,也让 AI 总结了一下 iOS App 设计开发方面的一些实践推荐,我还没真正做一个有美感的“好用” App,但我想试试,作为一个起步,我老担心技术栈方面的问题,但其实现在应该是最不应该“害怕”的问题,要的是去尝试,体会更多创造的快乐。

基于上文的推荐,我跑通了 Pencil 设计到生成代码的这条路,但是如何做更好的设计、代码和验证,结合工具和 Skills 以及最佳实践(比如:AGENTS.md)等等,需要做更多更多的事情。

中国大类资产投资 2025 年报 - SBBI

还没细看这个框架,新的知识,第一次接触 SBBI 这个概念,存下来慢慢看。

SBBI(Stocks, Bonds, Bills, and Inflation) 最早由 Roger Ibbotson 和 Rex Sinquefield 于 1976 年在美国整理发布。它第一次以系统、可验证的方式,长期跟踪股票、债券、国债和通货膨胀等基础资产类别的风险与收益。它的重要性,不只在于留下了一套长期数据,更在于帮助我们用一套分析框架来理解大类资产:不同资产在足够长的时间里,能够提供什么样的回报,又需要承担什么样的风险。

中国大类资产投资 2025 年报 - SBBI 正是沿着这一研究框架,基于中国过去 21 年的数据,对各类资产的风险与收益进行系统分解,从而回答一个基本问题:投资收益,究竟从何而来?

我们用一个公式 R=A+B-C 来拆解投资收益:投资收益(Return) = 超额收益(Alpha) + 市场收益(Beta) - 投资成本(Cost)

声明:和 AI 协作完成的,文章内容和主体是个人写的,由 AI 润色完成。

如题,文章要叙述如何在 AI 时代做架构设计,解决 what / why / how 三个问题:AI 时代的架构设计到底是什么、为什么还需要它、以及具体怎么做。

what - 什么是 AI 时代的架构设计?

先回顾传统架构设计要解决哪些问题:

  1. 方法论与体系:采用 TOGAF、C4、Arc42 等框架定义架构工作的流程与产出规范;
  2. 原则与指导标准:定义架构原则(Principles)和指导标准(Guidelines),作为决策的约束边界;
  3. 架构实施:从需求输入出发,定义系统边界,产出分层架构设计(L1~L4),同时覆盖逻辑部署与物理部署;
  4. 决策记录:遇到方案取舍时,完成 ADR(Architecture Decision Record)或 KDD(Key Design Decision),通过讨论与评审流程完成决策并归档;
  5. 协作与治理:与上下游团队持续对接,确保架构上下承接一致,并持续演进和治理。

这些活动的产出物和目的在 AI 时代没有本质变化——系统仍然需要拆解、权衡仍然需要记录、架构仍然需要治理。真正变化的是生产方式和工作流。具体来说,AI 时代新增了三个维度:

第一,产出方式从「手写」变为「人机协作」。架构师不再从空白页开始画图、写文档,而是用 prompt 驱动 LLM 生成初稿,人做审阅、修正和最终决策。比如系统上下文图(C4 Level 1)可以从需求文档自动生成初版,架构师在此基础上调整边界和职责。

第二,架构产物从「给人看」变为「人 + AI 都能消费」。传统架构文档以图形和自然语言为主,人类能读懂但 AI 难以结构化处理。AI 时代的架构产出必须是结构化文本——比如用 LikeC4 的 DSL 描述 C4 模型、用 Mermaid 描述时序——这样 AI Agent 在下游可以直接消费架构设计来生成代码骨架或校验实现一致性。

第三,架构治理从「人工评审」变为「规则 + Agent 自动校验」。架构原则不再是贴在 Wiki 上的口号,而是写成结构化规则文件,由 Agent 在每次变更时自动检查——比如「是否引入了未经批准的跨系统直接调用」「新增服务是否符合技术栈规范」。

总结:AI 时代的架构设计 = 传统架构方法论 × Architecture as Code × AI Agent 协作。核心变化不是「要不要做架构」,而是「架构以什么形态存在、由谁和什么工具来生产」。

why - 为什么还需要架构设计?

这个问题其实需要拆成两层来回答。

第一层:架构设计这个活动为什么还需要?

从需求到实现,缺少前期设计和系统模块的拆解确认,后期一定会形成技术债。这和有没有 AI 无关——AI 可以帮助你更快地写出代码,但如果系统边界没划清楚、模块职责没定义好,AI 写的代码越快,积累的技术债越深。

架构设计过程中有大量不可逆的权衡:选择单体还是微服务、同步还是异步、强一致还是最终一致——这些决策一旦做出,后期改动的成本极高。AI 可以提供方案对比和数据分析,但它无法替代人对业务上下文、组织约束和长期演进方向的判断。

此外,康威定律依然有效——系统架构会反映组织的沟通结构。跨团队的系统交互设计,本质上是组织设计问题,这不是纯技术 AI 能解决的。

第二层:架构师这个角色还需要吗?

如果从 AI Native 组织架构和 AI Builder 的视角看,专职的、只做架构文档的架构师一定没需求了。原因很简单:当 AI 能根据需求自动生成架构初稿,一个能力全面的 AI Builder(既懂业务又懂技术又能驱动 AI)自己就能完成从需求到架构到代码的闭环,中间不需要一个「翻译层」。

但这不是说架构能力不重要了,而是架构能力需要重新分布

  • 能力左移:架构师(或承担架构职责的 AI Builder)需要更靠近业务侧,具备业务分析能力,能把业务需求直接转化为架构输入,而不是等 BA 或 PM 翻译好再接手;
  • 能力右移:架构设计需要直接成为代码生成的有效输入。架构产物不再扔给开发团队自己去理解实现,而是作为 AI Agent 的上下文,驱动代码骨架、API 定义、数据库 Schema 的自动生成。

换句话说,架构师不会消失,但会融入 AI Builder 这个更大的角色中。纯「画图型」架构师被淘汰,能端到端交付的 Builder 成为主流。

新的挑战

团队协作中,如何让 Agent 输出的架构既被 AI 下游消费,又被人类团队理解和接受,是一个新的工程挑战。光有一堆结构化文件不够,还需要清晰的工作流、评审机制和质量标准。

how - 怎么做 AI 时代的架构设计?

核心理念:Architecture as Code(AaC)

选择 Architecture as Code(arch-as-code.org)作为基础范式,原因有三:

  1. 结构化文本是 AI 的最优输入:虽然现在的多模态模型能理解图片,但对于持续的演进和治理,结构化文本(DSL、Markdown、YAML)可 diff、可 review、可被 Agent 精确解析,远胜于 PPT 和白板照片;
  2. 版本控制是架构治理的基础:架构产物纳入 Git,变更历史可追溯,原则检查可自动化;
  3. AI 可直接消费并驱动下游:Agent 读取架构设计文件后,可以直接生成代码、校验实现一致性、更新文档。

工具选择

  • LikeC4:提供结构化的 C4 模型 DSL,同时支持可视化。选它的核心原因是它的 DSL 是 AI 友好的结构化文本,而生成的图是给人看的——兼顾两者。
  • Mermaid:用于时序图、流程图等动态视角的描述,同样是文本 DSL,AI 生成和修改都很方便。
  • C4 模型:作为架构分层的方法论,从 System Context(L1)到 Component(L3)再到 Code Level(L4),层级清晰,适合渐进式细化。
注:LikeC4 有标准的项目组织结构,下文的设计需要在此基础上做适配调整。

项目组织结构

整个架构项目分为两层:

  • .harness/:架构的「控制面」——规则、流程、变更记录、AI 技能定义。这是让 AI 知道「怎么做好架构」的地方;
  • architecture/:架构的「数据面」——实际的架构设计产出。这是让 AI 知道「系统长什么样」的地方。
.harness/
  rules/                              # 架构规则与约束
    kdds/                             # KDD/ADR 结构化记录
      2026-001-选择单体而非微服务.md
      2026-002-采用事件驱动解耦订单与库存.md
    architecture-principles.md        # 架构原则(如 cloud-first、单体优先等)
    architecture-guidelines.md        # 架构指导规范
      design-process.md               # 设计流程定义
      design-standard.md              # 设计标准与约束
      design-techstack.md             # 技术栈规范
  changes/                            # 基于需求输入的架构变更(参考 SDD 格式)
    _template/
      spec.md                         # 变更规格说明
      summary.md                      # 变更摘要
      tasks.md                        # 变更任务分解
  skills/                             # 自定义 AI 技能定义

architecture/
  system-context.c4                   # C4 Level 1:系统上下文
  L1-design.c4                        # 平台级设计(解耦为多个系统)
  xx-system/
    L2-design.c4                      # C4 Level 2:系统解耦为多个子系统
    xx-subsystem/
      L3-design.c4                    # C4 Level 3:子系统解耦为多个组件
      xx-component/
        L4-design.c4                  # C4 Level 4:服务/API/数据模型设计
        sequences.mermaid             # 时序图
    deployment.c4                     # 部署架构

AGENTS.md                             # AI Agent 的项目上下文(入口文件)
CLAUDE.md                             # 指向 AGENTS.md
README.md                             # 项目说明

各目录职责详解

.harness/rules/——架构的「宪法」

这个目录定义了架构的约束边界,AI Agent 在做任何架构决策时必须参考。architecture-principles.md 是最高层级的决策原则,比如:

  • 「单体优先,确有必要才拆微服务」——这是对微服务潮流的明确约束;
  • 「cloud-first,所有新服务默认上云」——消除了每个项目重新讨论部署方案的摩擦。

architecture-guidelines.md 下设三个子文件,分别定义流程(怎么做架构设计)、标准(架构产出的质量标准)、技术栈(可用技术及版本约束)。这些不是给人看的文档,而是 AI Agent 在做架构生成和校验时的规则输入

.harness/kdds/——关键决策的不可变记录

每个架构决策以独立文件记录,包含:背景、问题、考虑的方案、决策、后果。格式采用结构化 Markdown,方便 Agent 检索和应用。例如,Agent 在做新系统的技术选型时,可以检索所有 KDD 中关于「数据库选型」的决策,确保一致性。

.harness/changes/——架构变更的工程化入口

参考 SDD(Spec-Driven Development)的思路,每一次架构变更不是随意改文件,而是走「规格 → 摘要 → 任务拆解」的标准流程。_template/ 提供标准模板,每次新变更复制一份,Agent 按模板引导人类完成变更规格的填写,然后自动更新对应的架构文件。

.harness/skills/——自定义 AI 能力

存放项目特有的 AI 技能定义,比如「生成新系统的 L2 设计」「校验 L3 设计是否符合原则」等。这些技能可以被 CI 流程或开发时的 Agent 直接调用。

architecture/——架构设计的实际产出

按 C4 模型的层级组织:system-context.c4 描述系统与外部参与者的关系(L1),向下逐级细化到组件级(L3)和代码级(L4)。每个 .c4 文件是 LikeC4 DSL 结构化文本,.mermaid 文件是 Mermaid DSL。两个格式都是纯文本,可 diff、可被 Agent 精确读写。

AGENTS.mdCLAUDE.md

AGENTS.md 是整个项目的 AI 入口上下文文件,告诉 AI Agent 这个项目的性质(架构设计项目)、目录结构、工作方式。CLAUDE.md 是一个符号链接或引用文件,指向 AGENTS.md,确保不同 AI 工具都能找到项目上下文。

工作流示例

以「需要给订单系统设计异步通知能力」为例,走一遍完整流程:

  1. 发起变更:开发者复制 .harness/changes/_template/,填写 spec.md(描述业务需求:订单状态变更时通知下游)、summary.md(变更范围:新增消息队列,订单服务作为生产者)、tasks.md(拆解为 3 个任务:选型 MQ、定义消息格式、更新 C4 设计);
  2. AI 生成架构初稿:Agent 读取 spec.md.harness/rules/(原则、技术栈规范),生成 L3-design.c4 的变更和一个 sequences.mermaid 时序图初稿。技术栈规范约束了 MQ 只能选 Kafka,Agent 自动遵循;
  3. 人工评审:架构师(或 Team Lead)review Agent 的产出,调整系统边界——比如决定通知服务是否需要独立的子系统还是作为订单系统的扩展组件;
  4. 记录决策:如果讨论中有取舍(比如「为什么不直接调 API 而要走消息队列」),用 KDD 模板记录决策,归档到 .harness/kdds/
  5. Agent 校验 + 驱动代码:CI 流程中,Agent 校验变更后的 .c4 文件是否符合 architecture-principles.md,然后基于 L3/L4 设计生成 Kafka topic 配置、消息 Schema 和生产者/消费者的代码骨架;
  6. 合入并演进:变更合入主分支,架构资产随代码一起版本化管理,后续任何人对架构有疑问,直接读 .c4 文件,不需要翻 Confluence 或过期的 Wiki。

ADR/KDD 模板示例

# KDD-2026-003:订单状态变更通知采用消息队列而非同步 API 调用

## 背景
订单服务完成状态变更后,需要通知下游(库存、物流、通知中心)。
当前方案是同步 HTTP 调用,下游增多后订单服务耦合严重。

## 决策
采用 Kafka 作为消息中间件,订单服务发布事件,下游各自消费。

## 考虑的方案
| 方案 | 优点 | 缺点 |
|------|------|------|
| 同步 HTTP | 实现简单,可立即获得结果 | 耦合重,下游故障影响上游 |
| Kafka 消息 | 解耦,下游可独立演进 | 引入 MQ 运维复杂度,需处理最终一致性 |
| gRPC Stream | 性能好 | 下游改造大,团队不熟悉 |

## 后果
- 订单服务不再感知下游数量变化
- 需新增 Kafka 集群运维(已在技术栈白名单中)
- 业务流程从同步变为异步,需调整监控和告警策略

常见反模式与风险

  1. AI 生成的架构直接合入不加评审:AI 不了解组织的政治边界和团队的隐性约束,可能产出技术上合理但组织上不可行的方案。每次 AI 产出必须经过人工 review。
  2. 原则写得太大太空,Agent 无法执行:像「系统应该可扩展」这种原则对 AI 来说是噪音。原则必须具体到可被程序化检查——比如「系统间通信只能通过 API Gateway 或 Kafka,禁止直连数据库」。
  3. 过度依赖可视化,忽略结构化源文件:如果团队直接改图而不改 DSL 源文件,架构就退化成了传统的「画图存档」。必须坚持 DSL 是唯一真相源(Single Source of Truth),图只是渲染视图。
  4. KDD 写了不维护:过期的 KDD 比没有 KDD 更危险——Agent 检索到旧决策可能做出错误约束。KDD 应该有生命周期管理,定期 review 和标记废弃。

成功度量

当以下现象出现时,说明 AI 时代的架构设计实践已经落地:

  • 新系统的 L1~L3 设计初稿由 AI 生成,人工只做 review 和微调,耗时从天级降到小时级;
  • 架构原则变更后,Agent 能自动扫描所有现有设计,列出不符合新原则的条目;
  • 新人加入团队,通过读 .harness/rules/ 和 AGENTS.md 就能理解架构约束,不需要老员工口口相传;
  • 代码实现与架构设计的偏差能被 CI 自动检测——比如代码中出现了架构设计里没有定义的服务间调用。

总结

AI 时代的架构设计不是要抛弃过去的方法论,而是把架构从「人写的文档」变成「人 + AI 协作的结构化资产」。核心三件事:用 Architecture as Code 让架构产物可机器消费、用规则文件让约束可自动执行、用 AI Agent 让生产和校验自动化。架构师这个头衔可能会淡化,但架构能力——拆解系统、权衡取舍、定义边界——永远需要,只是承载方式和协作模式变了。

本周过的有点浑浑噩噩,回顾失去了主线和忙的方向和核心内容,下周开始调整一下。

本周观影

  • 在北极独自划船30公里去无人小岛露营:挪威博主又有更新了,海钓和岛上露营,海鸥、海豹和各种其他鸟类作伴,路亚小艇和各种装备,好玩又好看,真羡慕啊,最后总算钓上了几个螃蟹,酷!
  • 在 B 站的 Up 主行者况露看 EBC 大环线的徒步 vlog,成熟的路线,雪山盛宴,景美人美,我想去走走但是一想到要坐飞机那么远(我怕颠簸和对于失重超级敏感),又是犹豫了,看机缘吧,也许念念不忘会有点回响。(周四又正好看到了这个文章 天高地厚之间的行走:EBC 三垭口 + Gokyo + 岛峰全记录,作者也是户外达人了)。
  • 【阿丙】云南这座小城,温柔得让人想要住下来|云南 玉溪:云南玉溪,没去过,小城,洒满阳光,云南总是那么吸引人,去年去自驾了两周想着就是以后有时间多去普洱那样的地方住住,这个 Up 主还有云南其他好几个地方的视屏,非常好,也还有长江三峡好几个地方的 vlog,推荐。
  • 张雪为什么又又又又赢了?:认真踏实勤恳,异常优异的供应链和制造,会赢无数次。
  • 《风味人间 1 - 3 滚滚红尘》(还没看完):云南稻草烤猪,新疆烤鱼,远古流传下来的吃法;摩洛哥的塔吉锅,山东滕州的铁锅。

本周阅读

  • 《金融怪杰》:这两天读的这个人 - 布莱恩·吉尔伯,有一点记忆非常深刻,关于自我认知管理和情绪管理,了解自己和控制情绪,另外话说就是知道自己的能力边界和能力圈,同时懂得控制情绪,还在继续阅读中。

本周播客

“自由现金流”
“最后得出的一个结论是,价值投资在不同的市场都是有效的。大家往往对价值投资的理解是我持有的时间足够的长,它就是价值投资。实际上不是的,是你持有的资产,这些资产在远期能够稳定的创造现金流,并且你能够以一个合理或者合理偏低的对价去买到这个资产。长期持有,这个相对来说是价值投资。”

本周胡思乱想

  • 投资方面,看准了一定要舍得下重手,不然真是没有大幅“盈利”早日自由的可能的,但一定是不亏钱是第一要务,这方面所以要学习卡拉曼的《安全边际》。
  • AI 时代如何做架构设计文里,项目结构和实际执行起来要考虑如何结合 SDLC,而不是架构脱离后续的研发独立存在。
  • 看一下我们有的痛点,如何通过 AI/LLM 可以解决?

    • 架构设计遵循我们的 Principles、Patterns 和 KDDs
    • 架构设计的 review,包括文字和 lucid 图
    • Threat Modelling 执行
    • 架构设计的治理,确保实现符合架构设计
    • 实现的 reverse engineering,探视是否符合架构设计,如果之前没做过
  • 提醒一下自己,投资方面投入有点过于多了,用力过猛反而得不偿失了。
  • 团队沟通一片混乱,奔溃。

本周投资

  • 最大的问题是政策的不确定性,周五大暴击,周末有了一些准备的动作
  • 继续买入了点 SaaS
  • 集思录上看到了现金管理(https://www.jisilu.cn/data/repo/)这个栏目,学习了一下如何操作,学习了一种新的投资方式(国债逆回购,资金短期借出以获取固定利息的低风险理财方式,卖出 GC 开头的国债),后续有空闲的资金考虑操作一下

本周文章

这周我文章看的有点少,如上面说的投资方面用力过猛了,得收回点。

Forward Deployed Engineer:AI 时代的新宠岗位,到底干什么?

了解一下 FDE 这个角色,其实做 tob 服务,过去 onsite 在客户办公室,从来都是这样的,只是现在对于这个角色赋予更多的字面意义和光环,其实本质和 tob 服务过去做的事情没有啥本质区别。

说明:主要是人工写作完成的,但部分由 AI(Claude Code + DeepSeek + Waza Skills)完成的,持续更新(通常这句话是落空的)。

学习如何开发 Agent?我还是持续学习的一个过程,从理论到代码,但是缺少的是具体实践,希望自己从这个小文开始慢慢可以学着开发出一个 Agent 来,但是有多慢是不是会弃坑,回顾过去我总是这样的,但是希望这次真的不会,担心的一点由于足够慢,自己写的东西可能很快落后了,但是落后也比啥都没有强。

Agent 定义和架构

什么是 Agent?

一个 AI Coding Agent,本质上是在「用户输入 → LLM 推理 → 工具调用 → 结果反馈 → LLM 再推理」这个循环里跑的程序。拆开来看就四块:

  1. Agent Loop(主循环):驱动整个对话流转,管理 turn 的边界
  2. LLM API(模型调用):对接不同大模型,发送消息、接收响应
  3. Tool System(工具系统):让 LLM 能执行实际操作(读文件、执行命令、编辑代码)
  4. Context/Memory Management(上下文与记忆管理):管理对话历史、项目上下文、Skills 等

pi-mono 的分层设计

pi-mono 把 Agent 拆成了两层,这个设计思路很值得借鉴:

pi-coding-agent (Harness 层:CLI、资源加载、Session 管理、工具定义)
     ↓ 依赖
pi-agent-core      (Runtime 层:Agent Loop、AgentHarness、状态管理)
     ↓ 依赖
pi-ai              (API 层:多 Provider 统一接口、stream、类型定义)

核心思想:pi-agent-core 是「笨」的执行器,pi-coding-agent 是「聪明」的编排器。所有跟产品体验相关的内容(项目上下文、AGENTS.md、Skills、工具定义)都由 coding-agent 解析好,以纯字符串和工具对象的形式注入 agent-core。agent-core 只管跑 loop、调工具、管理状态,不关心这些内容从哪来。

这样分层后,如果想基于 pi-agent-core 做一个完全不同的 Agent(比如数据分析的、客服的),替换 coding-agent 这一层就够了,core 不用动。

Agent Loop 的运作方式

Agent Loop 是 Agent 的心跳。pi-mono 的 Agent Loop(packages/agent/src/agent-loop.ts)是一个双重循环:

外层循环(Follow-up),处理 follow-up 消息队列。Agent 完成一轮工作准备停下时,队列里如果有 follow-up 消息,就继续跑。

内层循环(Turn),单次对话轮次。每个 turn 包含:

  1. 发送消息给 LLM,流式接收响应
  2. 解析响应中的 tool_calls
  3. 执行工具(并行或串行),获取结果
  4. 将工具结果追加到上下文
  5. 检查 steering 消息队列,有新消息就注入
  6. 判断是否继续(还有 tool calls?有 steering 消息?)
  7. 继续的话回到第 1 步

下面是 Agent Loop 的简化伪代码:

while (有 follow-up 消息 或 有 tool calls 待处理) {
  // 1. 注入待处理消息(steering 或 follow-up)
  if (pendingMessages.length > 0) {
    context.messages.push(...pendingMessages)
  }

  // 2. 调用 LLM
  messages = convertToLlm(context.messages)  // AgentMessage[] → LLM Message[]
  response = await streamFn(model, { systemPrompt, messages, tools })

  // 3. 执行工具调用
  toolCalls = response.content.filter(c => c.type === "toolCall")
  toolResults = await executeTools(toolCalls)  // 支持并行/串行
  context.messages.push(...toolResults)

  // 4. 检查是否继续
  pollingMessages = await getSteeringMessages()
}

Agent 类(agent.ts)是对 Loop 的有状态封装,管理着当前对话记录(messages)、可用工具(tools)、系统提示词(systemPrompt)、思考级别(thinkingLevel),以及两个消息队列:steering(注入当前对话流)和 followUp(Agent 空闲后触发)。Agent 通过 subscribe() 暴露事件系统,外部监听 agent_startturn_startmessage_startmessage_updatemessage_endtool_execution_start/endagent_end 等生命周期事件来驱动 UI 更新。

开源 Agents 实现的分析小结

坚持把分析 pi-mono 和 bub 这个事情坚持下去,同时结合最近不同人对于 Calude Code 源码分析文章(分析源码的实践做法,参考这个:# 如何阅读一份源代码?(2020年版),下面是简单的摘录)。

跑起来;明确目的;区分主线和支线剧情;纵向(单模块)和横向(模块之间的依赖);情景分析;利用好测试用例;厘清核心数据结构之间的关系;多问自己几个问题;写自己的代码阅读笔记。

以上是我简单总结的一些阅读源码时候的手段和注意方法,大体而言有那么几点吧:
- 只有更好的输出才能更好的消化知识,所谓的搭建调试环境、情景分析、多问自己问题、写代码阅读笔记等都是围绕输出来展开的。总而言之,不能像一条死鱼一样指望着光靠看代码就能完全理解它的原理,需要想办法跟它互动起来。
- 写作是人的基础硬实力之一,不仅锻炼自己表达能力,还能帮助整理自己的思路。对程序员而言锻炼写作能力的手段之一就是写博客,越早开始锻炼越好。
最后,如同任何可以习得的技能一般,阅读代码这种能力也需要长时间、大量的反复练习,下一次就从自己感兴趣的项目开始锻炼自己的这种技能吧。

分析 pi-mono 目的是啥?1)如何实现加载 harness 相关的内容?2)如何管理记忆(状态)?3)如何管理 skills 和按需加载?4)如何管理工具调用?
分析 Bub 目的是啥?1)如何实现相关的理念的?2)如何对接 telegram?3)如何实现 tape 系统?
分析 Claude Code 目的是啥?

还有一个可能的参考项目,Agent-SDK without CLI dependencies, as an alternative to claude-agent-sdk, completely open source

pi-mono

项目地址:https://github.com/badlogic/pi-mono

不同 packages 的介绍:

  • pi-ai: "Unified multi-provider LLM API (OpenAI, Anthropic, Google, etc.)" 通过 API 对接各种不同大模型
  • pi-agent-core: "Agent runtime with tool calling and state management" 带工具调用和状态管理的 agent
  • pi-coding-agent: "Interactive coding agent CLI" 实现了 Coding Agent CLI,依赖 agent-code 和 ai
  • 其他的包括 pi-mom,pi-tui,pi-web-ui,pi-pods,不做分析

如何运行

基于 readme,npm install/run build/run check 完成后,以及 ./test.sh 之后,运行 ./pi-test.sh,启动 agent,然后执行 /login 选择 LLM provider,我选了 Github Copilot,基于提示完成登录后执行 /model 选择相应的模型,如:Opus 4.6,完成就可以用这个测试的 coding-agent 了。

pi-ai

主要问题:如何对接不同大模型?

pi-ai 是 pi-mono 的模型接入层,不在这次分析的重点范围。它通过统一接口 streamSimple(model, context, options) 屏蔽了不同 Provider(Anthropic、OpenAI、Google、GitHub Copilot 等)的差异,上层代码不关心具体是哪个 Provider,传 model 对象和消息上下文就行。agent-core 和 coding-agent 可以自由切换模型,核心逻辑不动。

pi-agent-core

Agent Core 的定位,以及其中的概念?

什么是 Core?为什么需要 Core?如何实现和使用 Core?

Stateful agent with tool execution and event streaming. - pi-agent-core

pi-agent-core 定位为一个「有状态的 Agent 运行时」,提供三个核心能力:

Agent 类(agent.ts,对 Agent Loop 的有状态封装。持有当前的 messages(对话记录)、tools(工具列表)、systemPromptmodelthinkingLevel。通过 prompt() 启动一轮对话,通过 continue() 从当前状态继续,通过 subscribe() 暴露事件系统,外部监听 Agent 生命周期中的每个节点。

AgentHarness 类(harness/agent-harness.ts,在 Agent 之上再加一层抽象,负责:

  • Session 持久化:每次对话自动写入 session 文件
  • 事件钩子系统:on() 注册特定事件的钩子(tool_callbefore_agent_startbefore_provider_request 等),subscribe() 监听所有事件
  • 消息队列管理:steering(中途插入的消息)、followUp(Agent 空闲后继续的消息)、nextTurn(下个 turn 的消息)
  • 资源管理:skills、promptTemplates 的管理和注入
  • 状态协调:模型切换、thinking level 切换、工具列表变更时同步持久化

AgentHarness 几个设计细节:

  • 不直接调用 LLM,而是通过 createStreamFn 创建闭包,每次 LLM 调用前动态解析 API key、headers、sessionId。OAuth token 可能过期,所以每次调用都重新获取。
  • prepareNextTurn 钩子:每个 turn 结束后重建 turnState(最新 context、model、thinkingLevel),下个 turn 用最新状态。用户可以在对话中途切换模型或思考级别。
  • pendingSessionWrites 机制:Agent 运行期间,session 写入先缓存起来,turn 结束时批量刷入,不用每次 event 都触发磁盘 I/O。

Session 系统(harness/session/,管理对话历史的持久化存储,后面细说。

pi-agent-core 本身不定义任何具体工具,也不加载任何具体资源——它只提供运行 Agent 的「引擎」。所有具体内容(工具定义、Skills、系统提示词)都由上层(coding-agent)注入。

AgentState 状态

  • agent-core manages live state, while coding-agent manages session memory

    • A simple way to think about it:

      • State: what the agent is holding in RAM right now to continue execution.
      • Memory: what the app remembers over time and can reload, summarize, or inject back into state.
    • So state is immediate and mutable; memory is durable or reconstructable. In this repo, memory eventually becomes state again when the session is restored or rebuilt.
如何调用工具?

pi-mono 的工具系统设计和 Anthropic 的 tool use 协议对齐,在上层做了工程化封装。工具调用的完整流程:

工具定义(AgentTool 接口,types.ts

interface AgentTool<TParameters, TDetails> extends Tool<TParameters> {
  label: string;                                           // 人类可读标签
  prepareArguments?: (args: unknown) => Static<TParameters>; // 参数预处理(兼容老旧模型输出)
  execute: (toolCallId, params, signal?, onUpdate?) => Promise<AgentToolResult<TDetails>>; // 执行
  executionMode?: "sequential" | "parallel";               // 执行模式
}

prepareArguments 是一个兼容性钩子:有些模型输出可能不符合 schema 的 tool call 参数,这个函数在 schema 验证之前运行,可以修正参数格式。

2. 工具调用流程(agent-loop.ts

prepareToolCall:
  1. 查找工具定义
  2. 运行 prepareArguments(如果有)
  3. schema 验证参数
  4. 调用 beforeToolCall 钩子(外部可以 block 某个工具调用)
  5. 返回 prepared(准备就绪)或 immediate(立即错误)

executePreparedToolCall:
  1. 调用 tool.execute()
  2. 支持 onUpdate 回调,工具可以流式输出执行进度
  3. 异常被捕获,转换为 error 结果(不抛异常,不中断 loop)

finalizeExecutedToolCall:
  1. 调用 afterToolCall 钩子(外部可以修改工具结果、标记错误、设置 terminate)
  2. terminate = true 表示这个工具希望 Agent 停止(当一批工具中所有工具都 set terminate,loop 提前退出)

并行 vs 串行执行,工具执行支持两种模式:

  • parallel(默认):先串行 prepare(因为 prepare 可能依赖前一个工具的结果),然后所有「已准备好」的工具并发执行。执行完成的顺序可能与工具在 assistant message 中出现的顺序不同,但最终 tool_result 消息按原始顺序排列。
  • sequential:逐个执行,每个工具的 prepare → execute → finalize 完成后才开始下一个。适用于有副作用的操作(如文件编辑),避免竞态条件。

内置工具,pi-coding-agent 提供 7 个核心工具(core/tools/index.ts):

工具功能
read读取文件,支持分页、截断、图片渲染
bash执行 shell 命令,支持超时、stdin、后台运行
edit基于精确字符串替换的文件编辑
write创建或覆写文件
grep基于 ripgrep 的内容搜索
find基于 fd 的文件搜索
ls列出目录内容

工具分两组:createCodingTools(read + bash + edit + write,完整读写权限)和 createReadOnlyTools(read + grep + find + ls,只读)。用户可以通过 --no-tools--tools 控制启用的工具。

扩展工具,Extension 系统允许第三方通过 extensions 目录注册自定义工具。Extension 用 TypeScript/JavaScript 编写,可注册:自定义 tool(带 schema 和 execute 函数)、自定义 slash command、自定义 CLI flag。Extension 之间如果有命名冲突,以 load order 先到先得,冲突会报告为诊断警告但不阻止加载。

如何构建 system prompt,并调用 LLM API?

System Prompt 的构建过程

System Prompt 在 core/system-prompt.tsbuildSystemPrompt() 中构建,支持两种模式:

  1. 自定义 Prompt 模式(用户通过 --system-prompt.pi/SYSTEM.md 指定):以用户提供的 prompt 为基础,追加:project context files(AGENTS.md/CLAUDE.md 从根目录到当前目录的所有文件)→ skills 列表(仅元数据,不加载完整内容)→ 日期和当前工作目录
  2. 默认 Prompt 模式:pi 内置了一套完整的默认 prompt,包括:

    • 角色设定:「你是一个运行在 pi coding agent harness 里的专家编程助手」
    • 工具列表和一句话描述
    • 使用指南:优先用 grep/find/ls 而不是 bash 做文件探索、保持简洁、标注文件路径
    • 项目上下文(AGENTS.md/CLAUDE.md)
    • Skills 元数据(<available_skills> XML 块,符合 agentskills.io 规范)
    • 日期和工作目录

Skills 的完整内容不在 system prompt 里,system prompt 只放 skills 的 name、description、filePath(以 XML 格式嵌入)。LLM 判断任务匹配某个 skill 时,调用 read 工具读取 SKILL.md 获取完整指令。这样 system prompt 不会膨胀,skills 在需要时又能拿到。

LLM API 调用过程,实际调用 LLM API 的链路:

AgentHarness.createStreamFn() → 闭包包装
  ↓ 每次调用前
动态获取 API key(处理 OAuth token 过期)
  ↓ 触发钩子
emitHook("before_provider_request") → 扩展可以修改 stream options(headers、timeout 等)
  ↓
streamSimple(model, context, options) → pi-ai 层的统一接口
  ↓ 触发钩子
emitHook("before_provider_payload") → 扩展可以修改请求 payload
  ↓ 发送 HTTP 请求
收到响应 → emit("after_provider_response")
  ↓ 返回 EventStream<AgentEvent>
AgentLoop 消费 stream 事件,更新 state

几个要点:

  • 每次 LLM 调用前重新获取 API key,支撑短生命周期的 OAuth token
  • convertToLlm 负责将内部 AgentMessage 转换为 LLM 兼容的 Message 格式(过滤 custom message、notification 等内部消息类型)
  • transformContextconvertToLlm 之前运行,可用于上下文裁剪(pruning)
  • 通过 before_provider_requestbefore_provider_payload 钩子,Extension 可以在请求发送前修改参数

pi-coding-agent

主要问题:

  • 如何加载 harness 相关的内容?
  • 如何管理记忆(状态)?
  • 如何管理 skills 和按需加载?
  • 如何调用工具?
  • 如何构建 system prompt,并调用 LLM API?
session 设计

https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/session.md

pi 的 Session 设计:

Session = 一个有树状结构的持久化对话记录。 不是线性聊天记录,而是一棵树,每个节点有 idparentId,天然支持 fork、分支、回退。

存储格式,JSONL 文件(session-manager.ts)。每个 Entry 是一行 JSON,类型包括:

Entry 类型说明
message用户/助手/工具结果消息
thinking_level_change用户切换思考级别
model_change用户切换模型
compaction上下文压缩记录
branch_summary分支切换时的摘要
customExtension 的自定义持久化数据
custom_messageExtension 注入上下文的自定义消息
label节点标签(用户命名分支)
session_infoSession 名称

树状结构带来的能力:

  • Fork,用户回到对话的任意节点,分叉一个新的对话方向。实现方式是复制 session 文件,parentId 指向 fork 点的 entry
  • Branch navigation,用户跳转到树中任意节点。目标节点不在当前分支时,系统生成 branch_summary(调 LLM 总结两个分支间的差异),然后 moveTo 到目标节点
  • Compaction,上下文过大时,系统将旧对话发给 LLM 做摘要,生成 compaction entry,保留摘要 + 最近 N 条消息,释放 context window 空间

SessionManagercore/session-manager.ts)封装了对 Session 文件的 CRUD 操作:

  • create(cwd) — 创建新 session
  • open(path) — 打开已有 session
  • forkFrom(sourcePath, cwd) — fork 一个 session
  • list(cwd) — 列出项目中的所有 session
  • continueRecent(cwd) — 恢复最近的 session
  • buildSessionContext() — 重建当前分支的上下文(从 leaf 走到 root)

buildSessionContext() 的逻辑:从当前 leaf 节点出发,沿着 parentId 链走到 root。如果路径上有 compaction entry,只保留 compaction 之后的消息。如果路径上有 branch_summary entry,将其作为上下文注入。最终返回一个 AgentMessage[],可以直接喂给 Agent。

如何加载 harness 相关的内容?

how pi-agent-core load harness related content? "pi-agent-core is a dumb executor. All harness-specific content (project context, AGENTS.md, skills, tool definitions) is resolved by the coding-agent's ResourceLoader and AgentSession, then injected into the agent as plain strings and tool objects. "

coding-agent 相关的代码,如何加载 harness 相关内容:

  • Resource Loading (src/core/resource-loader.ts):
  • System Prompt Assembly (src/core/system-prompt.ts):
  • AgentSession (src/core/agent-session.ts):

ResourceLoader(core/resource-loader.ts)是 harness 内容加载的中心,它的 reload() 方法按以下顺序加载所有内容:

1. 设置加载SettingsManager.reload() 加载全局设置(~/.pi/agent/settings.json)和项目设置(.pi/settings.json),合并优先级。

2. 资源路径解析PackageManager.resolve() 从多个来源收集资源路径:

  • 自动目录扫描:~/.pi/agent/skills/.pi/skills/.agents/skills/(从 cwd 向上到文件系统根目录)
  • settings.json 中的配置
  • Package 声明(npm 包中的 pi.skills 字段)
  • CLI 参数:--skill--extension
  • 每个路径标记了来源(source)和作用域(scope:user/project/temporary)

3. Extensions 加载loadExtensions(extensionPaths) 加载并初始化所有扩展。Extension 编译为 JS 模块运行在受限 runtime 中,可以注册 tools、commands、flags。

4. Skills 发现loadSkills() 扫描 skill 目录,解析 SKILL.md 文件(提取 frontmatter 中的 name、description、disable-model-invocation),只加载元数据,不加载完整内容。

5. Prompt Templates 加载loadPromptTemplates() 类似逻辑,解析 prompt template 文件。

6. Themes 加载loadThemeFromPath() 加载主题 JSON 文件。

7. Context Files 加载loadProjectContextFiles() 从三个位置读取:

  • ~/.pi/agent/ 下的 AGENTS.md 或 CLAUDE.md(全局级别)
  • cwd 向上到根目录的每个目录中的 AGENTS.md 或 CLAUDE.md(项目级别)
  • 离 cwd 越近的文件越排在后面(优先级越高,后加载覆盖前加载)

8. System Prompt 文件发现.pi/SYSTEM.md(项目级别)或 ~/.pi/agent/SYSTEM.md(全局级别)

9. Append System Prompt 文件发现.pi/APPEND_SYSTEM.md(项目级别)或 ~/.pi/agent/APPEND_SYSTEM.md(全局级别)

配置有什么?如何加载?以下是 Github Copilot GPT5.4 给出的一个时序图(mermaid 格式):

sequenceDiagram
    autonumber    
    actor User    
    participant CLI as main.ts    
    participant Args as parseArgs()    
    participant Session as createSessionManager()    
    participant Runtime as createRuntime()    
    participant Services as createAgentSessionServices()    
    participant Loader as DefaultResourceLoader    
    participant Settings as SettingsManager    
    participant Models as ModelRegistry    
    participant Agent as createAgentSessionFromServices()    
    participant SessionObj as AgentSession    
    participant Prompt as buildSystemPrompt()    
    participant Mode as Interactive/Print/RPC    
    participant LLM as Model Provider          
  
    User->>CLI: Start coding-agent CLI    
    CLI->>Args: parse args    
    Args-->>CLI: parsed flags, messages, resource options          
  
    alt early command
        CLI->>CLI: handlePackageCommand() / handleConfigCommand()
        CLI-->>User: exit early
    else normal startup
        CLI->>CLI: resolve app mode
        CLI->>CLI: run migrations
        CLI->>Settings: create startup settings manager
        CLI->>Session: createSessionManager(parsed, cwd, sessionDir)
        Session-->>CLI: SessionManager for effective session cwd
    
        CLI->>Runtime: createAgentSessionRuntime(createRuntime, { cwd, agentDir, sessionManager })    
        Runtime->>Services: createAgentSessionServices({ cwd, agentDir, authStorage, resourceLoaderOptions })
    
        Services->>Settings: create(cwd, agentDir)    
        Services->>Models: create(authStorage, models.json)    
        Services->>Loader: new DefaultResourceLoader({ cwd, agentDir, settingsManager, ...resourceLoaderOptions })
        Services->>Loader: reload()    
    
        Loader->>Loader: resolve extensions, skills, prompts, themes    
        Loader->>Loader: load AGENTS.md / CLAUDE.md from cwd ancestors
        Loader->>Loader: discover .pi/SYSTEM.md or agent SYSTEM.md
        Loader->>Loader: discover .pi/APPEND_SYSTEM.md or agent APPEND_SYSTEM.md
        Loader-->>Services: loaded resources + context files + prompt sources
    
        Services->>Models: register providers from extensions    
        Services-->>Runtime: services + diagnostics
    
        Runtime->>Runtime: resolve scoped models
        Runtime->>Runtime: build session options from CLI + settings + scope    
        Runtime->>Agent: createAgentSessionFromServices({ services, sessionManager, model, thinkingLevel, tools })
    
        Agent->>SessionObj: create AgentSession
        SessionObj->>Loader: getSystemPrompt()
        SessionObj->>Loader: getAppendSystemPrompt()
        SessionObj->>Loader: getSkills()
        SessionObj->>Loader: getAgentsFiles()    
        SessionObj->>Prompt: buildSystemPrompt({ customPrompt, appendSystemPrompt, skills, contextFiles, tools })    
        Prompt-->>SessionObj: final system prompt
    
        Agent-->>Runtime: session + modelFallbackMessage    
        Runtime-->>CLI: runtime
    
        CLI->>CLI: read piped stdin if not RPC    
        CLI->>CLI: prepareInitialMessage()    
        CLI->>CLI: initTheme()    
        CLI->>CLI: report diagnostics
    
        alt interactive mode    
            CLI->>Mode: new InteractiveMode(runtime, initial input)    
            Mode->>SessionObj: run()    
        else print/json mode    
            CLI->>Mode: runPrintMode(runtime, initial input)    
            Mode->>SessionObj: prompt(initial message)    
        else rpc mode    
            CLI->>Mode: runRpcMode(runtime)    
        end          
    
        SessionObj->>Loader: prompt templates available for /template expansion    
        SessionObj->>SessionObj: expand /skill and /template commands    
        SessionObj->>LLM: send messages with current system prompt    
        LLM-->>SessionObj: response/events    
        SessionObj-->>User: output in selected mode    
    end
如何管理记忆(memory)?

什么是记忆(memory)?为什么需要?

  • 记忆(memory):持久态,可以重新加载的上下文,跨 session

什么是 session?为什么需要?

  • 一次会话(conversation)的历史记录
A session in pi is the durable record of one agent conversation, including its tree structure, not just the current in-memory turn state.

Concretely, sessions are stored as JSONL files and each entry has an id and parentId, so pi can preserve branches, rewinds, forks, compactions, model changes, and message history over time. That is described in pi-mono/packages/coding-agent/README.md and implemented in pi-mono/packages/coding-agent/src/core/session-manager.ts.

pi 的 Memory 管理几个关键设计:

1. 树状结构而非线性历史

普通聊天应用是线性的(一条消息接一条消息),pi 用树状结构管理对话,每条 entry 有 idparentId。这带来的能力:

  • Fork,回到某个节点,从那里开始新的对话方向。底层是复制 JSONL 文件,设置新的 parentId
  • Branch navigation,用户在 TUI 中浏览对话树,跳转到任意节点。切换分支时自动生成 branch_summary,让 LLM 知道上下文发生了什么变化
  • Rewind,回到之前的某个点,丢弃之后的内容(本质上是切换到那个节点的分支)

2. Compaction(上下文压缩)

对话历史太长、超出模型的 context window 时,pi 自动触发 compaction:

  • prepareCompaction() 分析当前分支的 entries,算出哪些消息可以摘要、哪些必须保留(保留最近 N tokens,剩余发给 LLM 做摘要)
  • compact() 调用 LLM 生成摘要
  • 生成 compaction entry(包含 summary + firstKeptEntryId + tokensBefore),追加到 session
  • buildSessionContext() 重建时,遇到 compaction entry 从摘要开始,只加载 firstKeptEntryId 之后的消息
  • Compaction 也支持 hooks:session_before_compact / session_compact,Extension 可以干预摘要过程

compaction entry 像是对话树中的「压缩节点」,重建时自动解压,摘要本身可以被后续 compaction 再次摘要(递归压缩)。

3. Custom entries 支持 Extension 持久化

Extension 可以向 session 写入两种自定义数据:

  • custom entry,持久化 Extension 的私有状态(如文件编辑历史),不发送给 LLM
  • custom_message entry,持久化并注入 LLM 上下文(如外部系统的事件通知)

Agent 运行期间,pendingSessionWrites 缓存写入,turn 结束时批量刷入,不用每次 event 都触发磁盘 I/O。

借助 Github Copilot GPT5.4 给出的时序图(mermaid 格式)如下,概括来说:

sequenceDiagram
    autonumber
    actor User
    participant UI as Interactive/Print/RPC Mode
    participant Session as AgentSession
    participant Manager as SessionManager
    participant Store as Session JSONL File
    participant Builder as buildSessionContext()
    participant Compress as Compaction / Branch Summarization
    participant Msg as convertToLlm()
    participant LLM as Model Provider
    participant Ext as Extensions

    User->>UI: Send prompt
    UI->>Session: prompt(text, options)

    Session->>Session: expand /skill and /template
    Session->>Session: flush pending bash messages
    Session->>Session: inject pending next-turn messages

    opt extension pre-processing
        Session->>Ext: emitBeforeAgentStart(text, images, baseSystemPrompt)
        Ext-->>Session: extra custom messages and/or prompt override
    end

    Session->>LLM: agent.prompt(messages, systemPrompt)
    LLM-->>Session: assistant response / tool calls / usage

    Session->>Manager: appendMessage(user)
    Session->>Manager: appendMessage(assistant/tool/custom)
    Manager->>Store: append JSONL entries

    Note over Manager,Builder: Persistent memory is append-only session history

    opt session reload / startup / branch switch
        Session->>Manager: buildSessionContext()
        Manager->>Builder: rebuild current branch path
        Builder->>Builder: walk leaf to root
        Builder->>Builder: resolve model + thinking level

        alt compaction entry exists on path
            Builder->>Builder: emit compaction summary first
            Builder->>Builder: keep messages from firstKeptEntryId onward
            Builder->>Builder: append post-compaction messages
        else no compaction
            Builder->>Builder: emit full branch messages
        end

        Builder-->>Session: reconstructed AgentMessage[]
        Session->>Session: agent.state.messages = reconstructed messages
    end

    opt extension state persistence
        Ext->>Manager: appendCustomEntry(customType, data)
        Note over Manager,Store: Stored for extension restore only, not sent to LLM
    end

    opt extension context injection
        Ext->>Manager: appendCustomMessageEntry(customType, content, display)
        Note over Manager,Builder: Rebuilt as custom messages and included in LLM context
    end

    opt branch navigation
        Session->>Compress: generateBranchSummary(old branch)
        Compress-->>Manager: branch_summary entry
        Manager->>Store: append branch_summary
        Note over Builder: branch_summary becomes a synthetic user-context message
    end

    opt context grows too large
        Session->>Session: check compaction threshold / overflow
        Session->>Compress: compact(branch entries)
        Compress->>Msg: convertToLlm(messages selected for summary)
        Msg-->>Compress: LLM-compatible summary input
        Compress->>LLM: summarize older context
        LLM-->>Compress: summary text
        Compress-->>Manager: appendCompaction(summary, firstKeptEntryId, tokensBefore)
        Manager->>Store: append compaction entry
        Session->>Manager: buildSessionContext()
        Manager->>Builder: rebuild compacted context
        Builder-->>Session: summary + kept messages + newer messages
    end

    Note over Msg,LLM: Messages sent to the model are transformed view-memory, not raw session entries

    Session->>Msg: convertToLlm(agent.state.messages)
    Msg->>LLM: final model input for next turn
    LLM-->>User: next response
如何管理 skills 和按需加载?

这个问题是第一个如何加载 harness 相关内容相关,是不是可以放入一起?

How skills are managed?

At startup, it discovers skills from multiple sources:

  • Global dirs: ~/.pi/agent/skills/, ~/.agents/skills/
  • Project dirs: .pi/skills/, .agents/skills/ (cwd up to repo/filesystem root)
  • Packages: skills/ folders or pi.skills in package package.json
  • settings.json: skills array paths
  • CLI: --skill (repeatable)

Control flags/settings:

  • --no-skills disables auto discovery
  • --skill ... still adds explicitly even with --no-skills
  • enableSkillCommands controls /skill:name commands
  • /reload refreshes discovered skills during a session

How skills are loaded "as required"

  1. On startup, pi reads only each skill's metadata (name, description).
  2. It puts the available skill list into the system prompt (XML per Agent Skills spec).
  3. During a task, if a skill matches, the model should call read on that skill's SKILL.md.
  4. Full skill instructions are then used only for that task.

So: descriptions are always in context; full skill content is loaded on demand.

Forcing load when needed

  • Use /skill: to explicitly load and run it.
  • You can pass args: /skill:pdf-tools extract
    (args are appended as User: to the skill input).
  • If a skill has disable-model-invocation: true, it is hidden from auto-selection and must be invoked via /skill:name.

Skills 系统设计的几个原则:

1. 元数据在 prompt 里,完整内容按需加载

每个 skill 是一个目录,包含 SKILL.md(或其他 .md 文件)。SKILL.md 的 YAML frontmatter 定义 namedescriptiondisable-model-invocationloadSkills()harness/skills.ts)只解析 frontmatter 和 body,构造 { name, description, content, filePath } 对象。只有 namedescription 进入 system prompt(格式化为 <available_skills> XML 块,符合 agentskills.io 规范)。

LLM 看到 skill 的描述,判断是否匹配当前任务,匹配就调用 read 工具读取 SKILL.md 的完整路径。system prompt 不会因为大量 skills 而膨胀。

2. 多来源加载与优先级

Skills 来源发现由 PackageManager.resolve() 统一处理。自动发现的目录(.pi/skills/.agents/skills/)、settings.json 配置、npm package 声明、CLI 参数——这些路径被合并、去重,按优先级排序。每个 skill 标记了 sourceInfo,记录来源(sourcescopeorigin),用于调试和诊断。

3. Ignore 文件支持

Skill 目录支持 .gitignore.ignore.fdignore 规则,遍历时自动跳过被 ignore 的文件和目录。实验性的 skills 可以放在被 gitignore 的目录中,仍然会被加载。

4. 显式调用 Skills

用户可以通过 /skill:name args 显式调用 skill,系统把 skill 内容包装在 <skill> XML 标签中,作为 user message 发送。如果 skill 设置了 disable-model-invocation: true,它不会出现在 <available_skills> 中,只能通过 /skill:name 显式调用——适合危险操作或实验性功能。

5. Agent Skills 规范

pi 的 skills 格式遵循 agentskills.io 规范。Skill 文件的 frontmatter 验证规则:

  • name:必须匹配父目录名,小写字母+数字+连字符,不超过 64 字符
  • description:必填,不超过 1024 字符
  • disable-model-invocation:可选布尔值
   sequenceDiagram                                                                                                  
       autonumber                                                                                                   
       actor U as User                                                                                              
       participant CLI as CLI Parser (args.ts)                                                                      
       participant Main as main.ts                                                                                  
       participant SM as SettingsManager                                                                            
       participant PM as DefaultPackageManager                                                                      
       participant RL as DefaultResourceLoader                                                                      
       participant SK as skills.ts (loadSkills)                                                                     
       participant FS as Filesystem                                                                                 
       participant AS as AgentSession                                                                               
       participant SP as system-prompt.ts                                                                           
       participant LLM as Model                                                                                     
       participant RT as read tool  
       
       U->>CLI: pi [--skill ...] [--no-skills]                                                                      
       CLI-->>Main: parsed.skills, parsed.noSkills                                                                  
       Main->>RL: create with additionalSkillPaths + noSkills                                                       
       RL->>SM: reload settings (global + project)                                                                  
       RL->>PM: resolve resources (auto dirs + settings + packages + CLI)                                         
       PM->>FS: scan ~/.pi/agent/skills, ~/.agents/skills                                                           
       PM->>FS: scan .pi/skills + ancestor .agents/skills                                                           
       PM-->>RL: resolved skill paths (with precedence/enabled flags)                                             
       
       RL->>SK: loadSkills({skillPaths, includeDefaults:false})                                                     
       SK->>FS: read SKILL.md / root .md per discovery rules                                                        
       SK-->>RL: skills[] + diagnostics                                                                             
       RL-->>AS: resourceLoader.getSkills()                                                                         
    
       AS->>SP: buildSystemPrompt({skills,...})
       SP-->>AS: prompt + <available_skills> metadata (if read tool enabled)
       AS->>LLM: send system prompt + user message                                                                  
    
       alt Auto skill load (on-demand)                                                                              
           LLM->>RT: read(<skill location from available_skills>)                                                   
           RT->>FS: read SKILL.md                                                                                   
           FS-->>RT: full skill content                                                                             
           RT-->>LLM: skill instructions                                                                            
           LLM->>AS: continue task using skill guidance                                                             
       else Explicit command (/skill:name args)                                                                     
           U->>AS: /skill:name args                                                                                 
           AS->>FS: read SKILL.md (expand command)                                                                  
           FS-->>AS: file content                                                                                   
           AS->>AS: strip frontmatter, wrap <skill ...>, append args                                                
           AS->>LLM: send expanded skill block as user message                                                   
       end                                                                                                          

Bub

(待补充:分析 Bub 的 Agent 实现,特别是 tape 系统和 Telegram 集成)

Claude Code

(待补充:分析 Claude Code 的 harness 设计,参考 ccunpacked.dev 和 ZaynHao 的文章)

对于目前技术方向,自己的理解和一点思考

分析完 pi-mono 的实现,对「如何开发一个 Agent」有了更具体的认识:

1. Agent 的核心是 Loop + Context,不是模型

注意力容易放在「用什么模型」上,但 Agent 的工程挑战在模型之外。模型只是 loop 中的一个环节——输入消息,输出响应。真正的复杂度在:上下文怎么不爆炸(compaction)、对话中怎么注入正确的信息(system prompt + AGENTS.md + skills 按需加载)、工具调用失败怎么降级、对话状态怎么持久化和恢复。

pi-mono 花了大量代码在 session 管理、compaction、resource loading 上——这些才是 Agent 的骨架。模型升级了换配置就行,基础设施设计不好,后面改起来很痛。

2. 分层设计让 Agent 可扩展

pi-mono 的 core / harness / cli 三层分离是精心设计的。Agent core 不包含任何「产品」逻辑,只提供运行 Agent 的运行时。产品相关的决策(加载什么资源、提供什么工具、构建什么 system prompt)都在 harness 层。基于同一个 core 可以做 coding agent、客服 agent、数据分析 agent——换 harness 层就行。

3. Session 的树状结构是 Agent 的「时间旅行」

普通聊天应用的线性历史在 Agent 的多轮协作场景下不够用。用户可能想回到之前的某个决策点,换个方向。pi 的树状 session + fork + branch summary 解决了这个问题。特别是 branch summary,不是机械拼接历史消息,而是让 LLM 总结两个分支的差异,切换分支后模型能快速理解上下文变化。

4. Skills 的按需加载是上下文管理的典型做法

把 skills 的元数据放在 system prompt 里,完整内容通过 read 工具按需加载——它把「告诉模型有什么能力」和「告诉模型怎么用这个能力」分开了。元数据始终在上下文(成本低),完整指令只在相关任务时加载(按需付费)。

5. Extension 系统让 Agent 从「工具」变成「平台」

pi 的 extension 系统支持注册自定义工具、命令、flag,通过 hooks(before_agent_startbefore_provider_requesttool_calltool_result 等)介入 Agent 各环节。这让 pi 从「一个 coding agent 工具」变成了「一个可以构建各种 Agent 应用的平台」。

什么是未来

阅读 pi-mono 的代码,同时参考 Mitchel Hashimoto 的 My AI Adoption Journey 和 Anthropic 的 Harness design for long-running application development,对 Agent 的未来方向有几条判断:

1. Harness Engineering 会成为独立领域

模型能力在快速提升,但 Agent 的 harness(系统提示词、上下文管理、工具设计、session 管理、扩展系统)才决定实际使用体验。Harness Engineering 会像 DevOps、SRE 一样,逐渐成为一个被认可的工程方向。

2. Agent 的「记忆」会越来越重要

目前的 Agent 记忆主要靠「把历史消息塞进 context window」。随着 Agent 处理越来越长期的任务(跨天、跨周的项目开发),需要更智能的记忆机制——不只是 compaction,而是结构化的知识提取、任务状态追踪、决策理由记录。pi 的树状 session + custom entries 是这个方向的早期探索。

3. Multi-Agent 协作

pi-mono 目前是单 Agent 架构,但它还有一个 pi-pods 包没有深入分析,可能跟多 Agent 相关。未来多个 Agent 各司其职(一个写代码、一个 review、一个测试),通过结构化通信协议协作——这个方向值得关注。

4. Agent 的「操作系统化」

Claude Code 被描述为「运行在终端里的 AI 操作系统」。Agent 不再只是「对话机器人」,而是一个协调工具、管理状态、持久化记忆、执行后台任务的操作系统级抽象。shell 是它的内核,tools 是它的驱动,skills 是它的应用。

自己开发一个 Agent,需要如何做

基于对 pi-mono 的分析,自己开发一个 Coding Agent,可以按这个顺序来:

第一步:跑通最小 loop,对接一个 LLM API(Anthropic / OpenAI 或兼容接口),实现基本的 prompt → response → display 流程。这是「Hello World」,验证你能和模型对话。

第二步:加入工具调用,先加一个最简单的工具(read 读文件),实现 tool call 的解析、执行、结果回传,验证 LLM 能正确使用工具。然后逐步加更多工具(basheditwrite)。

第三步:上下文管理,实现对话历史的管理(线性数组开始就行),上下文压缩(messages 太多时,取最近 N 条 + 对旧消息做摘要),加载项目上下文(读取 AGENTS.md 或类似的项目说明文件)。

第四步:System Prompt 设计,角色设定、工具使用指南、项目上下文,持续迭代调优。这是最需要「手感」的部分。

第五步:Session 持久化,保存对话历史到文件(JSONL 是个好选择),支持恢复历史会话,fork 可选但很有用。

第六步:Skills 系统,支持加载外部 skill 文件,元数据进 system prompt,完整内容按需加载,支持 /skill:name 显式调用。

第七步:TUI / 交互体验,命令行交互界面、流式显示 AI 输出、工具调用的可视化反馈。

核心思路:先让 Agent 能跑起来,哪怕只有最基础的功能,然后基于实际使用逐步迭代。 不要一开始就设计复杂架构——pi-mono 的架构也是迭代出来的(commit 历史可以作证)。

参考

关于共通的一些话题

关于 pi-mono

关于 Bub

关于 Harness

分析 Claude Code 的代码

关于 ironcode - codedump

  • "为了学习如何实现一个Agent,我用Rust照着Python实现的kimi-cli在写一个coding agent,名字叫ironcode,目前还比较粗糙,后面如果能做到:用ironcode的agent来编码ironcode自身就有意思了。项目地址:https://github.com/lichuang/ironcode"

关于 Agent 学习的一些参考

还是和上周一样,多想多写多做,而不是一直的消化吸收他人的,本周博客上改成每周小结的标题,另外加投资方面的小结。

本周观影

  • 《风味人间第一季 2 落地生根:石子馍/馕饼,法式面包,枕头馍,羊肉泡馍,酿皮,包子,伊朗和中国;生鱼片,中日;马来西亚中国的传统,秘鲁利马的中餐;澳门,葡菜;浙江龙泉祈福,种田杀猪包粽祭祀,想不到浙江还有保持这种传统的地方,我老家是没有了。
  • 《盗火线》:95 年老片,情节我觉得一般,但有罗伯特德尼罗啊,能看看。

本周阅读

本周读书时间少了(晚上没看 Kindle 有关系,另外一方面也要留出来时间来读,不然就是有一搭没一搭),不过和自己交流的时间多了,写下了不少。

  • 《金融怪杰》
  • 《笑傲股市》

本周播客

发现一个新的播客《跨国串门儿计划》,X 上看人推荐的一期(#533. Anthropic如何运营一个 AI 原生工程组织),其他的内容也看了看,貌似挺好,后续我会挑更多一些看一下。

https://x.com/ZaynHao/status/2054714515854606632,也有视频版本(参考 https://x.com/ZaynHao/status/2054742909875019828

强烈推荐这期播客,这是最近听到的非常实用,信息不拖沓的 Claude Code (Anthropic)团队是如何运营组织,如何工作的分享。
非常适合身处或正在管理构建 AI Agent 产品的团队朋友听。
里面有很详实的故事来讲述他们团队的分工,大家的做事方式,以及变化等。
很实用。

提出针对个人投资者的具体、可执行的建议:

  1. 核心工具:推荐通过构建低成本、分散化的ETF组合(如A股、美股、黄金ETF)进行投资,这是“节流”的最佳方式。
  2. 关键心态:投资的最终收益取决于敢下多大的仓位并长期持有。构想一个让你买了之后“敢忘记账户密码”放一年的组合,就是好组合。
  3. 自我修炼:坚持每日记录与复盘,成功的模式难以复制,但降低重复犯错的频率就是最大的进步。

本身这个行业,也许我不会关注,但是嘉宾刘重杰(招商基金基金经理)对于行业的思考以及基金经理的思考框架是我可以学习的;其中一点,出海的企业,当地偏好、习惯、行业标准等有磨合过程,但是一定会出去,中国的产业链,有海外营收的有竞争力的,目前还是少数,管理层很勤奋,更广的市场,出海的利润是不是留在国内了,如果有这个情况,是个值得关注的信号。

必选消费和可选消费,分析框架应该完全不一样。 猪肉是刚需标准品,价格再便宜你也不能多吃多少,价格再贵也得买,所以供给的波动才是价格剧烈波动的根本;白酒则不同,剔除高端商务场景之后,它的需求对价格是有弹性的。这两个行业,受经济环境的影响机制,从根本上就不是一回事。他还提出了一个有点“扎心”的判断:食品饮料在GDP中的占比,会缓慢而坚定地下降——这恰恰是一个经济体走向成熟的标志。但这不意味着食品饮料没有投资机会。生意只有这么大规模,不代表这家公司没有利润。而个股层面,他认为:那些已经在布局出海的管理层,是他最愿意关注的信号。

本周胡思乱想

  • 最近又在做减法,信息流、自己的消耗。
  • 关于 AI/LLM 的各种考虑:

    • 这几天我在看如何更好组织 AI 时代的代码结构,有些是有共识的,但是 .harness 这样好像也没啥共识。
    • AGENTS.md 是有共识,要有 rules/changes 类似结构的共识,项目级别共享 skills 这个也不一定有共识;AGENTS.md 是个标准了,README.md 是给人看的,AGENTS.md 是给 AI 看的;.harness 下面解决的就是对 agent 的纠偏,团队层面可以设置一套通用的规范体系。
    • Skills 我是觉得也许还不如在项目方便共享,但是从企业开发来说,要解决的是团队层面的共享和不断迭代更新;global skills + local skills 也许对于企业来说是个更好的选择。
    • 人为的因素要通过自动化的过程和技术把影响降下来,我现在有点理解过去人说的,harness 其实就是约束。
    • AI 代码,其实现在有个趋势都是朝 mono code repo 靠,是有道理的,AI 可以足够的了解到整个开发的细节,远比人强,因为上下文足够的大了。
    • AI native 时代,AI builder 是个更合适的路径。
    • 我今天其实和不同人都聊了不少东西,核心的一点,就现在我们的工具体系和组织流程,AI 只是给我们提效,而不是本质上的一个转变,当然能做到提效也够了,但是提效的前提也是工具体系和组织流程和人的角色的变更。
    • https://github.com/Ar9av/obsidian-wiki :看这种项目的 skills 组织,以及 AGENTS/CLAUDE md 的关系(CLAUDE 指向 AGENTS),项目组织就很通用,在各家之间可以灵活切换。
  • 昨晚没睡好,一方面是睡前聊的太多了,到此为止,不再试着去想着“教育”他人,更多应该只是分享我自己的分享。
  • 继续寻找其他可能性,不要停止,不要温水煮青蛙。
  • 折腾的一周,无聊的工作,同时不要把这样的信息传递给他人,我不是他人的天使或地狱,我只是我自己,不要放弃其他的可能。
  • 学业上,如何可以更好帮助孩子,我没答案也没实际能做的,这个时间节点上我感觉自己能做的很少,但是我一直记着要尝试着做点什么,也许润物细无声应该是常态。

本周投资

  • 重新梳理了一下投资的分层思考和结构,分为适合我自己的三层:

    • 不动和追求 alpha 仓:长期持有,如果没有其他合适的,不考虑卖出;
    • 股息和追求 beta 仓:现金流不求高收益;
    • 试水仓:尝试提升我自己的交易策略和能力,同时结合行业轮动进行买卖,期望博取一些更多的机会;操作来说,控制在 10% 左右的仓位,需要考虑何时卖出:20% 跌幅卖出,2 个月内不动卖出,涨幅过 20%卖出或归入第一层去等等。
  • 买入 DRAM 存储方面的试水仓,极度拥挤,目前是负收益,回过头看想象存储还是会继续往上的,但也许是周期性的;NOW 是上月买入的,目前也还是负收益,但是本周有起伏,从过去财报来说其“当前未履约合同金额(cRPO)”还是可以的,但未来需要看看重 SaaS 企业的 token 收入(看同事分享的 Datadog 上的 AI 能力,可以说是突飞猛进),持续观察。
  • A 股方面没有任何操作,我把美的加入了观察名单,也看过一段时间的中远海控,但还是放弃了,看不懂;从上面说的三层仓位来说,还远远没完成构建,还在第一层和第二层的构建中,第三层在 A 股方向上我是犹豫的,感觉做不好。
  • 基金方面,我部分放弃了了美债(国债加美元企业债)方面的投入(美元持续走弱,汇率方面的损失导致了收益持续下滑),暂时考虑买入同公司的全球科技方向上去,但当下时间节点也许是错的,太拥挤了,这两个月虽然收益很好,但是今年全年看未必,怕会有巨大的回撤。

本周文章

创作、交易与精神独立

十分认同博主的观点,为自己而写作,而不是通过写作想博取什么,也正好看到了这篇 about writing,也摘录了很多观点,关于为什么要写,核心一点还是为了提升自己,梳理自己逻辑和思路,和自己对话。

当你不再把博客当成一项任务,不再向外寻求认同,那么「难」这个字也就不存在了。因为这时候,你已经不是在为了满足谁的「消费欲望」而写作,你只是在完成一次与自己的对话。

更多参考:为什么要写周记

AI 上游投资机会分类学

看到有人分享的,署名是"作者:GPT 5.5 Pro" AI 分析的真好啊,结合"存储投资综述"这个材料看,理解的更好(存储投资综述这个材料真好,理解存储为什么这么短缺以及上下游的产业链);回顾在这方面的投资看,没踏好这一波的浪潮,第一类的从光到存储的方面的热点,是不是能踏上文中说的第二类收益的机会,需要自己好好的研究。

I returned to AWS - and was reminded HARD why I left.

对我不需要弃用选其他,也不是说 AWS 不行,是通过这种文章可以有个更多的了解,对于 AWS 服务的利弊,以及业界的一些讨论,如:DynamoDB 贵,出的流量贵,IAM 复杂,Lambda 的问题,以及对于开源生态的影响等等;相关 Hacker News 上的 thread(对于上面文章的讨论):https://news.ycombinator.com/item?id=48073201,还是讨论的很热烈,特别是对于 open source 的利用。

Notes from inside China's AI labs

一个外人的视角看中国的 AI 情况,还是比较正面的,对于国内这些个公司的他真的是个外部人的视角,几家头部的情况有时候不一定如他说的那么好,DeepSeek 可能反而的确是个“异类”,和互联网的那几家是有些区别(其实这个结论我一个外人也是瞎说);我们需要全球化的合作和走出去,这种对于中国的 AI 或整个技术社区的情况一个叙述,无论怎么看都是利于我们的。

LanceDB 选型指南:它为什么这么火,以及你的项目是否该用它

多模态时代,Lance/LanceDB 在整个生态里面还是值得看一看,这个文章也分析的很清楚,利弊和适用的场景。

Lance 格式是一种列式存储格式,针对多模态 AI 数据做了优化,2022 年 7 月创建。它的技术亮点独立于 LanceDB 数据库存在。
LanceDB 数据库是构建在 Lance 格式之上的 embedded 数据库产品,2023 年 2 月创建,Apache 2.0 协议。开发体验和产品定位是独立于格式本身的工程和产品决策。