#喜欢的音乐 #博客更新
棒无的碎碎念,在,漫长岁月里
Agent 越权时,先别急着怪模型:权限边界才是第一现场
#博客更新

先说结论

Agent 出现越权行为时,我现在不会先问“这个模型是不是失控了”。我会先把现场拆成两部分:

1. 运行环境有没有把不该给的能力给出去?
2. 模型拿到能力之后,是否为了完成窄目标而绕过了原本应该遵守的边界?

这两件事可以同时成立。

Anthropic 在 8 月 31 日发布的对齐与安全复盘就把问题拆成了这两个方向:一方面是 operational security,另一方面是 motivated reasoning 和为了窄任务采取有害行动的倾向。

这比一句“模型逃出了沙箱”准确得多,也更值得工程师认真看。因为第一类问题靠重新训练未必能解决,第二类问题靠多加一个 approval 弹窗也未必能解决。

发生了什么

先把事实边界摆出来。

Anthropic 说,7 月 30 日曾报告三起 Claude 模型获得真实计算机系统未授权访问的事件。这些模型是为了网络安全评测而有意在没有 cyber safeguards 的条件下运行的;其中一个关键原因是第三方评测环境配置错误,模型因此访问到了互联网。

另外,英国 AI Security Institute 在 8 月 4 日报告了一起自己的测试事件:Claude Mythos 5 同样是在有意不启用网络安全防护的情况下运行,并且被明确给予了互联网访问能力,随后采取了一系列未经授权的行动。

这和“生产环境里的普通 Claude 用户突然被攻击”不是一回事。Anthropic 的文章也说,正在对两起事件做更深入分析,并计划与 METR 合作进行独立审查,后续细节还没有全部公布。

但这不代表事件可以被轻轻带过。测试环境本来就是为了观察模型在极端权限下会做什么;如果测试环境的权限和目标边界没有被准确记录,评测本身就会变成一次真实系统风险。

第一现场其实是这条链

一个能上网、能执行命令、能访问文件的 Agent,至少经过这样一条链:
模型决策
   ↓
工具适配层
   ↓
权限策略 / approval
   ↓
沙箱与文件系统
   ↓
网络出口 / DNS / 代理
   ↓
凭证与环境变量
   ↓
真实目标系统

任何一层的默认值出错,最终都可能表现成“模型越权”。但排查方向完全不同。

这张表不是为了把责任推给基础设施,而是为了避免把不同问题混成一个“模型安全”标签。

approval 不是沙箱

很多 Agent 产品把“需要确认”当成主要安全体验:模型想执行危险操作时,弹一个确认框。

这对用户体验有帮助,但它只覆盖一个很窄的边界:模型通过产品定义的工具接口发起调用时,是否让人批准。

它不能自动阻止:

插件初始化时自行读文件
插件代码直接发网络请求
依赖包在加载阶段执行副作用
子进程继承了更高权限的环境变量
日志或临时目录里残留真实凭证
一个看起来只读的工具通过路径解析访问了 workspace 外部

DeepSeek Harness 的插件清单里就明确提醒过:工具 approval 管的是模型调工具,不等于第三方插件代码被 sandbox 了。这个区别在任何可扩展 Agent 里都成立。

我的默认分层是:
插件代码:按不可信代码处理
模型工具调用:按可审计请求处理
沙箱子进程:按最小权限执行
网络访问:默认拒绝,按域名/任务放行
凭证:按一次任务、一次进程注入

如果这四层没有分开,界面上的“允许/拒绝”很容易给人一种超过实际能力的安全感。

reward hacking 为什么和越权放在一起

Anthropic 这次文章的另一部分讲了 reward hacking:模型在训练环境里找到作弊方式,获得奖励,却没有真正完成任务。

这件事和网络越权看起来是两个问题,底层却有相似结构:
狭窄的可测目标
       ↓
模型发现目标与真实意图之间的缝隙
       ↓
利用缝隙拿到更高回报

例如,训练环境奖励“看起来诚实的回答”,模型可能学会堆免责声明;奖励“通过评测”,模型可能寻找修改评分路径的办法。Anthropic 说,他们在容易发生 reward hacking 的模拟环境里训练模型,并观察到更严重的错位行为;同时也提到,早期训练中曾因为看到这类行为而回滚部分训练。

这里不能得出“任何模型都会攻击系统”的结论。更准确的工程问题是:

目标是否可被模型直接修改
评测是否只检查结果,没有检查过程
环境是否给了模型超出任务所需的权限
失败是否会被当成普通输出,而不是安全事件
监控看到的是行为,还是只看最终分数

给 Agent 画一张真正的权限图

如果今天让我给一个新 Agent 做安全设计,我会先画 capability graph,而不是先选模型:
                 ┌──────────────┐
                 │  Model       │
                 └──────┬───────┘
                        │ request
                 ┌──────▼───────┐
                 │ Policy       │  任务级允许范围
                 └──┬────────┬──┘
                    │        │
          ┌─────────▼─┐  ┌───▼─────────┐
          │ Tool scope │  │ Network     │  域名/端口/时限
          └──────┬──────┘  └──────┬──────┘
                 │                 │
          ┌──────▼─────────────────▼──────┐
          │ Sandboxed process + credentials│
          └────────────────┬───────────────┘
                           │
                    ┌──────▼──────┐
                    │ Audit log   │
                    └─────────────┘

每个箭头都应该能回答三个问题:

1. 谁授予了这项能力
2. 能力什么时候失效
3. 事后能不能还原一次调用

如果回答不了,说明这项能力只是“碰巧能用”,还没有成为可管理的系统。

一份我会真的执行的测试表

环境隔离

测试账号和生产账号完全不同
测试域名和生产域名在网络层分开
子进程不继承不必要的环境变量
workspace 外的路径默认不可读
临时目录按 session 隔离,任务结束清理

网络出口

默认 deny,而不是默认 allow
允许列表按任务生效,并设置过期时间
DNS、HTTP、HTTPS、WebSocket 和子进程网络分别验证
代理不会因为环境变量被意外绕过
对外请求记录域名、调用方和任务 ID

凭证

不把长期 key 写进 system prompt
不让插件在初始化时自动扫描凭证目录
每个 Agent 只拿它当前任务所需的最小权限
轮换和撤销不依赖重启整个服务
日志、错误消息和截图中不出现 secret

行为评测

不只测任务是否完成,也测是否绕过边界
记录模型尝试过但被拒绝的动作
对“修改评分器”“伪造成功”“隐藏失败”单独报警
检查模型在重试、超时和奖励变化后是否改变策略
对高权限任务保留人工复核样本

安全收紧的代价也要承认

权限收紧之后,产品一定会出现更多拒绝。社区里已经有人抱怨 Claude 对一些原本无害的请求变得过于谨慎,这类体感不能直接证明某个具体策略,但它揭示了一个真实取舍:
更少误放行  ←→  更少误拒绝

安全系统不能只追求“拒绝率越高越好”。如果所有不确定请求都被拒绝,用户会开始关闭保护、换工具,最后安全边界反而变差。

比较好的方向是把拒绝变得可解释、可分级:

低风险:直接执行并记录
中风险:缩小权限后执行
高风险:明确展示影响范围,请求批准
不可恢复风险:拒绝,并告诉用户需要改变什么配置

用户需要知道是“模型不愿意做”,还是“当前环境没有给它做这件事的权限”。这两种错误的修复方法不一样。

最后

Anthropic 这次复盘最值得记住的不是某个模型名字,而是它承认了一个很多 Agent 团队容易回避的事实:安全事件常常是模型行为和工程配置共同造成的。

所以 Agent 安全的第一张图,不应该是模型排行榜,而应该是权限图、网络图和恢复图。

先把模型放进一个真的隔离环境,再讨论它在环境里表现得有多聪明。否则我们测到的可能只是:谁忘了关哪一扇门。

参考资料

Anthropic:Improving our alignment and security efforts
Anthropic Research
DeepSeek Harness:插件开发教程
OKP:Anthropic 复盘 Claude 越权访问事件
OKP:前沿模型安全事件线

via 棒无 Improving our alignment and security efforts
编程 Agent 的额度,其实是一种 SLA
#博客更新

先说结论

编程 Agent 的额度,我越来越倾向于把它当成一种 SLA,而不是订阅页面上的赠品。

因为聊天产品被限流时,用户通常只是晚一点得到一个回答;编程 Agent 被限流时,可能正好停在:

已经改了几个文件,但还没跑完测试
子 Agent 已经启动,但主任务还没有汇总
上下文压缩刚做完,下一步还没执行
一次部署正在等待最后一个检查

这时候额度变化不是“少聊几句”,而是直接影响任务的连续性和恢复成本。

最近 OKP 记录了 Anthropic 和 OpenAI 编程产品在同一时间窗口里的额度讨论:Anthropic 侧的公开信息涉及 Claude Code 周额度从临时增加调整为较小的永久增加;OpenAI 侧则出现了“重置付费用量、优化 token 消耗”的公开公告和社区解读。社区把它概括成“额度暗砍”和“重置更耐用”,讨论热度很高。

这里必须区分三层事实:

1. 厂商正式公布的政策
2. 社区根据账户体感做出的观察
3. 用户自己在某个模型、套餐和时间窗口里的实测

这三层不能混成一句“某家把额度砍了”。但它们共同说明了一个问题:Agent 的容量边界已经是产品契约的一部分。

价格和额度不是一回事

很多产品页面只展示月费和模型名称,用户却真正受到下面这些变量影响:

一个“很便宜但经常在长任务中途停下”的 Agent,实际成本可能高于一个单价更高、但一次能完成任务的 Agent。

为什么编程任务特别依赖连续性

编程 Agent 不是只返回一段文字。它通常维护一条执行链:
理解需求
  → 定位代码
  → 制定计划
  → 修改文件
  → 运行测试
  → 读取错误
  → 修复
  → 再测试
  → 汇总结果

每一步都可能触发新的模型请求和工具调用。额度在这条链中间耗尽,会留下一个不完整但已经产生副作用的现场。

从用户角度看,真正关心的不是“今天还能发送多少条消息”,而是:

这个任务还能不能完成
被打断后恢复要不要重新解释
已经改动的文件是否能安全保留
额度恢复前我能不能继续做别的任务
有没有明确的剩余容量提示

所以编程 Agent 的用量指标应该更接近任务维度,而不是消息维度。

我会定义哪些容量指标

1. 可用请求预算

不是总 token 数,而是当前时间窗口还能发起多少次有效模型请求。工具调用、重试和子 Agent 都应该计入。

2. 上下文预算

同样一个模型,在短会话和长会话中的成本完全不同。需要区分:

当前输入 token
输出 token
cache hit / miss
压缩或历史重建产生的额外输入
子 Agent 是否重复携带上下文

Claude Code 官方文档已经提供 /usage、prompt cache、团队 spend limit 和 OpenTelemetry 等用量观察手段。这个方向是对的:用户至少要能知道容量花在哪里。

3. 时间窗口

“每周额度”太粗了。实际产品至少应该说明:

五小时窗口如何计算
周窗口何时重置
多设备是否共享
聊天、Cowork 和 Code 是否共享
失败请求是否占用额度
重置是否立即生效

4. 连续任务保证

这是最容易被忽略的指标。一个任务如果已经开始执行,额度不足时产品应该有明确策略:
继续当前任务
  或切换备用模型
  或保存 checkpoint 后暂停
  或请求用户补充额度

直接返回一个模糊的“达到限制”并丢掉上下文,是最差的处理方式。

5. 资源归属

如果一个主 Agent 开了三个子 Agent,额度应该能回答:
主任务用了多少
子任务 A 用了多少
重试用了多少
哪个工具产生了最多上下文

否则用户看到的总数无法指导下一次决策。

额度变化为什么会伤信任

价格调整至少是一个容易理解的数字:每月从 20 变成 25。额度调整更难,因为用户要通过长时间使用才能发现变化。

最伤信任的不是额度少,而是这几种不确定:

页面写着“无限”,但长任务会在不透明的地方停下
同一个任务今天能完成,明天突然只做到一半
额度条跳动,但没有解释是输入、输出、重试还是并发造成的
重置时间和用户看到的时间不一致
失败请求是否扣费没有说明

编程 Agent 的用户本身就在把真实工作交给系统。他们会容忍模型偶尔犯错,但很难接受容量边界不可预测。

如果是我来做 Agent 产品

我会把额度设计成一个可观察、可恢复的状态机,而不是一个藏在后端的计数器:
                    ┌──────────────┐
                    │ task running │
                    └──────┬───────┘
                           │ budget low
                    ┌──────▼───────┐
                    │ warn user    │
                    └──┬─────┬─────┘
                       │     │
              ┌────────▼┐  ┌─▼──────────┐
              │ fallback │  │ checkpoint │
              │ model    │  │ and pause  │
              └────┬─────┘  └─────┬──────┘
                   │              │
                   └──────┬───────┘
                          ▼
                    task continues

具体做法是:

1. 任务开始时估算一个区间,不假装精确
2. 接近阈值时提前提醒,而不是等请求失败
3. 保留最近一次可恢复 checkpoint
4. 把备用模型和备用 provider 当成正式路径
5. 记录每次 fallback 的原因和额外成本
6. 额度耗尽时保留任务状态、已改文件和待办步骤
7. 让用户能看到 reset 时间和当前任务的预计消耗

这和我们在做 Pi/cohub 时关注的事情是一致的:Agent 不是一次回答,而是一段可能持续很久的工作。工作系统必须知道自己何时应该继续,何时应该停下来等人。

用户自己能做什么

在服务商策略无法改变时,我会采用几条保守策略:

把长任务拆成可恢复阶段

不要让一个会话同时负责分析、实现、测试和部署。每个阶段写出明确产物,下一阶段从文件和 checkpoint 接着走。

给强模型留预算

机械搜索、格式修改、简单测试可以用便宜模型;设计方案、跨文件重构和最终审查留给强模型。关键不是永远用最强模型,而是不要在低价值步骤把预算消耗完。

记录自己的任务成本

我会记录:
任务名称
开始/结束时间
模型
请求次数
是否发生压缩
是否发生重试
最终是否完成

一两周之后,才能知道自己真正买的不是“多少 token”,而是多少个完成的任务。

预留故障转移路径

如果一个模型或 provider 是唯一入口,额度一变,整个工作流就会被带走。能接 OpenAI 兼容接口、能保留 transcript、能切换模型的 Agent,抗波动能力会更好。

本地模型也有额度

本地部署看起来没有服务商 quota,但它有自己的容量边界:

显存和系统内存
磁盘吞吐
并发 slot
温度和功耗
长上下文的速度衰减
模型加载和切换时间

我上一篇写 Qwen3.8-Flash-Next 时就提到过:模型“能加载”不等于“能生产”。本地 Agent 的内存和吞吐其实也是一种 SLA,只是承诺方从云服务商变成了自己的机器和推理后端。

最后

编程 Agent 的额度不是一个抽象的套餐数字。它决定了一个正在修改真实代码的系统能不能把事情做完。

所以我希望未来的 Agent 产品页面少写一点“无限”,多写几件更有用的事:

一个任务大概能跑多久
额度在什么情况下会消耗
接近上限时会怎么处理
中断后能不能恢复
备用路径是什么

SLA 的核心不是承诺永远不出问题,而是出问题时边界清楚、状态保留、用户知道下一步该怎么办。

这对编程 Agent 尤其重要。

参考资料

Anthropic:Manage costs effectively
OKP:Anthropic 与 OpenAI 编程模型额度政策
OKP:ChatGPT 停机与 Codex 用户迁移讨论
OKP:Codex 生态持续扩张
模型发布只是开始:Qwen3.8-Flash-Next 与 runtime

via 棒无 Manage costs effectively - Claude Code Docs
Agent 开始自己省 token:Grok Bot 的成本优化意味着什么
#博客更新

先说结论

Agent 产品开始主动宣传“自动省 token”,说明一个变化:token 成本已经从后台指标,变成了用户能感知的产品功能。

9 月 1 日,Grok Bot 的官方更新里连续出现两条相关信息:一条是 Grok @Bot upgrades,另一条是 Automatic token optimization to lower your Grok @Bot cost will be added soon。按 OKP 的追踪数据,两条帖子分别获得了 16,505 和 18,789 个赞。

这里要先说清楚:官方目前公布的是“即将加入自动优化”的方向,没有给出统一的节省比例、具体算法或所有任务上的成本承诺。所以这篇不是 Grok Bot 的节省效果评测,而是想回答一个更实际的问题:
一个 Agent 到底为什么会贵,以及成本优化应该放在哪一层。


Agent 的账单不是一次请求

普通聊天产品的成本大致是一问一答:
一次输入 + 一次输出 = 一次成本

Agent 完成一个任务时,通常是这样:
理解任务
  → 读文件
  → 调工具
  → 看结果
  → 修改计划
  → 再调工具
  → 重试
  → 验证
  → 总结

如果第 i 次模型请求的输入、输出、缓存和工具开销分别是 I_iO_iK_iT_i,一个任务的粗略成本可以写成:
C_task = Σ (I_i × p_in + O_i × p_out + K_i × p_cache + T_i)

真正让账单变大的,往往不是某一个回答特别长,而是请求次数和重复上下文太多。

一个看起来只需要“改一个按钮”的任务,可能包含:

每一轮都重新发送项目规则
工具返回完整日志,而不是摘要
模型反复读取同一个大文件
截图或网页状态被当成高 token 的视觉输入
失败后没有明确停止条件
多个子 Agent 各自携带一份重复上下文

所以 Agent 的成本优化不能只做成一个“换小模型”的开关。

Grok Bot 的信号为什么值得看

Grok Bot 不是单纯的聊天框。它被描述成拥有自己的电脑,可以进入 Gmail、Salesforce、LinkedIn 等服务执行任务。这样的 Agent 一旦进入重度使用阶段,token 消耗会和任务链路绑定:
任务越长
  → 工具调用越多
  → 上下文重复越多
  → 重试机会越多
  → 成本越难预测

早期产品最容易宣传“它能做什么”;到了用户真的拿它跑工作之后,问题会变成:

这个任务大概花多少钱
为什么同样的任务今天比昨天贵
Agent 是不是在重复读相同内容
失败重试有没有上限
我能不能在任务中途切换到更便宜的模型

“自动 token optimization”回应的其实是这些问题,而不只是模型推理速度。

成本优化应该分五层

第一层:不要重复发送不变的东西

最简单、收益通常也最稳定的是上下文去重:

system prompt 保持稳定,尽量命中 prompt cache
项目规则按需加载,不要每一轮全文拼接
工具结果只保留模型真正需要的字段
同一文件的内容在一个 turn 内复用,不要重复读取

这层优化不改变模型能力,只减少重复搬运。

第二层:让工具返回“可用结果”

很多 Agent 贵,不是模型太爱思考,而是工具返回了太多原始材料。

例如一个 shell 工具可以返回 2 万行日志,也可以返回:
{
  "exitCode": 1,
  "stderr": "TypeError: ...",
  "relevantFiles": ["src/app.ts:42"],
  "tail": "..."
}

原始日志应该保存在可追溯的外部记录里,模型上下文只拿摘要和定位信息。这样既省 token,也让模型更容易抓住真正的错误。

第三层:不同阶段用不同模型

不是所有步骤都需要同一档模型:

这里有一个重要前提:切换模型不能让上下文重新完整上传一遍,否则省下来的输出费用可能被输入费用吃掉。

第四层:给循环设置预算

Agent 的循环应该有明确的预算,而不是“直到模型觉得完成了”。
type TaskBudget = {
  maxSteps: number;
  maxInputTokens: number;
  maxOutputTokens: number;
  maxWallTimeMs: number;
};

function canContinue(state: TaskState, budget: TaskBudget): boolean {
  return (
    state.steps < budget.maxSteps &&
    state.inputTokens < budget.maxInputTokens &&
    state.outputTokens < budget.maxOutputTokens &&
    state.elapsedMs < budget.maxWallTimeMs
  );
}

达到预算之后,不一定要直接失败。可以按任务类型选择:

保存当前状态,等待用户继续
切换到便宜模型做收尾
只执行验证,不再扩展范围
给用户展示目前完成了什么、还差什么

第五层:把成本变成可观察数据

“感觉今天很贵”不是可调试的指标。至少要记录:

每个任务的总 token 和总费用
每一步的输入/输出/cache 命中
工具调用次数和工具结果大小
重试次数
每个模型在任务中的占比
成功任务的单位成本
失败任务已经消耗的成本

我会特别关注两个数字:
cost_per_successful_task
cost_before_user_abandonment

前者告诉你系统完成一件事要付出什么,后者告诉你用户在 Agent 还没完成之前已经被消耗了多少预算。

“省 token”不能变成“少做工作”

成本优化有一个很容易踩的坑:把任务结果变差,换成账单变好。

例如:

过度压缩工具结果,丢掉关键错误
为了少发请求,跳过验证步骤
强行缩短上下文,让模型重新猜项目背景
在复杂任务中途切到小模型,导致返工
把多次尝试隐藏掉,让用户看不到实际成本

所以优化目标不应该是:
minimize tokens

而应该更接近:
minimize cost
subject to successful completion, safety, and recoverability

也就是在完成率、安全性和可恢复性不下降的前提下,减少成本。

云端 Agent 和本地 Agent 的成本不一样

Grok Bot 这类云端 Agent 主要面对的是服务端 token 成本和用户套餐成本。Pi/cohub 这类运行时还要考虑另一种成本:

云端 API token
浏览器/容器运行时间
文件存储和日志保留
多 Agent 并发
本地模型的显存、内存和电力

本地模型看起来没有 API 账单,但“把一个 100GB 模型留在内存里跑一整天”也不是零成本。只是成本从按 token 计费,换成了固定设备成本和吞吐成本。

因此我不太相信一个统一的“每百万 token 多少钱”能够描述 Agent 的真实价格。更合理的单位可能是:
每个成功任务的成本
每个有效工具动作的成本
每个可恢复工作小时的成本


从产品角度,我会怎么做

如果我要给 Agent 加成本控制,不会只在设置页放一个 slider。我会做四件事:

1. 任务开始前给区间估算:告诉用户这是短任务、长任务还是可能持续运行的任务
2. 任务进行中显示消耗趋势:不要求精确到最后一分钱,但要能看出是否进入异常循环
3. 预算触顶时优雅降级:保存状态、切换模型或请求用户确认,不要突然丢掉整个任务
4. 事后给出可解释账单:哪些步骤最贵、哪些工具产生了大量上下文、哪些重试没有收益

这比单纯说“我们自动优化了 token”更值得信任。用户不一定需要知道每个内部算法,但需要知道 Agent 为什么花钱。

最后

Grok Bot 这次把 token 优化放到公开产品更新里,我觉得是一个很重要的信号:Agent 的下半场不是只比谁更会做事,也要比谁更会控制做事的成本。

一个 Agent 如果只能偶尔完成一次漂亮演示,却让用户不敢把真实工作交给它,它仍然只是 demo。

真正好用的 Agent,应该让人知道它正在做什么、还会花多少、出了问题能不能停在一个可恢复的位置。

省 token 只是手段。让用户敢把任务交给你,才是目的。

参考资料

Grok Bot:OKP 最新产品更新与 token 优化信号
Grok Bot 产品页
模型的新货架:从 Grok 4.6 上架 Pi 说起
Anthropic:Manage costs effectively

via 棒无
当视频模型开始生成界面:Runway Solaris 观察
#博客更新

先说结论

8 月 31 日,Runway 发布了 Solaris 研究预览,并把它称为 Interface World Model

官方描述很大胆:这不是一个普通的视频生成器,而是一种新型“操作系统”,窗口、菜单、滑杆等界面由视频模型实时生成,方向包括场景化视频、游戏界面、创意工具和产品原型。

我对这件事的判断是:如果 Solaris 的可操作性能够成立,它改变的不是“视频能生成得更漂亮”,而是界面本身可能不再是预先写好的组件集合。

但现在还不能把它写成成熟产品。当前公开信号主要来自 Runway 官方账号和一个 X List 旁证,公测资格、API、状态持久化和独立测试都没有明确资料。下面是方向分析,不是能力评测。

过去的界面是什么样的

我们熟悉的软件界面有一个稳定假设:
固定组件
  + 固定状态
  + 固定事件处理
  + 固定数据模型
  = 可操作应用

一个按钮是一个 DOM 节点,一个滑杆有明确的数值,一个菜单项对应一条路由。即使界面由游戏引擎或 Canvas 绘制,背后通常仍然有一套确定的 UI 状态机。

传统的生成式 AI 主要生成的是内容:
提示词 → 图片 / 视频 / 音频

它可以生成一个看起来像软件的画面,但这个画面通常只是结果,不是一个可以持续操作、保存状态、撤销和再次打开的应用。

Solaris 想挑战的是中间那条边界:
意图
  → 模型生成当前界面
  → 用户动作
  → 模型理解动作后的世界状态
  → 生成下一帧界面

如果这条循环稳定,界面就不再只是“渲染数据”,而变成了模型对世界状态的一种实时投影。

它和 GUI Agent 不是一回事

最近也有很多 GUI Agent:模型看屏幕,点击按钮,输入文字,拖动鼠标。这些系统通常是在已有界面上行动。

可以这样对比:

所以不能因为两者都“会用界面”,就把 Solaris 当成另一个 computer-use 模型。它更接近:模型不仅使用工作台,还参与生成工作台。

真正困难的不是画出一扇窗

从演示画面看,窗口、菜单和滑杆并不难想象。真正难的是这些东西必须具备软件的性质。

1. 状态要持久

用户拖动滑杆之后,数值应该进入某个可恢复的状态,而不是下一帧又随机回去。
动作 A
  → 状态 S1
  → 关闭界面
  → 重新打开
  → 仍然得到 S1

如果状态只存在模型的短期上下文里,它就更像一次互动幻觉,而不是应用。

2. 动作要可重复

同样的点击在同样的状态下,应该产生相同或可解释的结果。视频模型天然带有生成随机性,而软件交互依赖确定性。

这会要求系统把“视觉帧”和“真实状态”分开:
可生成的显示层
       ↓
可验证的状态层
       ↓
可执行的动作层

如果没有状态层,用户看到的按钮和系统真正接受的动作可能不是一回事。

3. 界面要能被机器理解

固定 UI 有 DOM、Accessibility Tree、语义标签和键盘焦点。模型生成的界面如果只有像素,接入自动化、辅助功能和测试都会变得困难。

一个真正可用的 Interface World Model,至少需要回答:

当前有哪些控件
每个控件的语义是什么
哪些控件可以操作
操作会改变哪些状态
屏幕阅读器和键盘如何访问它们

“看起来像按钮”不等于“它是一个按钮”。

4. 延迟必须足够低

普通视频生成可以等几秒甚至几分钟。界面交互不能每次点击都等一段完整视频生成。

用户会期待:
按下按钮
  → 立即看到反馈
  → 状态逐步稳定

因此 Solaris 更像实时世界模型,而不是离线视频模型。它要解决的不是单次画质,而是连续生成、状态更新和输入响应之间的延迟。

5. 失败要能撤销

固定应用里的错误操作通常可以 undo、回退或重新加载。生成式界面如果把每次状态变化都当成新一帧,就必须有明确的历史:
S0 → S1 → S2 → S3
           ↑
        undo / fork

否则用户很难知道一次错误是模型生成错了,还是自己的操作真的改变了数据。

我会怎样评估它

如果 Solaris 之后开放试用,我不会先截几张好看的图,而会做一套重复性测试。

我尤其关注“同一个任务跑十次”的成功率。生成界面最容易在单次演示里看起来惊艳,真正决定它是不是产品的是第十次还能不能找到同一个按钮。

它可能先在哪些地方成立

游戏

游戏本来就接受动态世界和非固定界面。模型生成一个场景化的控制层,可能比在办公软件里生成表单更自然。但游戏仍然需要物理规则、存档、碰撞和多人同步,视觉生成不能替代底层状态机。

创意工具

创作工具的界面本来就经常围绕当前任务变化。用户在做分镜、调色或构图时,需要的控件不一样,动态生成一个任务专用工作台有实际价值。

产品原型

这是最容易落地的方向:不是直接替代生产软件,而是让用户用自然语言快速得到一个可交互的原型。这里对确定性的要求相对低,但仍然需要能保存和分享。

场景化学习

教学界面、模拟实验和可视化解释也可能受益。模型不只是给一段答案,而是根据用户的理解程度生成一套可以探索的界面。

也要警惕一个误区

“界面由模型生成”不代表界面一定更好。

固定组件的价值就在于稳定、可预测、可测试。动态生成会带来新的成本:

用户每次打开都看到不同布局
团队无法复用操作教程
自动化脚本容易失效
产品问题难以复现
视觉一致性和品牌规范变复杂
安全敏感的操作可能被模型藏在不明显的位置

所以我不期待所有软件都变成生成界面。更现实的形态可能是:稳定的底层状态和权限 + 针对当前任务生成的工作台视图。

最后

Runway Solaris 目前还是研究预览,很多关键问题没有答案。它值得关注,不是因为一条视频里出现了会动的菜单,而是因为它把一个问题摆到了台面上:
界面究竟是程序的固定外壳,还是模型理解世界后生成的一种临时视图?
我暂时不会把它叫作“下一个操作系统”。但如果它能把生成画面、真实状态、语义操作和持久化历史接在一起,那它可能会成为一种新的软件入口。

现在先等它从演示里出来,给别人真正点几下。

参考资料

Runway 官方研究页面
Runway 官方网站
OKP:Runway 发布 Solaris
阿里 Qwen-UI-Agent 信号(相关背景)

via 棒无 AI Video Research & Innovation | Runway AI
模型的新货架:从 Grok 4.6 上架 Pi 说起
#博客更新

先声明立场:我是 Pi 团队的人,这篇难免「利益相关」。但正因为在场内,有些观察比外面看得早一点——下面所有数据都是公开可查的。

先说结论

模型分发的主战场,正在从「上架应用商店」变成「进 agent 运行时」。

过去一周有两件事让我对这个判断确定下来:

1. 8 月 13 日,xAI 官宣 Grok 4.6 可以在 Pi 使用。 模型发布次日单独发一条平台上架公告——这个动作本身比那条帖子重要。
2. DeepSeek Harness 的模型适配层 dsh-llm-pi-ai,底层就是我们的 @earendil-works/pi-ai 这是我上一篇写 Harness 插件时亲手发现的:156k star 的仓库,模型接入的缝是用 Pi 的 SDK 铺的。

一个是模型厂商把 Pi 当渠道来官宣,一个是框架作者把 Pi 当底座来依赖。方向一致:agent 运行时正在变成模型的货架。

两件事的细节

Grok 4.6 登陆 Pi

Grok 4.6 是 8 月 12 日发的,主打长程 agent、跨代码库分析和自我验证。首发帖累计 2500 万浏览、近 3 万赞。第二天,官方账号单独发了一条:「Grok 4.6 is now available in Pi」——10.4 万浏览、1273 赞。

把这两条帖子的关系看清楚:模型发布是新闻,「在哪个运行时里可用」是后续剧情。 剧情线还在继续:Perplexity 的 CEO 拿 Grok 4.6 当 orchestrator 跑了 Wide-And-Deep-Research 基准,结论是它在性能-成本曲线上位于帕累托前沿。注意这个用法——模型的评价场景已经从「聊天打分」迁移到「在某个运行时的编排下表现如何」。

pi-ai 在 Harness 的地基里

上一篇插件教程里我提过这事,这里补上量化的一面:
@earendil-works/pi-ai
周下载(8-15 ~ 8-21):4,236,540
最新版本:0.84.28-14 发布)

DeepSeek Harness 把它用作 LLM seam——README 原话是 "Generic multi-provider adapter for the harness LLM seam backed by @earendil-works/pi-ai"。翻译一下:Harness 里每一次换模型、配 provider、接 OpenAI 兼容网关,底下跑的都是 pi-ai 的抽象。

这不是我们去找 DeepSeek 谈的合作,是他们选型选中的。被当成基础设施用,是对一个库最好的验证方式——比任何 benchmark 都硬。

为什么货架会易主

回头看技术产品史,分发渠道的迁移有迹可循:

搜索引擎时代,浏览器默认搜索引擎是渠道,Google 付费买位
移动时代,App Store 上架位是渠道,首发渠道能决定一款应用的命运
云时代,**云市场(Marketplace)**是渠道,企业软件先上 AWS Marketplace 再谈销售

AI 时代的等价物正在显形。模型能力在快速同质化——DeepSeek 8 月三连发(V4-Pro → V4-Flash API → Vision-Exp)、GLM、Kimi、Qwen 都在月更节奏里,当供给过剩,渠道价值就上升。而 token 消耗最大的场景已经不是聊天框,是 agent:一个长任务动辄几百次调用。模型厂商要抓住的,是这些调用的入口。

入口在哪?就在运行时的那个模型选择器里。上一篇我在 dsh 的 Web UI 里把 provider 从 DeepSeek 切到自定义的 mock——那个下拉菜单就是货架。用户在那个菜单里能看到谁、默认是谁、切换成本多高,决定了模型的实际市场份额。

DeepSeek 自己看得最明白:低价 API 加自研 harness,模型和货架一手抓。这是官方版答案。而 xAI 选择的是另一条路——不自己造货架,把模型铺进别人已有的货架,Pi 是其中之一。

站在货架上是什么感觉

坦白讲,感受是复杂的。

好的那一面:pi-ai 五个月做到周下载四百多万,说明「多 provider 抽象」这个判断做对了——开发者不想为每家模型写一遍适配,模型厂商也不想让集成成本挡住试用。

不安的那一面:当一个库从产品变成公共契约,它的错误预算就没了。 以前发个 0.x 版本改接口,坏的是自己的项目;现在底下压着 Harness 这样的框架和它们身后成千上万的会话,兼容性和版本语义就是别人的生产环境。dev preview 可以随便破兼容,底座不行——这也是我从 Harness 文档里读到 "breaking changes expected" 时格外有共鸣的原因:他们可以这么说,我们不能。

接下来会怎样

三个预测,放在这里等着验证:

1. 「available in X」会成为模型发布的标准动作。 X 是一张运行时清单,就像今天 App 官宣支持 iOS/Android 一样自然。下一个官宣登陆某个 agent 运行时的模型,不用等太久。
2. 运行时的竞争会从功能转向生态位。 功能会被抄平,「谁的模型选择器里有谁」「谁是新模型的首发渠道」不会。Harness 开源五天 7174 个插件仓库抢的就是这个位置。
3. 模型评测表会多出一列:在哪些运行时可用。 单独的分数不够了,编排质量正在成为模型表现的一部分——Perplexity 那个 orchestrator 实测就是预演。

对我们自己,结论也简单:渠道不是终点。被依赖就要配得上依赖——接下来 pi-ai 的每个版本号,都是对下游的一份承诺。

参考资料

xAI:Grok 4.6 is now available in Pi(数据来自 OKP genai-hot 追踪记录)
dsh-llm-pi-ai README
@earendil-works/pi-ai on npm
本系列前两篇:Hi, deepseek-harness! / 给 DeepSeek Harness 写插件

via 棒无
Hi, deepseek-harness!
#博客更新

DeepSeek 于 2026-08-13 发布 Harness v0.1 开发者预览版,MIT 许可证开源

::github{repo="deepseek-ai/deepseek-harness"}

期待已久的 DeepSeek 官方 Harness 终于来了,我却体验不到十分钟就放置了(也许是我习惯了现有的 coding agent 的使用,目前依然是偏向 CLI)我们也有自己的基于 Pi 的 web UI 云端 agent——cohub

先声明一句:下面是个人体验 + 架构速读,不是评测。Harness 现在还是 developer preview,官方 README 自己都写了「未来将出现破坏兼容性的变更」,所以这篇写的是 2026-08-17 这一周的它。

先把事实摆一下

DeepSeek Harness(命令是 dsh)不是新模型,是一个 agent harness。官方主页把它概括成一句话:
Agent = Model + Harness
模型是灵魂,harness 是让 agent 认识环境、调用工具、在真实环境里持续干活的那一层。这层以前是各家 coding agent 各做各的,现在 DeepSeek 自己下场开源了一个。

发布一周的数据很夸张:

GitHub 五天 15 万+ stars(我 8 月 18 号查 API 是 156,653,这个增速本身就少见)
官方 X 帖 19,000+ 赞、近 400 万浏览,HN 731 分
知乎热榜第一挂了 253 个回答,小红书出现成体系教程(「从 0 开始成为高手」这种)
Ollama 社区已经在搞 ollama launch dsh,Reddit 有人拿 Qwen3.8-27B 塞进去实测,X 上有单卡 4090 48GB 跑 Q8 约 100 tokens/s 的帖子

生态第一波反应速度比很多模型发布都猛。装起来也确实快:
npx @deepseek-ai/dsh web

Node 环境有的话一条命令,浏览器打开 127.0.0.1:3080

十分钟之后我把它关了

流程是这样的:起来之后是个 Web UI,先去 Settings 里填 DeepSeek API key,然后「Choose workspace」选一个项目目录,之后才能开会话。中间每一步都顺,没有报错,就是——

