从脚手架到产品:DeepSeek Harness插件化架构设计与实践

做模型集成这个领域久了,你会慢慢发现一个规律:大多数工具最后不是死于功能太少,而是死于接口太死。DeepSeek Harness 这个项目,最初只是我在某个模型接入需求里随手搭的脚手架,后来它因为一套插件机制越长越像产品,连我自己都没想到。这件事本身值得好好拆一遍,尤其是“万物皆插件”这种听起来很玄的设计,到底是怎么一步步把一套一次性脚本变成可扩展的基础设施。

如果你正在做 LLM 应用中间层,或者手头有一个“什么功能都要塞进去”的服务,这篇文章能给你一些可以直接抄作业的架构思路。我不打算只讲某个框架的用法,而是把脚手架演变为产品的底层逻辑、插件协议的边界设计、动态加载的技术细节、以及我踩过的几个大坑,全部摊开来说。

1. 从脚手架到产品,差的就是一套插件协议

1.1 脚手架为什么撑不住

做技术的人都有一个本能:功能一旦开始堆叠,你就会不自觉地抽公共方法。我最早写 DeepSeek Harness 时也是这样,先是写一个模型调用函数,再来一层模型封装,然后加重试逻辑、参数装配、结果格式化。大概两周后,这个文件膨胀到八百多行,每次加新需求,都要在至少五个地方做修改。真正让我决定重构的,不是代码量,而是新需求根本插不进去。

举个例子。当时要接入一个新模型,这个模型支持多段思维链输出,意味着请求和响应的结构都和原来不一样。按照老写法,我得在主流程里加判断,在解析结果的地方加分支,在超时重试的地方再补特殊逻辑。这种模式就是典型的脚手架状态:能用,但只对当前这一条路能用。

脚手架的定义不是简陋,而是“没有扩展点”。扩展点就是那些允许你在不修改核心代码的前提下,往系统里塞新能力的位置。没有扩展点的系统,每加一个功能,就是在原本就紧凑的身体上再缝一块肉。短时间感觉不到问题,等缝了十几次以后,整个逻辑链路已经没人能说清楚。

1.2 插件协议的本质是“先画边界,再填内容”

后来我把所有变化点都摊在桌面上,发现团队里真正变化的不是“模型调用”本身,而是模型调用前后发生的那些事情:输入解析、请求构造、工具选择、结果校验、错误处理、指标采集。这些统统可以被替换。

于是我把协议定义为五个阶段:注册、发现、初始化、执行、销毁。任何功能,只要能完整走过这五个阶段,就是一个插件。这个设计让我把“DeepSeek 模型怎么接”这个问题,直接变成了“DeepSeek 适配器这个插件怎么写”。

这带来的最大变化,是整个系统的演进路径变了。以前是一个模块决定其他模块的命运,现在是协议决定所有模块的命运。协议是稳定的,内部可以烂,可以换,但外部接口一旦定下,就不再因为某个业务需求而随意变动。

这里我想说一个很关键的认知:插件化不等于把所有东西都抽象成一个接口,那只会让接口变得又宽又软。好的插件协议应该足够窄,窄到每个插件只干一件事,窄到替换一个插件时不需要关心其他插件内部怎么实现。

提示:插件协议的第一个版本不用追求完美,但它必须回答清楚三个问题:输入是什么、输出是什么、出错怎么办。这三个问题回答清楚了,协议的地基就算打稳了。

2. 底层构造揭秘:注册表、动态加载与生命周期管理

2.1 用一个注册表收拢所有能力

DeepSeek Harness 的底层核心其实非常小,主要就是一个注册表和一个加载器。注册表在内存里维护插件名、版本、入口对象、依赖声明。这一步是所有插件化的心脏,没有注册表,后面的一切都无从谈起。

我习惯用装饰器来做注册,这样写插件的人不需要主动调用任何注册函数。伪代码长这样:

_PLUGINS = {} def register_plugin(plugin_id, version="1.0.0"): def decorator(cls): _PLUGINS[plugin_id] = { "class": cls, "version": version, "dependencies": getattr(cls, "dependencies", []), } return cls return decorator

然后在主程序中,所有插件都用register_plugin("xxx")标注。加载器只需要扫一遍注册表,就能知道系统里有哪些能力,有哪些版本,依赖关系是什么。

这里有一个关键细节:为什么用插件 ID 而不是类名?因为类名会随着重构不断变化,但 ID 是稳定标识。插件 ID 一旦对外公开,就尽量不要改,否则依赖它的其他插件全部要跟着断。就好比一个服务的 API 路径,你可以换内部实现,但路径不能随便变。

