controller-runtime Manager 核心原理与常见坑位解析
你刚开始用 controller-runtime 写 controller最绕不开的就是它那个叫 Manager 的入口。很多同学拉完 kubebuilder 生成的项目代码看到一个manager.New和一大堆 Options往往直接照抄却说不清这个对象到底做了什么。这篇是 controller-runtime 系列第二篇专门把 Manager 拆开聊它解决什么问题、内部启动链路是什么样、日常配置要关注哪些字段以及我在实际项目中踩过的坑。适合已经写过简单 controller、想进一步吃透 controller-runtime 机制的开发者如果你刚从 client-go 硬编码 informer 的写法转过来这篇尤其对口。1. 为什么所有 Controller 都离不开 Manager1.1 Manager 到底“管”了什么先给一个最直白的定位Manager 是 controller-runtime 里面的“全屋智能中枢”它不是 controller 本身但所有 controller 都挂在它下面。它把开发一个 controller 过程中高度重复的活全部集中起来包括提供“带缓存的 client”读写 Kubernetes API 不用每次手动走 API Server。维护 cache/informer让 controller 只关心 local cache 里的事件不需要自己管理 ListWatch。统一注册和启动所有 controller、webhook、自定义 Runnable。处理 leader election保证多副本下只有一份 controller 在干活。暴露 metrics、健康检查、pprof 端点。管理优雅退出和 context 传递。换句话说如果没有 Manager你得自己写 informer factory、自己管理 workqueue、自己处理并发同步、自己做 leader election。这些逻辑每个 controller 都一样重复写不仅浪费时间还容易在细节上漏掉。Manager 存在的意义就是把这些通用能力内聚化让业务开发者只关注Reconcile(ctx, req) (Result, error)这一个函数。我在没有 Manager 的时代用 client-go 写过 controller。说实话单 controller 还能撑住一旦要同时监听 Deployment、ConfigMap、Pod还要处理资源关联关系代码结构会迅速失控。informer 注册顺序、线程安全、事件消费速率、缓存同步等待每一个环节都可能踩坑。换成 controller-runtime 的 Manager 后上述问题我从代码里直接消失了因为它已经帮我屏蔽掉了大部分并发和事件流细节。1.2 没有 Manager 时你的 controller 要面对什么这里做个反推你才能理解 Manager 的价值。如果你直接用 client-go 写基础流程是创建kubernetes.Clientset、创建informers.NewSharedInformerFactory、为每种资源注册 event handler、启动 informer、等 cache sync、然后从workqueue.RateLimitingInterface消费 key。这还没算重试机制、事件过滤、错误处理。等你要同时监听多个资源就需要维护多个 informer并且把它们的事件统一丢进同一个队列。如果这时再引入 leader election又要在启动前先抢锁、抢到锁再启动 informer整体启动序列开始变得脆弱。Manager 的价值不在于多高级而在于把“controller 生命周期”和“基础依赖”绑定在一起。你在它的Add方法里塞进去一个 Runnable它可以帮你保证等缓存同步完成后才开始干活退出时按注册顺序反向关闭并且通过Runnable.PreShutdown这种钩子给你清理资源的机会。这就是为什么几乎所有基于 controller-runtime 的项目最终都围绕 Manager 组织代码。它给出来的不只是一种写法更是一套完整的“controller 进程生命周期模型”。2. Manager 的启动链路到底在做什么2.1 manager.New 阶段一切都还只是初始化很多人以为manager.New会立刻创建一堆客户端并连接 API Server其实不是。它只做配置和对象构造真正的连接都在mgr.Start(ctx)之后才发生。阅读源码会发现manager.New的核心动作分好几层先处理 Options缺省项全部填上默认值。创建Metrics相关 listener默认绑定:8080提供/metrics。创建Cache对象但不是马上启动 ListWatch。创建Client对象注意它是包装 cache 的“分层 client”读路径走 cache写路径走 API Server。初始化 event recorder、日志、字段索引管理器。如果配置了 leader election会在内部生成一个用于抢锁的 runnable group。把所有需要启动的内部组件注册到一个runnables队列里包括 leader election 阶段需要的组件和普通组件。这里最关键的一点是Manager 在 start 之前不是一个“活的”东西它更像一个已经排好序的启动清单。所以如果你想在manager.New之后立刻用它的 client 做一次查询大概率会拿到“缓存还没同步”的错误或者什么也查不到因为真正的 informer 还没跑起来。我见过很多同学在main.go里 manager.New 后立刻去mgr.GetClient().Get然后发现偶尔成功偶尔失败。这完全不是随机问题而是你的缓存可能还没有Synced。正确做法是把这种启动前查询放到一个自定义 Runnable 的Start方法里等manager.Start触发后通过Cache 的 WaitForCacheSync再执行查询。2.2 Start 之后的内部序列mgr.Start(ctx)一旦被调用你会看到整个生命周期才开始真正推进。整个过程大致是启动 health probe listener 和 metrics server。优先启动 leader election 前的 Runnable比如用于记录 ready 的 health 检查。如果开启 leader election先启动抢锁 goroutine拿到锁之后才启动主 Runnable 组。主 Runnable 组包含 cache 的启动、controller 启动、webhook 启动以及所有通过mgr.Add注册的组件。所有 Runnable 的Start(ctx)内部会自己处理阻塞逻辑例如 cache 启动后会运行 goroutine不会被单个 informer 卡死。当 context 被取消Manager 会依次调用每个 Runnable 的PreShutdown和Start返回后的清理逻辑最终退出。其中“启动顺序”不是随便定的。Controller-runtime 源码里把 Runnable 分成多个组leaderElectionRunnables、nonLeaderElectionRunnables、runnableGroup等并用runnableGroup.Start中的 channel 控制并发与返回值。这个机制保证了 controller 不会在 cache sync 之前启动否则依赖 cache 的Reconcile函数一开始就会读到空缓存。为什么要特别关注这个因为自定义 Runnable 如果直接写在mgr.Start之前 goroutine 里跑它可能没有依赖基础设施就启动了但如果你通过mgr.Add注册manager 会帮你控制它跟其他组件之间的启动关系。这个差异直接影响你是否会遇到“启动后数据没就绪”的问题。2.3 Leader Election 的细节隐患在 controller-runtime 中Manager 的 Options 里只要把LeaderElection设为 true就会自动启用选主。它默认使用configmaps或leases作为锁资源通过启动一个 goroutine 调用leaderelection.RunOrDie来实现。经验是如果你的项目以 Deployment 多副本方式运行却把LeaderElection设成了 false那每个副本都会同时执行 Reconcile资源竞争、重复更新、甚至状态抖动都会出现。反之有些只在开发环境跑的单副本项目开了 leader election 也没问题不过要注意锁资源需要创建权限。锁资源选择也很关键。默认的LeaderElectionResourceLock在较新版本是leases在旧版本可能是configmapsleases。如果你的 RBAC 只给了configmaps的 get/update 权限却没给leases运行时会报leader election lock already exists之类的错误。我之前排查过一个诡异现象本地用 admin kubeconfig 跑一切正常到某个受限命名空间就反复重启最后发现就是锁资源权限缺失。还要记得填LeaderElectionID。如果没填框架会自动生成一个但生成规则往往包含当前进程名导致多副本抢的锁名不一致这样 leader election 就形同虚设。我在生产环境习惯显式设置一个固定 ID比如my-controller-leader-election确保所有副本抢同一把锁。3. 手把手把 Manager 跑起来3.1 一个最简可运行的 Manager 骨架下面这份代码是“最小可用”级别去掉了一切浮夸装饰只用标准库和 controller-runtime 的核心逻辑package main import ( context fmt os os/signal syscall k8s.io/apimachinery/pkg/runtime k8s.io/client-go/rest sigs.k8s.io/controller-runtime/pkg/builder sigs.k8s.io/controller-runtime/pkg/client sigs.k8s.io/controller-runtime/pkg/controller sigs.k8s.io/controller-runtime/pkg/manager sigs.k8s.io/controller-runtime/pkg/manager/signals sigs.k8s.io/controller-runtime/pkg/reconcile ) type demoReconciler struct { client client.Client } func (r *demoReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { // 这里只打一条日志业务逻辑先跳过 fmt.Printf(received request: %s/%s\n, req.Namespace, req.Name) return reconcile.Result{}, nil } func main() { if err : run(); err ! nil { fmt.Fprintf(os.Stderr, manager failed: %v\n, err) os.Exit(1) } } func run() error { // 1. 从 kubeconfig 或集群内配置构建 REST 配置 restConfig, err : rest.InClusterConfig() if err ! nil { // 开发环境的退路 restConfig, err clientcmd.NewNonInteractiveDeferredLoadingClientConfig( clientcmd.NewDefaultClientConfigLoadingRules(), clientcmd.ConfigOverrides{}, ).ClientConfig() if err ! nil { return err } } // 2. 创建 Manager mgr, err : manager.New(restConfig, manager.Options{ LeaderElection: true, LeaderElectionID: demo-leader-election, }) if err ! nil { return err } // 3. 注册 controller绑定到 manager 管理的 cache/client err builder.ControllerManagedBy(mgr). Named(demo-controller). For(corev1.ConfigMap{}). Complete(demoReconciler{client: mgr.GetClient()}) if err ! nil { return err } // 4. 启动 Manager监听系统信号 ctx : signals.SetupSignalHandler() return mgr.Start(ctx) }这段代码虽然短但已经把核心链路拉通了manager.New创建 Managerbuilder.ControllerManagedBy(mgr)注册 controllermgr.Start启动一切。你可以在本地集群直接跑通过打日志看到 Reconcile 被触发的时机。3.2 注册 Controller 时为什么一定要传入 Managerbuilder.ControllerManagedBy(mgr)这行很多初学者不理解为什么 Controller 不能自己独立存在因为 controller 需要四样东西一个 cache 来监听资源、一个 client 来读写对象、一个 event recorder 来上报事件、一个 logger 来打印日志。这些全部由 Manager 提供。当你传mgr进去时builder 会从它身上提取这些依赖并包好 ownership 关系。在源码层面builder.ControllerManagedBy(mgr)本质上是build(mgr, ctrl.Options{})它内部会调用controller.New(unmanaged, name, options)随后调用r.Watches之类的逻辑。由于传入的是 manager 而不是裸的 clientcontroller 才会被放进 Manager 的 runnable 队列从而在mgr.Start时一起起来。如果你直接把一个 controller 在 manager 外部自己用 goroutine 启动从功能上也不是不可能但你会失去 manager 提供的优雅退出、缓存同步等待、日志注入等能力。长期维护下去代码会慢慢长出很多重复的“手写依赖倒置”逻辑非常难受。3.3 Options 参数与适用场景我整理过一份使用频率最高的 Options 清单这些字段看起来不起眼实际影响都很大Options 字段典型取值影响Scheme注册了所有 CRD 的 runtime.Scheme不注册会导致无法识别自定义资源MetricsBindAddress:8080 或 0是否暴露 metrics设为 0 表示禁用HealthProbeBindAddress:8081启动 readiness/liveness 接口容器探针必备LeaderElectiontrue / false多副本时必须开启否则多份抢跑LeaderElectionID固定字符串多副本必须一致否则选主失效Cache.DefaultNamespacesmap[string]cache.Config限定 controller 只 watch 指定 namespaceNewCache自定义 Cache 实现极少改通常用默认NewClient自定义 Client 实现可用于接入私有 apiserver 或做拦截GracefulShutdownTimeouttime.Duration决定退出前等待 runnable 清理的时间这里特别说明Scheme。很多朋友在 manager.New 时只传了一个空runtime.Scheme导致之后Complete时能注册 controller但 Reconcile 里一旦调用client.Get就会报no kind registered for the type v1.ConfigMap。原因就是 scheme 里没有corev1.AddToScheme甚至没有clientgoscheme.AddToScheme。我在初始化阶段会固定用以下三行scheme : runtime.NewScheme() _ clientgoscheme.AddToScheme(scheme) // 内置资源 _ corev1.AddToScheme(scheme) // 也可以合并进上一行这里为了清晰 _ myapi.AddToScheme(scheme) // 你的自定义 CRD如果你的项目是通过 kubebuilder 生成的main.go里已经有Scheme初始化逻辑不要因为看着“自动完成”就忽略它。一旦新增了自定义 CRD 的 API 包要手工把对应AddToScheme加进去。4. Manager 常见问题与排查指南4.1 启动即退出Leader Election 失败最常见的失败现场是程序启动后没几秒日志就出现failed to acquire lease demo-leader-election: the client is not configured to use a configuration with leader election或者是类似 “error creating leader election lock”。这种基本可以定位为要么 RBAC 没给对应锁资源权限要么锁资源类型和实际允许的类型不一致。排查时我一般三步走确定集群里锁资源是否已经存在kubectl get leases -n namespace。检查当前运行账号是否有coordination.k8s.io的leases的 get/list/create/update 权限。查看 Deployment 的args或 env 里是否覆盖了 LeaderElectionID如果多个副本启动参数不一致锁名就会不同等于没选主。另外一个容易被忽视的场景是本地开发时自己电脑上可能同时跑着多个进程都使用同一个 kubeconfig 和同一个 LeaderElectionID也会争抢锁。如果你只是想本地调试建议在 main 里加个环境变量开关本地默认把LeaderElection置为 false。4.2 Reconcile 跑不到缓存同步一直听不懂有时 Manager 能启动但 controller 事件迟迟不触发。可以在日志里看到waiting for cache sync to complete这是正常的因为 Manager 在启动时会等待 controller 依赖的 informer 完成首次 ListWatch 同步。但如果一直卡在这里通常有两种原因一是 RBAC 权限不足。controller 使用的 client 是通过 manager 创建的而这个 client 的读路径走 cache也就是说它需要权限去 List/Watch 对应资源。比如你没有configmaps的 list/watch 权限informer 就永远无法完成同步。处理办法是检查 controller 所在 ServiceAccount 的 Role/RoleBinding 或 ClusterRole/ClusterRoleBinding确保resources和verbs都包含get/list/watch。二是资源量太大导致同步过慢。如果集群里有一个 namespace 下有几十万个 ConfigMapinformer 首次 List 可能要花不少时间。这不算 bug但可以通过限定Cache.DefaultNamespaces来缩小 watch 范围降低启动时的压力。4.3 读性能和写行为Cache 与 Client 的关系Manager 的GetClient默认带缓存也就是读操作走 local cache速度很快但会有些“失真”——刚创建的资源可能在一两秒内读不到。这是缓存机制造成的正常现象。如果你需要在某个 API 里立刻读取刚刚Create的数据建议不要依赖 caches 的强一致性而是用 uncached client。Controller-runtime 提供了client.New直接创建非缓存客户端或者通过APIReader绕过缓存。但要注意直接读 API Server 会增加请求压力不要全部替代默认 client。我们可以把“强一致读”的场景单独拉出来用mgr.GetAPIReader().Get(...)完成。在某些项目里由于 Reconcile 会高频读写同一个资源默认带 cache 的 client 更容易出现“resourceVersion 冲突”。因为Get拿到的是缓存里的旧版本然后直接Update结果 base 版本不对被 API Server 拒掉。这不是 Manager 的锅而是你的 Reconcile 没有正确使用CreateOrUpdate或Patch机制。建议对更新类逻辑使用controllerutil.CreateOrUpdate或者在 Update 前重新 Get 最新对象。4.4 优雅退出卡死无法完成滚动更新Manager 的Start在 context 取消后会等待所有 Runnable 停止这个等待有默认超时。如果你在自己的 RunnableStart里写了for { select{} }这种永不返回的循环或者 Reconcile 里卡了死循环Manager 就可能无法优雅退出Deployment 滚动更新会被卡住。排查方法很简单GracefulShutdownTimeout默认值一般是 30s如果超时后进程仍没有退出多半是某个 Runnable 没有响应 context 的取消。你自己的 Runnable 必须监听ctx.Done()在收到退出信号时返回。不要把整个逻辑放在一个不可取消的 goroutine 里。另外如果你在 Reconcile 里用time.Sleep模拟重试不要在 sleep 期间不监听 ctx。正确写法是select { case -time.After(retryAfter): case -ctx.Done(): return reconcile.Result{}, nil }5. 一些让 Manager 更好用的扩展姿势5.1 自定义 Runnable把后台任务交给 Manager 管理有些项目需要在 controller 进程里额外起一个定时器周期性扫一遍资源做清理或校验。你当然可以在 main 里直接go func() { ticker }()但这样既不参与 manager 的启动顺序也不参与优雅退出。更规范的做法是实现manager.Runnable接口然后mgr.Add。示例type periodicScanner struct { client client.Client } func (s *periodicScanner) Start(ctx context.Context) error { go func() { ticker : time.NewTicker(5 * time.Minute) defer ticker.Stop() for { select { case -ctx.Done(): return case -ticker.C: // 做扫描 } } }() // Start 方法想让 runnable 保持运行直接阻塞也可以 -ctx.Done() return nil } func (s *periodicScanner) PreShutdown() error { // 清理定时任务资源 return nil }这样当 Manager 收到退出信号PreShutdown会被调用不会再出现“主协程退了后台扫表任务还在跑”的问题。同时这个 Runnable 会并入 manager 的 healthz 检查链路好处是如果这个 Runnable 启动失败manager 可以直接判为不健康。5.2 限定 Namespace提升多租户场景稳定性如果 controller 只负责一个业务组件的资源没必要 watch 全集群。给Cache.DefaultNamespaces配置一个 map可以显著降低 API Server 压力也能避免因为观察到其他 namespace 的资源触发无效 Reconcile。mgr, err : manager.New(restConfig, manager.Options{ Cache: cache.Options{ DefaultNamespaces: map[string]cache.Config{ my-namespace: {}, }, }, })这里有个注意点如果之前有其他权限需要读取 Cluster-scoped 资源比如 Node 或 CRD那么 DefaultNamespaces 不会影响 Cluster-scoped 资源的 watch 行为只有 namespaced 资源才会被 namespace 条件过滤。5.3 把 Manager 封装成自己的启动器很多中大型项目不会直接在所有 controller 入口都重复 manager.New而是封装一个自己的 runner 包统一处理日志、 metrics、健康检查、profile、leader election 这些配置。我见过做得比较顺的版本大概长这样type App struct { Name string Cmd *cobra.Command Options manager.Options } func (a *App) Run() error { // 把应用名映射到 metrics、leader election 前缀 a.Options.MetricsBindAddress fmt.Sprintf(:%d, metricsPort()) a.Options.HealthProbeBindAddress fmt.Sprintf(:%d, healthPort()) a.Options.LeaderElectionID a.Name -leader-election mgr, err : manager.New(config.GetRestConfig(), a.Options) // 注册全局 controllers mgr.Add(a.controllers...) return mgr.Start(signals.SetupSignalHandler()) }这种封装的收益是项目里每个新 controller 只要实现manager.Runnable并登记到列表中剩下的启动、优雅退出、监控暴露逻辑完全统一。对团队开发很友好新同学上手时不用理解太多 manager 细节也能把控制器稳定跑起来。我个人在实际项目里的体会是Manager 这个概念比表面上看起来更重要很多 controller 的稳定性问题最后都能追溯到 manager 配置不当或生命周期管理没跟上。把它当成一个“有生命周期、有依赖注入”的组件来对待而不是一个简单的启动函数就会少踩很多坑。如果你刚接触这个库建议先跑通上面的最小骨架再逐步加上 leader election、cache 限定、自定义 Runnable按需扩展就好。

相关新闻

无标题文档如何起步:从需求挖掘到内容落地的完整方法

无标题文档如何起步:从需求挖掘到内容落地的完整方法

有次我打开一个项目文档,标题栏只写了四个字符:“【无标题】”。正文空白,关键词空白,摘要空白。刚开始我也以为是对方手滑没填完,差点直接回一句“请补全需求”。后来想想,这种状态其实比一堆空话更有意思…

2026/10/19 6:22:47 阅读更多 →
水下图像质量评价:UICM核心原理与Python复现指南

水下图像质量评价:UICM核心原理与Python复现指南

做水下图像增强和复原的朋友,十有八九在论文、开源代码里撞见过UIQM和UICM这两个词。我第一次看到它们的时候,脑子里有两个疑问:一是这套“水下图像质量评价指标”和普通图像那套 PSNR、SSIM 到底差在哪;二是UICM明明只是UIQM的一…

2026/10/19 6:22:47 阅读更多 →
Linux I2C驱动开发实战:从内核框架到设备树与调试

Linux I2C驱动开发实战:从内核框架到设备树与调试

做嵌入式Linux开发的朋友,肯定绕不开I2C这个总线。不管你是接了个温度传感器、触摸屏、音频Codec,还是EEPROM存储芯片,I2C都是最常见的外设通信方式之一。做Linux嵌入式驱动开发,I2C驱动这块属于入门必修课,它既不像GP…

2026/10/19 6:21:47 阅读更多 →

最新新闻

Uipath调用Python全攻略:三种主流方式与踩坑指南

Uipath调用Python全攻略:三种主流方式与踩坑指南

你有没有遇到过这样的情况:流程里需要做数据清洗、复杂报表计算,或者要调一个现成的机器学习模型,但Uipath自带的活动库翻来翻去就是找不到合适的,硬用Invoke Code写C#又费劲得要命。我自己的解决思路很直接——把Python拉进来干活…

2026/10/19 6:59:04 阅读更多 →
深度强化学习做量化交易:PPO、A2C与DDPG集成策略实战

深度强化学习做量化交易:PPO、A2C与DDPG集成策略实战

简介:这是一份基于深度强化学习的自动化股票交易策略设计源码,面向金融科技研究者、量化交易入门者及对智能投顾感兴趣的开发者。项目采用PPO、A2C和DDPG三种Actor-Critic算法训练交易代理,通过与股票市场环境交互来学习最优交易决策&#xf…

2026/10/19 6:59:04 阅读更多 →
零基础部署大模型:LFM2-2.6B_rai_1.8.0_medusa_npu_4K本地跑通完整教程(含ModelScope SDK下载)

零基础部署大模型:LFM2-2.6B_rai_1.8.0_medusa_npu_4K本地跑通完整教程(含ModelScope SDK下载)

大模型人工智能基础模型 【免费下载链接】LFM2-2.6B_rai_1.8.0_medusa_npu_4K 项目地址: https://ai.gitcode.com/hf_mirrors/amd/LFM2-2.6B_rai_1.8.0_medusa_npu_4K 点击查看 免费下载 LFM2-2.6B_rai_1.8.0_medusa_npu_4K 是一款 26 亿参数的小型大语言模型&…

2026/10/19 6:59:04 阅读更多 →
游戏存档备份指南:Ludusavi 帮你守住 19,000+ 款游戏的进度

游戏存档备份指南:Ludusavi 帮你守住 19,000+ 款游戏的进度

游戏存档备份指南:Ludusavi 帮你守住 19,000 款游戏的进度 【免费下载链接】ludusavi Backup tool for PC game saves 项目地址: https://gitcode.com/GitHub_Trending/lu/ludusavi 去年我重装系统,才发现某款玩了一百多小时的 RPG,存档藏在旧盘的 AppData 里,有些游戏的…

2026/10/19 6:59:04 阅读更多 →
1 条 SQL 跑通 MiniOB 数据库:从构建、启动到看懂执行链路

1 条 SQL 跑通 MiniOB 数据库:从构建、启动到看懂执行链路

1 条 SQL 跑通 MiniOB 数据库:从构建、启动到看懂执行链路 【免费下载链接】miniob MiniOB is a compact database that assists developers in understanding the fundamental workings of a database. 项目地址: https://gitcode.com/GitHub_Trending/mi/miniob…

2026/10/19 6:59:04 阅读更多 →
提示词工程实战:六要素拆解与三步迭代法,写出稳定高质量AI输出

提示词工程实战:六要素拆解与三步迭代法,写出稳定高质量AI输出

写 Prompt 这件事,我前后折腾了至少两年。最开始我以为,提示词不过就是把需求说清楚,“帮我写一段文案”“给这段代码找 bug”,后来才发现这种想法害了不少人。你把一句话丢给模型,模型就只知道这一句话;模…

2026/10/19 6:58:04 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →