NASA 与 IBM 开源“月球基础模型”:让人工智能读懂月球

2026 年 9 月,NASA 与 IBM Research 正式发布 NASA-IBM Lunar Foundation Model(NASA-IBM LFM)。这是一个专门面向月球遥感科学设计的多模态、多分辨率人工智能基础模型。模型权重公开托管于 Hugging Face,微调和推理代码则开放在 GitHub,并采用 Apache 2.0 许可证。 它并不是类似 ChatGPT 的语言模型,也不是一个能够模拟整个月球的“数字月球”。更准确地说,它是一套专门学习月球表面遥感数据的视觉基础模型。 从“识别图片”到“理解月球遥感数据” 几十年来,人类已经通过大量探月任务积累了规模庞大的月球观测数据。 其中最重要的数据来源之一,是 NASA 于 2009 年发射的月球勘测轨道飞行器 Lunar Reconnaissance Orbiter,简称 LRO。经过十多年运行,LRO 已经获得覆盖月球大部分表面的高分辨率影像和多种遥感数据。 但数据越来越多之后,一个新的问题逐渐出现: 如何有效分析如此庞大的月球数据? 如果研究人员希望寻找陨石坑、统计地貌、识别特殊火山结构或者分析极区水冰潜力,传统方法往往需要针对每一个研究任务重新建立算法和训练模型。 NASA 和 IBM 希望改变这种模式。 NASA-IBM Lunar Foundation Model 的思路与近年来人工智能领域的“基础模型”类似:先利用海量数据进行大规模预训练,让模型形成一种对月球表面结构的通用表示能力,然后再针对具体科学问题进行微调。 因此,它并不是一个只会“找陨石坑”的模型,而更像一个可以进一步训练成许多不同月球分析工具的基础平台。 近 200 万组月球数据 …

从 System Prompt 到长期知识架构:一套 AI Agent 的演进实践

近年来,AI Agent 的能力正在快速从“会聊天”演变为“能够长期工作”。 它们开始拥有文件系统、Shell、浏览器、代码执行环境、外部 API、远程主机、数据库、记忆、插件、Skill,甚至能够把任务交给其他 Agent。 这带来了一个比“怎么写好 Prompt”更重要的问题: 当一个 AI Agent 真正开始长期运行时,它应该如何组织自己的知识、规则、上下文、记忆和工具? 如果所有内容最终都堆进一个越来越长的 system prompt,系统很快就会遇到三个问题: 一个更成熟的方向,是把 Agent 看成一个长期运行的软件系统,而不是一段特别长的 Prompt。 本文讨论的正是这种演进过程。 一、研究 System Prompt,真正应该学习什么? 收集 OpenAI、Anthropic、Google、Microsoft、Meta、xAI、Perplexity、Cursor、OpenCode 等不同 Agent 产品的 system prompt、CLI Agent 规则和工作流后,一个很容易出现的误区是: 把优秀句子复制出来,然后拼进自己的 system prompt。 这种方法短期看起来很强,长期却很容易失控。 因为不同公司的 Agent: 真正值得借鉴的,不是某一句具体措辞,而是多个独立系统反复出现的共同架构思想。 当这些产品横向放在一起比较时,会发现很多设计已经开始趋同。 例如: 这说明成熟 Agent 的核心已经不再是一个巨大 Prompt,而是一套分层知识系统。 二、第一原则:Bootstrap 是宪法,不是数据库 Agent 启动时会注入一部分固定上下文。 这部分内容非常宝贵。 …

RustDesk Server OSS 设备记录审计、旧设备清理与管理实践

自建 RustDesk Server 运行一段时间后,很容易出现一个实际问题: 服务器已经连接过不少客户端,但究竟登记过多少设备?哪些设备仍在使用?哪些只是已经废弃的历史记录? RustDesk Server OSS 并没有像 Pro 版本那样提供完整的设备管理控制台,因此很多信息需要直接从服务端数据库进行审计。 本文以 Docker 部署的 RustDesk Server OSS 为例,介绍如何安全查看设备记录、理解数据库字段、识别旧设备、删除废弃记录,以及如何建立一个长期可用的系统管理命令。 一、先确认 RustDesk Server 的部署方式 RustDesk Server OSS 主要包含两个服务: 如果采用 Docker 部署,可以先检查: 常见部署会看到两个独立容器: 然后检查数据目录挂载: 典型结果类似: 这意味着 RustDesk 的数据库、服务器密钥等持久化数据实际上都保存在宿主机目录: 二、RustDesk OSS 的设备记录保存在哪里 RustDesk Server OSS 默认使用 SQLite 数据库: 数据目录中通常还能看到: 这里有一个值得注意的细节。 如果存在: 说明 SQLite 正在使用 …

Rocket.Chat 7.x 升级到 8.5.x:一次 Docker 与 MongoDB 联动迁移实践

Rocket.Chat 从 7.x 升级到 8.x,看起来像一次普通的容器镜像升级,但在实际环境中,真正需要处理的不只是 Rocket.Chat 本身。 这次升级同时涉及: 整个过程最重要的并不是“把新镜像跑起来”,而是保证: 任何一个阶段出现问题,都能够明确知道数据是否安全、问题出在哪里,以及能否回退。 一、为什么不能只修改镜像版本然后 docker compose up 旧环境采用的是典型的 Docker Compose 部署: MongoDB 使用的是较早时期常见的第三方容器镜像。 升级到 Rocket.Chat 8.x 后,数据库环境也需要同步调整。新的目标结构变成: 这带来了一个非常重要的问题: 旧 MongoDB 数据目录不能简单地直接挂载到新的 MongoDB 8.2 容器里。 MongoDB 的数据目录内部包含: 跨多个 MongoDB 大版本直接复用底层数据目录,风险远高于普通容器镜像升级。 因此这次采用的不是“原地替换数据库镜像”,而是: 也就是说,迁移的是逻辑数据,而不是直接让 MongoDB 8.2 接管 MongoDB 7 的物理文件。 二、升级前先建立可验证的数据库基线 在修改任何东西之前,先记录数据库当前状态。 例如检查: 这里最重要的不是某一个具体数字,而是建立一个可以在迁移结束后重新比对的基线。 例如: 迁移后重新执行相同统计。 …

一次 OpenClaw × Nextcloud Talk 故障排查与完整审计:从 Webhook 401 到迁移残留清理

前言 在一套长期运行的自建 AI Agent 环境中,OpenClaw 通过 Nextcloud Talk 接收消息,并借助 FRP、反向代理和 Webhook 与外部服务通信。 某次系统维护之后,Nextcloud Talk 中的机器人突然停止回复。与此同时,OpenClaw 此前还经历过一次失败的版本升级,因此最初很容易怀疑:是否升级失败破坏了插件、数据库或 Gateway 状态? 最终调查表明: Talk 故障与失败升级没有直接关系。真正原因是 Nextcloud 公网域名迁移后,OpenClaw Talk Channel 中的 baseUrl 仍指向旧地址,导致 Webhook Backend 校验失败并返回 HTTP 401。 在修复 Talk 后,又对整个 OpenClaw 安装实例进行了完整的只读审计,清理了迁移残留、失败升级 candidate 和旧 SQLite snapshot cache,并验证 SQLite、插件、Gateway、FRP、Agent 数据库等核心组件均处于正常状态。 这次排查很适合作为一个复杂自托管系统的故障分析案例: 不要看到异常就立即修复,而应先确定故障边界,建立证据链,最后只修改真正错误的部分。 一、系统架构 为避免暴露真实基础设施信息,本文统一使用占位符。 典型架构如下: …

从 /nextcloud/ 迁移到独立子域名:一次完整的 Nextcloud URL 架构重构

很多早期部署的 Nextcloud 都采用子目录模式。 例如: 这种部署方式简单,而且可以和其他服务共用同一个主域名。 但随着 Nextcloud 和现代浏览器安全机制不断演进,子目录架构会逐渐暴露一些限制。 这次迁移最终把正式地址从: 迁移为: 也就是独立子域名根路径部署。 整个过程涉及: 并不是简单地修改一个域名字符串。 一、为什么要从子目录迁移到子域名 最直接的原因之一是: 现代浏览器支持: Cookie 前缀。 它要求: 而如果 Nextcloud 长期运行在: 路径下,就很难完全满足: 这一要求。 安全扫描因此一直存在一个: 相关提示。 这意味着即使 HTTPS、HSTS、Content-Security-Policy 等其他配置全部正常,子路径本身仍然会限制部分 Cookie Hardening。 因此最终决定把 Nextcloud 放到独立子域名根目录。 二、DNS:先创建新的正式入口 首先创建: 对应 DNS A 记录: TTL 采用普通值,例如: 在真正修改 Web Server 之前,先确认: 这样后续 TLS 和反向代理才能正常验证。 三、TLS:把新域名加入现有多域名证书 …

从多个大版本一路升级到 Nextcloud 34:数据目录分离、App 兼容性、数据库索引与完整性修复