2.2 动态加载要解决“重依赖”问题

动态加载插件最怕的事情,是为了用一个小功能,把一堆重型第三方依赖全部拖进主进程。所以加载器必须支持延迟加载,默认只在初始化阶段才真正导入插件内部用到的库。核心调度器永远不需要感知某个插件具体依赖了 Pydantic 还是 TensorFlow。

这样设计的好处,在插件少的时候看不出来,等到插件数量多了以后会非常明显。比如你同时有模型接入插件、评测指标插件、工具调用插件,如果主进程启动时全部 import 一遍,光依赖冲突和环境检查就能让你怀疑人生。延迟加载可以保证:一个插件有问题,最多是该插件不可用,而不是整个系统起不来。

延迟加载的另一个附带收益是热插拔。插件处于未激活状态时,连类都不需要真正导入。注册表里只需要记录一个模块路径和元信息,等到真正要被调用时再去 import。这个机制对在线升级和灰度发布都很有价值。

2.3 生命周期:用状态机管住插件的生死

每个插件都会经历几个状态:已注册、已配置、已初始化、运行中、已卸载。我建议用枚举把状态钉死,不允许插件随意跳转状态。状态机这事听起来简单,但没有它,你很难定位一个插件到底卡在哪一步。

当某个插件的初始化阶段失败时,它会进入失败状态,调度器把它标记为不可用。调用方拿到的是一句明确的错误提示,而不是整个进程崩溃。这个设计在脚手架阶段看起来是多余的,等插件数量多了以后你就能体会到价值——一个插件的失败不会再拖垮整个任务。

生命周期管理的另外一个作用是支持清理。插件在卸载时需要释放连接池、关闭线程池、取消定时任务。如果少了这个步骤,热更新几次以后你会发现内存悄悄涨上去了。这不是框架层能替你解决的,插件协议里必须预留这个钩子,强制要求插件作者编写清理逻辑。

3. 产品化三步走:配置中心、可观测性与契约测试

3.1 配置中心把“魔法值”逐出系统

脚手架阶段的配置基本是硬编码,或者散落在各个模块里的常量。产品化要做的事,就是把所有参数收拢到一个配置中心。每个插件在协议里声明自己需要哪些配置项,配置中心负责校验和注入。插件拿到的上下文里,已经是合法配置,不需要自己翻环境变量。

有人可能会说,这不就是加了一层封装吗?区别在于,配置中心能做交叉校验。比如两个插件都声明需要同一个 API Key,配置中心可以检查这个 Key 是否过期,是否能访问目标网关。这种集中校验在脚手架阶段根本不会有人去做,因为大家只管把代码跑通。

如果你的插件数量超过十个,配置项超过几十个,没有一个配置中心,排查问题的成本会成指数级上升。你看一个插件行为异常时,第一步一定是看它实际收到了什么配置,而不是去源码里翻它到底读了哪个环境变量。配置中心解决的就是这个“实际收到什么配置”的透明性问题。

3.2 可观测性:给插件装上仪表盘

脚手架阶段,你打印两行日志就觉得自己看到了全部。产品阶段不行,你需要回答这些问题:每个插件运行了多少次?平均耗时是多少?失败集中在哪类错误?哪个模型网关最容易超时?

我给 DeepSeek Harness 加了三个指标:调用次数、耗时分布、错误码分布。插件 SDK 会自动上报这些指标,业务代码不需要额外埋点。实现思路是:加载器在对插件做代理时,用装饰器包装 run 方法,统计时间与异常,再写入一个内部 metrics 队列。

光有指标还不够,还需要导出接口。运维同学拿到指标后,能画出一张调用拓扑图:哪个模型服务的真实成本最高,哪个插件在高峰期的失败率上升,哪个错误码对应的模型在退化。产品化的标志,不是你功能多齐全,而是你能随时回答“系统现在怎么样了”。

3.3 契约测试:给插件上一道紧箍咒

插件多了以后,最怕接口悄悄变掉。纯靠单元测试根本挡不住跨插件的回归,因为每个插件单测都是自己给自己设置预期,很容易变成自说自话。我实践下来最有效的,是给插件做契约测试。

具体做法是:定义一份协议样本库,每个插件注册时必须跑一遍样本输入,确保输出符合协议。这份样本别搞得太复杂,核心是覆盖三种情况:正常输入、空输入、异常输入。加载器启动时会运行一个自检钩子,任何一个插件自测失败,就直接进入失败状态,不允许投放到正式环境。