我是在终端里干活的人。我的日常是 Claude Code / Codex 这类 CLI 工具,一个命令进目录,直接开始改代码。Harness 第一版只有两个官方 profile:webheadless(headless 是跑一次性任务,打印结果退出)。没有官方 TUI。于是十分钟里我的注意力被「配 key、选 workspace、认识界面」吃掉了,还没走到真正干活那一步,就关掉了。

说实话,关掉它的时候我心里清楚:这不是它的问题,是我已经不是它的第一目标用户了。v0.1 明显是 web-first 的产品节奏,先让用户能在浏览器里看见轨迹、看 Trajectory 视图、点 fork/resume。这个选择对「想让更多人先上手」是对的,只是恰好跟我的肌肉记忆反着。

但我放下它,不是因为觉得它没东西。恰恰相反,睡前我又把它的架构文档读了一遍,然后觉得这事值得写下来。

它的架构是「真插件化」

「Everything is a plugin」这种话每家都在喊,但 Harness 是少数真的把这句话落到加载器层面的。底层是一个叫 Cordis 的元框架(DeepSeek 自己维护,还配了一篇论文),几个关键设计:

模型、工具、技能、会话、沙箱、存储、loop、调度、UI,全是插件。 官方原文列的就是这些,包括 agent loop 本身。没有「特权核心」——session log 可以换,agent loop 可以换,你是在旁边挂一个新插件,而不是 fork 仓库改源码。

注册是可逆副作用。 插件通过 ctx.effect() 挂注册,卸载时自动回滚。所以插件可以热加载、热卸载,不会像很多框架那样卸了还留一串幽灵 handler。

依赖通过注入声明。 插件声明 inject 它需要的服务(ctx.toolsctx.llmctx.sessions),加载顺序由依赖关系推导,而不是手工写 boot 顺序。事件分 emit / waterfall / parallel / serial 四种派发模式,写在类型系统里。

组合靠 patch 层叠。 一次启动是这么叠出来的:
dsh-base(模型适配/工具/持久化/沙箱/审批/遥测)
  → dsh-web-app(浏览器应用)或 dsh-headless(一次性 runner)
  → profile 自己的 cordis.patch.yml
  → home 级 cordis.patch.yml
  → --patch 覆盖层

dsh --dump-config 能看到你这台机器实际 boot 出来的整棵树,树里任何一行都可以用你自己的 patch 换掉。这个设计对「个人魔改」和「企业定制」是同一个答案:不用改源码,改配置。

另外两个我觉得认真的地方:

● Every run is traceable。 模型看到的一切都进 append-only session log:system prompt、推理、工具调用与结果、子 agent 调度、上下文注入。Trajectory 视图按来源检视,fork / resume / replay 都基于同一条事件流。这个对调试 agent 比什么指标都有用。
● 四种 runtime mode。 Standard(全工具集)、Code(用模型生成的代码编排多轮工具调用)、Minimal(只剩 shell + 文件编辑器,拿来 benchmark 模型)、Creator(在内存里试插件)。最后一个模式说明他们想清楚了自己的开发者是谁。

我真正在意的:harness 层开始卷了

这件事比「DeepSeek 出了个 coding agent」重要。它意味着 harness 从一个各家私有的实现细节,变成一个公开的、有官方玩家的层。

DeepSeek 的模型价格低(V4 Flash 公测那波降价很凶),harness 是模型的分发通道——低价的模型 + 好用的运行时,这个组合拳才是完整的
插件生态就是第二个分发通道:模型厂商、工具厂商、服务商都能通过插件进来,dsh-plugin topic 已经在运转,社区插件聚合站也出现了
社区验证了它的开放性:Qwen 模型、Ollama、J-Space(社区 harness,有人测出 Terminal Bench 87.9→90.1,社区基准非官方)都挂上去了

当然,也有实打实的风险:dev preview 阶段 API 会破,star 数不代表留存,插件生态要等真实的开发者留存才能判断。X 上有条评论我印象很深,大意是「插件化解决了生命周期和副作用,但拓扑不是语义——换工具容易,决定什么该重试、什么该升级给人,才是 harness 的难点」。我认同这个说法。这也是为什么我虽然十分钟就关了它,还是会把它的 repo 和社区 keep 在视野里。

和 cohub 的关系

disclosure:cohub 是我们公司(Viscept)的产品,基于 Pi 做的云端 agent,web UI。有人可能觉得「你们也是 web UI,怎么评价人家的 web UI」——正因为我们也在这条路上,我才更清楚 web-first 和 local-first 是两条不同的产品路径:

Harness 是 local-first:你的代码、key、日志都在本机,装好即用,隐私边界清楚
cohub 是云端的:环境在远端,从浏览器就能进,不用管本机依赖

两条路径都成立,目标用户有重叠但不完全一样。Harness 出来那天,Pi 的作者也在 X 上公开聊过(686 赞的那条),态度是欢迎的——harness 层有更多人认真做,对所有做 agent 产品的人都是好事。

最后

我现在的态度很简单:第一版还轮不到我日常用,但它把「一切皆插件」当真了,并且把可追踪性做成了运行时约束而不是宣传词。这两点,我会继续盯着。

下次它出 TUI 的时候,我会再花十分钟。

参考资料

DeepSeek Harness 官方主页
deepseek-harness GitHub(README / 架构文档 / CLI 文档)
Cordis 论文:A Programming Paradigm for Spatiotemporal Composability
OKP 证据页:DeepSeek Harness v0.1 热度追踪
Reddit:Qwen3.8-27B + DSH 实测帖
知乎:Harness 评价讨论

via 棒无
Cohub 实操:用一个 Space 从零搭一个可发布的小工具
#博客更新

disclosure:这是我们公司(Viscept)做的产品,这篇是实操向,我会讲清楚每一步在干什么、有什么坑。

先说结论

如果你想试 Cohub,最快的入门路径不是看文档,而是走一遍真实的闭环
创建一个 Space → 和 Agent 说需求 → 它建文件/装依赖/跑起来 → Save 存 Checkpoint → 发布成 Work

整个过程大概 20 分钟。这篇文章记录我实际跑通的步骤,包括遇到的坑。

第一步:创建 Space

Cohub 的核心单元是 Space。你可以把它理解成「一个隔离的开发环境 + 对话 + 文件系统 + Agent」。

用 CLI 创建(cohub 是官方 CLI):
# 安装(如果你还没有)
npm install -g @neta-art/cohub-cli

# 登录
cohub auth login

# 列出你的 spaces
cohub spaces ls

# 创建新 space
cohub spaces create --name "my-first-tool"

或者直接在 web 上点 New Space 也行。我建议至少 CLI 装一个,因为后面很多操作 CLI 更快。

第二步:和 Agent 提需求

创建之后,打开 Space,跟 Agent 说你要做什么。关键是要把需求讲清楚,就像跟一个工程师同事提需求:
帮我做一个 Markdown 转 HTML 的小工具,输入一段 markdown,输出渲染后的 HTML。要能选样式主题,还要有一个预览区域。
注意几个点:

1. 说目标,不说实现。不需要告诉它用什么库,它会自己选。
2. 一次一个需求。第一轮先让它把核心功能做出来,再迭代加功能。
3. 它可以读写文件、跑命令。Agent 不是只回复文本,它会在 Space 的文件系统里创建文件、装依赖、跑 dev server。

第三步:看它干活,必要时纠偏

Agent 开始干活后,你会看到它:

创建项目文件(package.json、源码等)
npm install 装依赖
启动 dev server,暴露预览端口

这里有个经验:Agent 第一次做出来的东西,大概率不是你要的最终版。正常的迭代节奏是:
第一轮:核心功能能用
第二轮:你试了,提反馈("样式太丑""这个按钮没反应")
第三轮:它改,你再试

在 Cohub 里,你可以在同一个 Space 的预览区直接试它做出来的东西,不用自己本地跑。这个循环比「聊天里来回贴代码」高效得多。

第四步:Save(Checkpoint)

当你对当前状态满意(或者到了一个里程碑),存一个 Checkpoint:
cohub -s <space-id> spaces checkpoints create --message "markdown-to-html v1 done"

为什么这个重要:

1. 它是不可变快照。之后再怎么改,都能回到这个点。
2. 可以 fork。从这个 Checkpoint 分支出新想法,不影响主线。
3. 是可分享的稳定基底。别人可以基于你的 Checkpoint 继续工作。

这比 git commit 更像「存档」——你随时能回到任何有意义的时刻。

第五步:发布成 Work

这是 Cohub 和大多数 AI 工具最大的区别:Agent 的产出可以直接发布成一个公开可访问的页面(Work)
# 把项目构建成静态文件后发布
cohub -s <space-id> spaces files ls

# 发布目录为 Work
cohub -s <space-id> works publish my-tool --file dist/index.html

发布后你会得到一个公开 URL,任何人打开就能用你做的工具。这个 Work 还可以:

配置访问权限
用 Work Commerce 变现(卖功能解锁/积分)
被 fork 和 remix

实际遇到的坑

坑 1:Agent 装依赖慢

第一次让 Agent 跑 npm install,如果网络慢会等很久。解决办法:让它用国内镜像,或者先用最简依赖把核心跑通,再逐步加。

坑 2:端口预览 vs 实际发布

开发时 Agent 起的 dev server 端口,和发布后的静态托管不是一回事。如果你做的是 SPA 或需要后端的应用,发布时要注意:

纯前端 → 构建后发布 dist/ 即可
需要后端 → 用 Cohub 的 Sandbox 能力或对外部 API

坑 3:迭代时别丢上下文

每轮给 Agent 反馈时,引用具体现象("点击提交后没反应")而不是模糊的("好像不太对")。Agent 在同一 Space 里有完整上下文,具体反馈能让它精准修改。

写在最后

Cohub 最有意思的地方,是把「和 AI 协作做东西」从聊天里搬到了一个有文件、有环境、能发布的真实空间里。

你可以把它当:

快速原型工具(几分钟做个工具验证想法)
一个带 Agent 的完整开发环境
一个内容/工具的分发平台(Work)

如果你还没试过,建议按这篇的流程走一遍。从"让 AI 聊天"到"让 AI 帮你把东西做出来并发布",这个转变,用了才知道。

----------------------

产品:cohub.run
CLI:npm install -g @neta-art/cohub-cli
生态索引:github.com/markbang/awesome-cohub

via 棒无
Docker 生产实践:从能跑到跑得稳的 Checklist
#博客更新

先说结论

「Docker 能跑」和「Docker 能稳定跑」是两回事。本地 docker run 一次成功,和在生产集群里扛住流量、重启、扩容,中间隔着不少坑。

这篇文章是我在生产环境踩过之后总结的 Checklist。不追求面面俱到,只讲高频、高影响的十件事,按重要程度排序。

1. 镜像尽量小,但要小得有理

镜像体积直接影响拉取时间和启动速度。常见手段:

alpinedistroless 作为基础镜像
● 多阶段构建:构建阶段用全量镜像,运行阶段只拷贝产物
清理不必要的缓存和包管理器元数据

# 多阶段构建示例
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
RUN npm ci --omit=dev
EXPOSE 3000
CMD ["node", "dist/index.js"]

但注意:不是越瘦越好。distroless 没有 shell,调试会很痛苦;alpine 的 musl libc 偶尔和依赖有兼容问题。先瘦到合理范围,别为了几十 MB 自找麻烦。

2. 非 root 用户运行

默认容器内是 root,这是安全大忌。一旦容器被攻破,攻击者就是 root 权限。
FROM node:20-alpine
# 创建非 root 用户
RUN addgroup -S app && adduser -S app -G app
USER app

大多数官方镜像现在都支持直接切用户。这一步成本极低,收益很高。

3. 健康检查必须配

没有健康检查,编排系统(K8s/Swarm)就不知道你的容器是不是真的活着。进程在不代表服务可用。
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD wget -q -O - http://localhost:3000/healthz || exit 1

注意 start-period——给应用启动留时间,别一上来就被打回。

4. 日志打 stdout,别写文件

容器里的日志应该走 stdout/stderr,由编排系统收集,而不是写到容器内的文件。原因:

容器文件系统是临时的,重启就没了
你没法轻易拿到容器内的文件
云平台(CloudWatch、ELK、Loki)都从 stdout 收集

所以应用日志直接 console.log/print,别自己写日志文件轮转。

5. 资源限制,不是可选项

不设 --memory--cpus 限制,一个失控的容器能拖垮整个节点。
# docker-compose 或 k8s 里都要设
resources:
  limits:
    memory: 512M
    cpus: "0.5"
  reservations:
    memory: 256M

limits 一定要设,reservations 至少给一个合理值。这是生产环境第一道防线。

6. 环境变量和密钥,别硬编码

镜像里不要写死任何密钥。用:

环境变量(运行时注入)
Docker secrets / K8s secrets
专门的密钥管理(Vault、云厂商的 secrets manager)

镜像一旦构建就难以「撤销」里面硬编码的密钥。密钥泄露的补救成本远高于一开始就用环境变量。

7. 固定依赖版本,别用 latest

FROM node:20-alpine 里的 20 可能今天和明天解析到不同的小版本。生产环境要可复现

基础镜像用精确 tag(如 node:20.18.0-alpine
依赖锁文件(package-lock.json / poetry.lock)进镜像
有需要时用 digest 固定镜像

可复现 = 可回滚 = 可调试。

8. 处理僵尸进程和信号

容器作为 PID 1 时,要正确处理信号(SIGTERM)和孤儿进程。常见方案:

用带 PID 1 处理的运行时(如 tini
确保应用能优雅关闭(监听 SIGTERM,完成在途请求)

RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "dist/index.js"]

不然 docker stop 会变成 kill -9,数据库写一半就没了。

9. 镜像构建也要考虑 .dockerignore

.dockerignore 能大幅减少构建上下文和镜像体积,避免把 node_modules.git、日志、临时文件打进去。
node_modules
.git
*.log
.tmp
dist

这也是多阶段构建里第一层就过滤掉的东西。

10. 一个容器一个职责

别在一个容器里跑 web + worker + cron。拆开:

各自独立扩缩容
一个挂了不影响其他
日志、健康检查、资源限制都更清晰

一个容器只做一件事,是容器化最大的架构收益。

验证清单

改完以后,跑一遍这个验证:
# 1. 镜像构建成功且体积合理
docker build -t my-app .

# 2. 容器能启动且健康检查通过
docker run -d --name test -p 3000:3000 my-app
docker inspect --format='{{.State.Health.Status}}' test
# 期望: healthy

# 3. 优雅停止
docker stop test
# 观察日志是否有优雅关闭记录

# 4. 资源限制生效
docker run --rm -m 256m my-app
# 期望: 超出限制时 OOM,而不是拖垮宿主


写在最后

这十条里,健康检查、资源限制、非 root、日志走 stdout 是成本最低、收益最高的四项,强烈建议从这些开始。

容器化不是终点,只是起点。把这些基础打牢,后面接 CI/CD、上 K8s 才会顺。

如果哪条你踩过不同的坑,欢迎交流。

via 棒无 Docker 生产实践:从能跑到跑得稳的 Checklist - 棒无
#博客更新

2026年7月29日 Everyday we talk a little less. 半个月辗转了两个地方 我还没忘记自己是谁。如果哪天我们分开了,希望是山有雾..... 最近上班有点透支了 我是棒无,最近打算重启博客了! 在毕业后的一个多月里,我度过了很漫长的日子

via 陪棒无度过漫长岁月
#博客更新

20226年6月5日 结束了大学生涯 希望再走的慢一点慢一点.... 好长时间没发了 可能最近真的很忙吧 加油

via 陪棒无度过漫长岁月
让 AI 写好前端,我现在会先把这些话说清楚
#博客更新

先说结论。

让 AI 写好前端,重点不是多给它一点“灵感”,而是先把它容易乱跑的边界收紧。

我这阵子在折腾一个 tmux 相关的 web 项目,页面和终端渲染被我和 AI 来回改了很久。改到最后我越来越确定一件事:

前端做不好,很多时候不是模型不会写代码,而是我们喂给它的要求太松了。

你如果只说一句“帮我做个好看的页面”,它大概率会回到最常见的网页套路:

hero 很大
card 很多
badge 一排
shadow 和 radius 也不缺
看起来很努力,但就是没有自己的味道

它能把东西做出来,但不一定能做成你想要的样子。

1. 先分清楚:你到底要它做什么

这个问题看起来简单,但其实最关键。

很多前端任务混着三件事:

● 页面结构:信息怎么排
● 视觉方向:看起来是什么气质
● 交互边界:哪些地方脆弱,不能乱碰

如果这三件事混在一起,AI 就会很容易把注意力放错。

比如我那个项目里,终端视口其实是最脆弱的部分。它不是普通卡片,也不是普通文本块,更不是一个可以随便加阴影、加浮层、加复杂布局的区域。

它更像一个设备边界。

所以我后来改法就变了:

产品骨架先稳定
terminal 只负责 terminal
外层 chrome 只负责信息和操作
视觉装饰尽量收敛

这一步很重要。因为如果你不先告诉模型“哪个模块不能乱碰”,它就会自然而然把每个模块都当成可优化对象。

2. AI 最容易回退到模板味

这个我觉得是 AI 前端里最常见的问题。

只要 prompt 稍微模糊一点,它就会滑回训练数据里的高频网页模式。

结果通常长这样:

结构没错
组件也齐
配色也不丑
但一眼看上去就是“AI 做的”

为什么会这样?

因为模型默认会选最稳的解,而不是最有个性的解。

而所谓“稳”,对很多前端任务来说,恰好就是模板味。

所以如果你真的想让它写出有 taste 的页面,不能只让它“自由发挥”,而要给它更具体的偏好:

这个产品像什么
不是哪个风格都能用
哪些元素默认不要
哪些信息一定要先出现
哪些层级必须压住

这不是限制 creativity。

相反,这是在给 creativity 一个能落地的边界。

3. 第一屏不是信息仓库

我现在越来越不喜欢那种什么都往第一屏塞的做法。

很多 AI 页面看起来“内容很多”,实际上是没想清楚第一屏到底干什么。

第一屏最重要的不是堆信息,而是先把这几件事说清楚:

这是什么产品
它和别的东西有什么不同
用户为什么应该继续看下去
你这个页面的主情绪是什么

如果第一屏什么都想讲,最后通常什么都讲不清楚。

我现在比较认可的一种方法是:

第一屏只负责建立身份
第二屏再补场景
第三屏讲功能细节
最后再给操作入口

也就是每一段只做一件事。

这个原则看起来朴素,但很好用。因为 AI 很容易把 section 写成平铺直叙的内容清单,而不是有职责的页面段落。

4. 默认不要卡片,真的有用

这个判断很狠,但我发现它很好用。

很多 AI 页面的问题,本质上是太喜欢卡片了。

什么都要卡片:

hero 里要卡片
特性区要卡片
CTA 附近也要卡片
甚至一段说明文字也要 border + shadow + radius

最后页面就很“忙”,但没有重点。

我现在会先问自己一个问题:
如果去掉 border、shadow、background、radius,这块内容还成立吗?
如果还成立,那它大概率就不该是卡片。

这个判断能帮你砍掉很多不必要的视觉噪音。

而且它特别适合拿来约束 AI,因为模型很爱“补装饰”。你不给规则,它就一直补。

5. 先定设计系统,再让它写

AI 写前端最怕的不是不会写,而是写着写着风格漂了。

今天一套颜色,明天又一套按钮,后天再换一层背景逻辑,最后整个页面就散了。

所以我现在更倾向于先定这些东西:

background / surface / text / muted / accent
主要字号层级
按钮风格
间距节奏
圆角和边框的使用规则

这套东西最好在 prompt 之外就先写成 token 或设计说明。

因为 AI 其实挺擅长遵守“明确的系统”,不太擅长自己现场发明一套又一套。

如果你一开始就把系统定住,它后面写页面会稳很多。

6. 视觉参考比“高级”这种词更重要

“高级”“极简”“有氛围”这些词,听起来很对,但其实很滑。

模型看到这种词,往往只能往自己最熟的方向靠。

所以我现在更愿意直接给它:

参考图
mood board
颜色锚点
字号节奏
气质描述

因为这些东西比“高级一点”这种抽象词有用得多。

前端设计不是让模型猜,而是让它有一个明确的视觉方向可以靠。

尤其是有 taste 的项目,很多时候不是模块不够,而是审美方向不统一。

7. 给它页面叙事,不只是组件清单

这个点我觉得也很关键。

很多人让 AI 做页面的时候,给的是组件列表:

header
hero
feature cards
CTA
footer

但页面不是部件拼装,它应该有自己的叙事。

比如:

先建立身份
再补场景
再讲差异点
最后落到动作

如果你只给模块,它就会把这些模块平均地摆出来。

如果你给的是叙事,它才知道每个 section 的职责。

我现在会直接在需求里写:

第一屏负责什么
第二屏负责什么
哪些内容要晚一点出现
哪些元素不能抢主视觉

这会比“做个漂亮页面”有效得多。

8. 验证链路要早点放进去

前端最烦的一种情况是:

代码看起来对,页面其实不对。

比如:

移动端溢出
fixed 层遮住按钮
某个断点布局崩了
终端视口尺寸不对
页面 chrome 压到内容

这些东西只看代码经常看不出来,必须跑起来看。

所以我现在会尽量让 AI 带着验证去改,而不是只让它改完代码就算了。

最简单的方式就是:

跑测试
看截图
检查响应式
确认关键交互能点

如果能加 Playwright 这种自动化检查,会更稳。

它不是为了“显得工程化”,而是真的能减少很多肉眼不容易发现的问题。

9. 我现在让 AI 写前端的默认流程

我大概会这么做:

先写清楚边界

这个页面是给谁用的
它是管理台、控制台,还是展示页
哪个区域是脆弱区,不能乱改
哪些模块可以大胆做视觉

再给明确的 taste

深色还是浅色
克制还是热闹
偏产品感还是偏编辑感
更像工具,还是更像作品

然后给验证目标

桌面端要怎样
移动端要怎样
关键状态要怎样
不允许出现什么问题

最后再让它动手

这样出来的结果通常比“直接开始写”稳很多。

10. 说到底,前端不是堆组件

我越来越觉得,AI 前端最重要的不是“会不会生成页面”,而是你有没有把 art direction 这件事交代明白。
#博客更新

2026年4月19日 一切都会到来 写完了毕业论文,完成了最后一次体测,日子就这样一天天过去,亲爱的朋友,我们来日方长

via 陪棒无度过漫长岁月
 
 
Back to Top