长期运行的 Nextcloud 实例,升级通常不是简单地执行一次: 就可以结束。 随着运行时间增加,实例会逐渐积累: 因此,一次跨越多个主要版本的升级,本质上更像是一次系统整理。 这次升级最终依次完成: 最终版本为: 一、没有跨主要版本跳跃 整个升级过程采用官方支持的逐版本路线。 例如: 这样做的主要原因不是保守,而是每一个主要版本都可能包含自己的: 如果跳过中间版本,就可能绕过原本应该执行的升级阶段。 二、数据目录分离显著改变了 updater 的行为 在早期升级过程中,一个非常明显的瓶颈出现在: 某次升级中,这一步曾经持续: 后来数据目录从应用程序目录中彻底分离。 原来的结构类似: 调整后变成: Nextcloud 配置中的: 也同步修改。 而且没有通过符号链接伪装旧数据目录。 之后再次进行: 升级时, 几乎变成瞬时完成。 这说明此前 updater 很大一部分时间很可能消耗在庞大的数据目录树检查上。 应用代码和数据目录分离后,更新器只需要处理真正属于程序的文件。 三、升级使用 updater.phar,并明确关闭 updater 自己的备份 其中一次升级命令类似: 这里使用: 并不是表示系统不需要备份。 而是因为该实例已经有独立的备份策略,不需要 updater 再额外生成一份完整程序备份。 更新完成后,继续执行: 最终状态为: 四、第三方 App 是升级中最需要单独处理的部分 Nextcloud Core 与第三方 …

一次持续近一周的 Nextcloud 后台数据库迁移:PreviewMigrationJob 的资源失控、限速执行与最终完成

在一次 Nextcloud 大版本升级之后,系统表面上已经完成版本更新,维护模式也已经解除,但数据库和存储层仍然存在一个持续运行的后台迁移任务: 这个任务最终持续了接近一周。 它并不是传统意义上“数据库 Schema 升级跑了一个星期”,而是 Nextcloud 把一部分历史数据迁移拆成了后台任务,使主版本升级可以提前结束,而大规模历史数据转换则在服务恢复之后继续进行。 这类设计可以缩短维护窗口,但也带来了一个容易被忽略的问题: 升级完成,不代表升级相关的所有数据迁移都已经结束。 一、迁移的实际规模 该实例积累了大量历史 Preview 数据。 当时统计到的迁移规模大致为: 因此,这并不是一个几十秒能够结束的普通后台任务。 Nextcloud 会让 PreviewMigrationJob 分批处理数据,而不是在版本升级过程中一次性完成全部迁移。 这也是为什么: 已经执行成功, 也都已经恢复正常, 但后台仍然持续进行数据迁移。 二、真正的问题不是“慢”,而是普通 cron 调度下出现资源失控 最开始,这项任务完全交给 Nextcloud 正常的 cron 机制运行。 例如: 正常情况下,这种方式没有问题。 但对于一个规模达到十万级数据库记录、百万级历史 Preview 文件的迁移任务来说,问题开始出现。 后台 PHP 任务逐渐堆积,部分进程进入: 也就是 Linux 中的不可中断 I/O 等待状态。 随后系统出现了明显异常: CPU 本身并不是主要瓶颈。 真正的问题更接近: …

在 Linux 上为特定 USB 网络设备设置稳定接口名:摆脱 MAC 地址和 USB 端口变化

在 Linux 上使用 USB 蜂窝网络设备、便携式路由器或手机 USB 网络共享时,经常会遇到一个看似不起眼、实际上很影响自动化的问题: 同一台 USB 网络设备重新启动后,网卡名称可能发生变化。 如果系统配置、路由优先级、监控脚本或自动化服务依赖固定接口名,这种变化就会带来麻烦。 一种常见做法是根据 MAC 地址生成接口名,另一种做法是绑定 USB 物理端口。但这两种方式都有局限。 更稳妥的方案是: 识别设备本身,而不是识别它当前的 MAC 地址或插在哪一个 USB 口。 本文记录一种基于 systemd.link 和 udev 设备属性的实现方式。 一、问题:USB 网络接口名称并不一定稳定 许多 USB 网络共享设备通过 RNDIS、CDC Ethernet 等方式向 Linux 暴露网络接口。 系统可能根据 MAC 地址生成类似这样的名称: 如果设备每次重新启动都会生成新的 MAC 地址,那么就可能出现: 对于普通桌面使用,这通常没有太大问题。 但对于一台长期运行的 Linux 主机,如果配置中存在: 或者脚本中需要: 那么接口名变化就会破坏自动化。 二、第一种解决方法:绑定 …