这个做法的价值,在于把边界问题前置。很多协作问题的根源是双方对边界的理解不一致。契约测试让这种不一致在启动阶段就暴露,而不是等线上任务跑到第 10000 条数据时突然炸开。炸开以后你再想去定位是哪个插件的边界没守好,那代价就太大了。

3.4 版本管理与滚动升级

产品化逃不开版本管理这件事。插件和插件之间会有依赖,A 插件依赖 B 插件的某个能力,如果 B 升级后删掉了那个能力,A 可能在不知情的情况下挂掉。这个问题靠文档通知是不可靠的,必须在协议层解决。

我采用的做法是:在注册表里记录每个插件的依赖声明,包括依赖插件 ID 和版本范围。加载器启动时做一次依赖解析,类似包管理器的逻辑。版本不满足就直接报错,不给运行时留幻想。有了依赖解析,插件升级就变成一件有约束的事情:你想升级 B,系统会告诉你哪些插件可能受影响,你可以选择一起升级或者先做兼容测试。

4. 实操上手:30 分钟写一个 DeepSeek 模型接入插件

4.1 骨架代码与注册流程

理论说了不少,我把一次最小可用的模型接入插件写出来,大家感受一下实际手感。下面的代码把一次模型调用封装成一个插件:

from harness.plugin import HarnessPlugin, register @register("deepseek-chat-adapter", version="1.0.0") class DeepSeekChatAdapter(HarnessPlugin): dependencies = ["httpx>=0.27"] def configure(self, config): self.base_url = config.get("api_base", "https://your-model-gateway.example") self.api_key = config["api_key"] self.timeout = config.get("timeout", 30) def run(self, request): prompt = request["prompt"] response = self._call_model(prompt) return {"text": response["choices"][0]["message"]["content"]} def _call_model(self, prompt): # 真实项目中这里才是一个 HTTP 请求 payload = {"model": "deepseek-chat", "messages": [{"role": "user", "content": prompt}]} # 省略请求代码,插件跑通后再补上 return {"choices": [{"message": {"content": "mock response"}}]}

这段代码虽然简单,已经包含了插件的几个关键要素:稳定的插件 ID、配置集中注入、入参出参都是可序列化的普通字典。

有人会问,为什么不用 pydantic 模型或泛型来定义输入输出?因为插件协议要面向不同语言的调用方,保持普通字典是兼容性最高的选择。如果你所有插件都是 Python,确实可以用更严格的模型,但一旦要暴露给其他团队或服务,最好是文档化的字典结构。序列化协议越简单,跨语言协作越省心。

4.2 配置项与依赖管理的细节

插件需要的参数,尽量集中在同一个命名空间下,比如用插件 ID 做前缀。避免两个插件都去读一个叫api_key的配置,一旦一个插件改错了 Key,排查时你会分不清是哪个插件的问题。

依赖声明的版本范围不要太宽松,也不要锁死到只允许一个版本。我的经验是,核心依赖允许>=某个基线版本,但插件自身的通信协议依赖要尽量精确。因为通信协议变了,往往意味着行为变化,这种行为变化正是你想在升级时发现的事情。

还有一条建议:核心框架不要预装任何插件的第三方依赖。插件的依赖应该由专门的安装器统一收集,生成一份虚拟环境锁文件。这样不同插件需要的版本冲突,可以在安装阶段就被发现,而不是运行到一半才报 ImportError。依赖问题越早暴露,修复成本越低。

4.3 本地验证与调试三板斧

插件写完以后,先用 CLI 工具跑一次自检:

harness test --plugin deepseek-chat-adapter

如果自检失败,定位路径基本是固定的三步。第一步,确认插件是否被加载器扫描到,检查插件目录路径和文件命名。第二步,确认配置是否注入成功,把实际生效的配置 dump 出来看一眼,别猜。第三步,确认 run 方法本身是否抛异常,去指标队列里看失败原因分布。

调试插件最忌讳的,就是直接去改框架核心。插件协议是铁律,协议之外临时开的通道,会一点点腐蚀整个架构。你这次为了省事开了一个后门,下次别人也会学你开一个,到最后这个系统就没有边界可言了。遇到确实解决不了的问题,先在插件内部加日志,把上下文打全,再决定要不要扩展协议,而不是绕过协议。

5. 踩坑实录:插件化最容易翻车的六个问题

5.1 插件扫描目录与模块名冲突

动态加载最经典的问题,就是插件模块名互相覆盖。Python 的sys.modules会缓存已导入的模块,如果两个目录下都有adapter.py,第一个被 import 之后,第二个永远不会被加载。这个问题有个很隐晦的表现:插件少的时候一切正常,插件增加到一定数量后,某些插件随机失效。

我的解法很简单:强制要求插件文件名与插件 ID 保持一致,同时加载器里要使用唯一的模块路径,而不是单纯按文件名套件。这个规范要写在插件开发文档里,并且用工具检查,不能靠人自觉。因为这类问题一旦出现,排查起来极其消耗时间,你会发现所有逻辑都是对的,但插件就是没执行。

5.2 插件之间的循环依赖

插件互相调用时,特别容易出现 A 插件初始化阶段要调 B 插件,但 B 插件还没初始化完。这种循环依赖在业务代码里会被编译器或运行时直接报错,在插件系统里却往往表现为诡异的 None 或空对象。

我的解决方案有两个方向。第一,插件之间不要直接互相引用,改为通过事件总线通信。A 发一个事件,B 监听事件并响应,这样它们的生命周期天然解耦。第二,如果非要直接调用,初始化阶段只做资源准备,不做业务调用,真正的调用放在 run 阶段。这样初始化顺序即使不理想,也不会导致空对象。

加载器最好还是做一次拓扑排序,先初始化没有依赖的插件,再初始化有依赖的插件。这一步在插件数量超过五个以后就必须做,不然每次启动顺序稍微一变,行为就跟着变,线上会出大问题。

5.3 共享上下文的状态污染

很多插件会往共享上下文里放连接池、缓存、状态标记。最开始没什么问题,但插件一多,互相之间就可能出现状态污染。A 插件往上下文写了某个标记,B 插件读了之后以为是自己的状态,结果行为完全错乱。

我的做法是:上下文对象设计成不可变模式,只放只读配置和受控的共享资源。任何插件想往上下文里加自己的数据,必须先创建一个派生副本,不能直接改原对象。这个约束在单线程环境下感觉多余,但一旦上了多线程或者多协程,它带来的收益极大。

并发安全也是一个藐视不得的问题。如果插件内部用了可变类变量去存状态,并发调用时会出现莫名其妙的串数据。我见过最惨的案例是,两个任务同时跑,A 任务的结果被 B 任务覆盖,排查了整整两天,最后发现是插件里一个模块级 list 在作怪。教训就是:插件所有内部状态都要存在实例属性里,绝不能放模块级变量。

5.4 版本升级导致旧插件失效

插件化系统时间久了会积累很多老插件,有些老插件依赖的第三方库已经不再维护,但核心框架升级后,它们就开始报错。最容易翻车的不是代码逻辑,而是依赖的隐式行为变化。比如某个库升了一个小版本,异常类型从ConnectionError变成了TimeoutError,插件里的 except 语句没覆盖到,直接崩溃。

应对这个问题的办法有两个。一个是依赖锁定,插件在发布时记录自己实际验证过的依赖版本范围。另一个是升级前跑全量契约测试,至少在 CI 里把核心框架和所有插件的组合矩阵跑一遍。组合矩阵听起来重,但插件数量几十个时,这是唯一可靠的保障。

5.5 权限控制:插件能做什么事必须显式声明

插件化的好处是扩展容易,风险也在这里。一个带后门或带有恶意逻辑的插件,如果读取了不该读的文件、访问了不该访问的内网地址,后果很严重。这不是危言耸听,插件生态越开放,被滥用的面就越大。

我给插件系统加了权限清单,每个插件在注册时声明自己需要哪些权限,比如网络访问、磁盘读写、环境变量读取。加载器在运行插件前检查权限清单,未授权的调用直接拒绝。这个设计在内部项目里看起来有点多余,但它能拦住很多低级错误,比如某个插件误删了配置文件。

5.6 不要把“插件化”当成万金油

最后说一句反话。插件化不是没有成本,前期协议设计、加载器实现、契约测试,都要实打实投入工时。如果你的系统里只有两三个变化点,直接写 if-else 大概率更快,也更稳。

但如果你已经能预见到扩展路径,或者你正在为“接新模型就要改主流程”这件事头疼,那插件化就值得投入。DeepSeek Harness 之所以能从一个脚手架变成产品,不是因为插件化本身听起来高级,而是它把变化点集中到了最小范围。其他模块基本不用动,新增能力只需要多一个插件目录下的文件。这种“局部变动不波及其他”的特性,才是它长成产品的核心动力。

我个人实际开发中的体会是:给项目做插件化最好的时机,往往不是第一天,也不是最后一天,而是你第一次因为“加需求要改多个地方”而皱眉的时候。这时候动手,不是重写,不是重构,而是顺势把边界画出来。DeepSeek Harness 走到现在这一步,回头看不复杂,但它证明了一件事:只要边界画得足够清楚,脚手架也可以自己长出产品该有的样子。如果你想给自己的工具也做一次升级,建议从最小的插件协议开始,先跑通一个插件,再慢慢把其他能力拆进插件边界里。这个顺序看起来慢,但落地最稳。

相关新闻

机器学习与深度学习入门:从基础原理到高效学习路径

机器学习与深度学习入门:从基础原理到高效学习路径

“机器学习,深度学习”这个标题太大,大到几乎所有入行的人都被它晃了一下。它不是某一个项目,而是一整套知识体系。如果你正打算入门,或者已经在某些教程里被各种术语捶打了一段时间,这篇东西就是写给你的。我会把这两…

2026/10/20 22:14:33 阅读更多 →
XSS防护第一步:读懂xss-payload-list攻击载荷与绕过机制

XSS防护第一步:读懂xss-payload-list攻击载荷与绕过机制

写XSS防护的文章,我一直有个观点:搞清楚攻击payload,恰恰是做好防守的第一步。很多团队天天喊"防XSS",却连攻击者到底拿什么打进来的都不清楚,这防线建得就有点心虚。所以这篇我就围绕 xss-payload-list 这份…

2026/10/20 22:14:33 阅读更多 →
RNN、CNN、Transformer:序列建模三大瓶颈与架构选型指南

RNN、CNN、Transformer:序列建模三大瓶颈与架构选型指南

1. 从序列建模说起:为什么 Encoder 架构必须迭代做序列建模的人都有一个共同的体感:模型结构这东西,不是越复杂越好,而是每一代架构都在解决上一代解决不了的问题。RNN、CNN、Transformer 这三代 Encoder 架构的演进,表…

2026/10/20 22:14:33 阅读更多 →

最新新闻

开放式代码审查:从规则沉淀到AI辅助的团队实践

开放式代码审查:从规则沉淀到AI辅助的团队实践

那一次Review,至今让我印象深刻。我自认为提交了一段“完美”的代码:类型明确、命名讲究、注释齐全,甚至提前把函数的三种边界情况都测了一遍。结果同事在评审里只问了我三个问题:为什么定义成接口而不是具体类型?三秒…

2026/10/20 22:55:46 阅读更多 →
SQL孤岛与间隙问题全解析:从窗口函数到连续登录实战

SQL孤岛与间隙问题全解析:从窗口函数到连续登录实战

做时间序列分析的朋友一定碰到过这样的场景:一张表里存着用户的登录记录,日期断断续续,你不仅要找出哪几天没登录,还要把连续登录的几天拼成一个“段”来统计。又或者,你面前是一堆带时间戳的告警事件,需要…

2026/10/20 22:55:46 阅读更多 →
机器人系统十年演进:从脉冲伺服到数字孪生的架构变革

机器人系统十年演进:从脉冲伺服到数字孪生的架构变革

要说这十年机器人系统最大的变化,我得先讲个真实场景。2024年我在客户现场调一套柔性上料系统,机器人配上3D视觉和力控打磨单元,工程师们坐在办公室里用数字孪生平台远程调试,坐标变换、轨迹规划、碰撞检测全在仿真环境里跑完&…

2026/10/20 22:55:46 阅读更多 →
Diagram-Design:结构化视觉表达的底层工程能力

Diagram-Design:结构化视觉表达的底层工程能力

1. 项目概述:这不是画图,是用结构化思维解决真实问题的底层能力“diagram-design”这个词组乍看像某个设计软件的插件名,或者某次内部培训的课程代号,但在我过去十年带过的几十个跨领域项目里,它其实代表一种被严重低估…

2026/10/20 22:55:46 阅读更多 →
diagram-design:结构化思维的可视化推演方法

diagram-design:结构化思维的可视化推演方法

1. 项目概述:这不是画图,是用结构化思维解决真实问题“diagram-design”这个词组乍看像一个工具名或软件功能,但在我过去十年带过的几十个跨领域项目里,它从来不是指“用Visio拖几个方框”,而是一套把模糊想法落地为可…

2026/10/20 22:55:46 阅读更多 →
动作单元驱动的能量流管理:知识工作者的复利提效法

动作单元驱动的能量流管理:知识工作者的复利提效法

1. 项目概述:这不是“躺平”,而是用系统性思维重构日常工作的能量守恒“躺平挖 alpha”这个标题一出来,很多人第一反应是调侃——又一个打鸡血式的时间管理法?或者干脆是反内卷的消极宣言?其实完全不是。我在某实验室带…

2026/10/20 22:54:43 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →