openJiuwen agent-core ByModelNameAllocator 状态序列化重构:从 dict 到 list 的兼容演进
人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习【免费下载链接】agent-coreopenJiuwen agent-core可提供AI Agent开发、运行、调优与演进相关的全套SDK能力项目地址https://gitcode.com/openJiuwen/agent-core点击查看免费下载导读本文聚焦 openJiuwen agent-core 中ByModelNameAllocator按模型名分组的轮转分配器的一次关键序列化重构当团队模型池同时配置glm-5与glm-5.1这类含点号的模型名时旧实现把轮转计数器以dict[model_name, int]形式写入 session checkpoint触发了 session 持久化层expand_nested_structure的 nested-path 误解析导致全量恢复时进程崩溃。本次重构将state_dict()改为 list 序列化每条记录携带model_name与index两个字面字段同时保留对旧 dict 格式的加载兼容。读完本文你将理解崩溃的完整根因链路、新格式的设计动机、state_dict/load_state_dict的源码级实现以及如何用测试基线81 个用例验证这一兼容演进。一、问题背景多模型池中的崩溃现场用户配置了多模型同时包含glm-5与glm-5.1启动 team在 session checkpoint 持久化阶段崩溃错误如下TypeError: NoneType object does not support item assignment File openjiuwen/core/session/utils.py, line 218, in expand_nested_structure current[current_key] expand_nested_structure(value)诊断日志逐层冒泡显示了真正的原因[split_nested_path] inputglm-5.1, output[glm-5, 1] [root_to_path] nested_pathglm-5.1, current_typeint, reasoncurrent is not dict [DEBUG] root_to_path returned None: keyglm-5.1, result_keys[glm-5] [DEBUG TypeError] keyinner_indexes ... [DEBUG TypeError] keymodel_allocator_state ... [DEBUG TypeError] keyjiuwen_team_sess_... ...调用链为team session state →model_allocator_state→inner_indexes→ 处理 keyglm-5.1。二、根因剖析nested-path 误解析与 NoneType 崩溃2.1 旧实现的序列化形态ByModelNameAllocator的旧state_dict()实现把运行时的_inner_indexes: dict[str, int]直接以 dict 形式序列化其中key 就是 model_name{ inner_indexes: {glm-5: 0, glm-5.1: 1}, pool_digest: ..., }这里_inner_indexes记录的是每个模型分组当前的轮转计数游标它是 allocator 的运行时内部状态。问题在于它被直接送进了 session 持久化层。2.2 持久化层的路径语义session 持久化层的核心入口是openjiuwen/core/session/utils.py中的expand_nested_structureutils.pydef expand_nested_structure(data: Any) - Any: if isinstance(data, list) or isinstance(data, tuple): result [] for item in data: result.append(expand_nested_structure(item)) return result elif isinstance(data, dict): result {} for key, value in data.items(): current_key, current root_to_path(key, result, create_if_absentTrue) current[current_key] expand_nested_structure(value) return result ...当数据是 dict 时它对每个 key调用root_to_path(key, result, create_if_absentTrue)把 key 当作nested-path处理。而split_nested_pathutils.py对含.或[的 key 进行拆分def split_nested_path(nested_key: str) - list: ... params nested_key.split(NESTED_PATH_SPLIT) # NESTED_PATH_SPLIT . for param in params: if [ in param: ... else: final_list.append(param) return final_list模块常量定义在文件头部utils.pyNESTED_PATH_SPLIT .NESTED_PATH_LIST_SPLIT [IMMUTABLE_ATOMIC (str, int, float, bool, type(None), bytes, frozenset, complex)。于是glm-5.1被拆成[glm-5, 1]——点号被当作路径分隔符。2.3 崩溃的两条触发路径root_to_path会逐层在结果 dict 中创建中间节点create_if_absentTrue时最终把glm-5.1从字面 key 改写成嵌套结构{glm-5: {1: ...}}。崩溃取决于dict 的遍历顺序先遍历到glm-5.1先创建result[glm-5] {}随后遍历到glm-5时发现它已存在且是 dict……此时第二层再取到None后赋值即崩溃先遍历到glm-5result[glm-5]先被写成标量0IMMUTABLE_ATOMIC直接返回随后遍历到glm-5.1时root_to_path走到中间层发现current[glm-5]是int而非 dictcurrent is not dict返回(None, None)最终current[current_key]对None做 item assignment抛出TypeError: NoneType object does not support item assignmentutils.py 中root_to_path的实现会明确返回(None, None)。前者是数据损坏后者是崩溃——两条路径都不可接受。三、方案决策list 序列化模型名永不落 key 位3.1 新旧格式对比核心决策是state_dict()改为list 序列化每条 record 携带model_name与index两个字面字段load_state_dict()优先读新counterslist向后兼容读旧inner_indexesdict。# new { counters: [ {model_name: glm-5, index: 0}, {model_name: glm-5.1, index: 1}, ], pool_digest: ..., } # legacy (still loadable) { inner_indexes: {glm-5: 0, glm-5.1: 1}, pool_digest: ..., }3.2 决策要点持久化层从此永不把 model_name 放在 dict key 位置——彻底脱离key 是 path 还是字面这个误解空间。模型名在数据形态上被显式表达为 opaque value。pool_digest字段不变digest 不匹配时仍然全部归零既有不变量保持。legacy 路径只在 load 端保留——新 session 一律按 list 写。运行时内部状态self._inner_indexes: dict[str, int]不动——它在进程内不经过 session 持久化层模型名作 key 没有问题仅出口端state_dict做格式翻译。3.3 被拒绝的方案方案被拒绝的理由只修底层expand_nested_structure不动上层底层 fix 确实根除 crash 和数据损坏但上层仍把 model_name 当 dict key 用别的子系统未来再这么做也是一颗潜在地雷用 list 序列化把模型名是 opaque value的语义在数据形态上显式化比让每个 caller 都记得避坑可靠强行限制 model_name 不含./[违反用户预期——glm-5.1、claude-3.5-sonnet、gemini-1.5-pro都是真实在用的模型名不做 legacy 兼容让旧 session 的 pool_digest 不匹配兜底归零会让所有已存 session 的轮转计数器静默清零代价为零的load端 fallback 完全可以保留旧数据四、源码级实现state_dict 与 load_state_dict新实现位于 openjiuwen/agent_teams/models/allocator.py 的ByModelNameAllocator类中。4.1 state_dictlist 化的出口def state_dict(self) - dict: Snapshot per-group counters pool digest for session persistence. return { counters: [ {model_name: name, index: index} for name, index in self._inner_indexes.items() ], pool_digest: self._pool_digest, }这里把_inner_indexes.items()逐条翻译为{model_name, index}记录。docstring 明确解释了动机模型名可能含.或[如glm-5.1、claude-3.5-sonnet而 session 持久化层历史上会把 dict key 中的这类字符当作 nested-path 编码解释——Using a list keeps every model name as an opaque string value.4.2 load_state_dict新格式优先、旧格式兜底def load_state_dict(self, state: dict) - None: if state.get(pool_digest) ! self._pool_digest: self._inner_indexes {name: 0 for name in self._groups} return counters state.get(counters) if isinstance(counters, list): for record in counters: if not isinstance(record, dict): continue name record.get(model_name) if name not in self._inner_indexes: continue try: self._inner_indexes[name] int(record.get(index, 0)) except (TypeError, ValueError): self._inner_indexes[name] 0 return legacy state.get(inner_indexes) if not isinstance(legacy, dict): return for name, raw in legacy.items(): if name not in self._inner_indexes: continue try: self._inner_indexes[name] int(raw) except (TypeError, ValueError): self._inner_indexes[name] 0恢复逻辑的关键路径digest 不匹配 → 全部归零pool_digest不匹配意味着持久化计数针对的是已经变化的池布局保留旧计数会带偏新的轮转归零是唯一安全默认。新格式counterslist逐条读取model_name必须存在于当前分组name not in self._inner_indexes则跳过——容忍池布局变化index非数字时容错归零。旧格式inner_indexesdict老 session 升级后仍能正确恢复计数不会静默清零。4.3 防御性契约ModelAllocator协议allocator.py要求所有 allocator 实现allocate/state_dict/load_state_dict三个方法并明确load_state_dict的防御要求容忍缺键从 0 开始、未知键忽略、pool_digest不匹配计数器全部归零或保持默认。state_dict()的输出必须能经json.dumps/json.loadsround-trip。4.4 pool_digest 的不变量_pool_digestallocator.py对每条 entry 取(model_name, api_base_url)按池序拼接 sha1def _pool_digest(pool: list[ModelPoolEntry]) - str: h hashlib.sha1(usedforsecurityFalse) for entry in pool: h.update(entry.model_name.encode(utf-8)) h.update(b\x00) h.update(entry.api_base_url.encode(utf-8)) h.update(b\x1f) return h.hexdigest()凭证或 metadata 变更不刷 digest——它们 in-place 刷新而不使 allocator 计数失效池条目的增删 / 重排会改变 digest触发load_state_dict时计数归零。对应测试test_pool_digest_stable_under_credential_refresh验证了旋转 api_key 后计数保留这一不变量。五、验证81 个用例与新增 regression 覆盖5.1 测试基线pytest tests/unit_tests/agent_teams/models/test_allocator.py81 passed。测试文件覆盖四种内置策略RoundRobinModelAllocator、ByModelNameAllocator、RouterAllocator、IntelliRouterAllocator、build_model_allocator工厂、池条目物化、session 持久化 round-trip 与resolve_member_model位置查找。5.2 新增 regression 用例用例一带点号模型名的 round-triptest_by_model_name_state_dict_round_trips_dotted_model_names。池含glm-5/glm-5.1/claude-3.5-sonnet先断言state_dict的counters是 list再验证load_state_dict后轮转计数无误pool [ _make_named_entry(glm-5, g5a), _make_named_entry(glm-5, g5b), _make_named_entry(glm-5.1, g51a), _make_named_entry(claude-3.5-sonnet, c35), ] a ByModelNameAllocator(pool) a.allocate(model_nameglm-5) a.allocate(model_nameglm-5.1) snapshot a.state_dict() # counters must be a list so persistence never re-parses model names. assert isinstance(snapshot[counters], list) by_name {record[model_name]: record[index] for record in snapshot[counters]} assert by_name {glm-5: 1, glm-5.1: 1, claude-3.5-sonnet: 0} b ByModelNameAllocator(pool) b.load_state_dict(snapshot) assert b.allocate(model_nameglm-5).to_team_model_config().model_client_config.api_base http://g5b assert b.allocate(model_nameglm-5.1).to_team_model_config().model_client_config.api_base http://g51a用例二legacy dict 格式兼容test_by_model_name_load_state_dict_accepts_legacy_dict_format。旧inner_indexesdict 格式仍能正确恢复 counterslegacy_state {inner_indexes: {gpt-4: 1, claude: 1}, pool_digest: digest} a.load_state_dict(legacy_state) assert a.allocate(model_namegpt-4).to_team_model_config().model_client_config.api_base http://a2 assert a.allocate(model_nameclaude).to_team_model_config().model_client_config.api_base http://c25.3 既有用例迁移与新格式容错既有test_by_model_name_state_dict_resumes_per_group_rotation、test_persist_leader_config_includes_allocator_state等 round-trip 用例同步迁移到新counterslist 断言如后者断言snapshot[counters]中{gpt-4: 1, claude: 1}且pool_digest存在。test_by_model_name_load_state_dict_tolerates_malformed_input同步覆盖新格式的非法输入容忍counters非 list如not-a-list、index非数字如bogus均安全降级为计数 0。集成侧test_persist_leader_config_includes_allocator_state验证了ByModelNameAllocator经TeamAgent._persist_leader_config写入 session 后state[teams][t][model_allocator_state][counters]形状正确。六、在 session 持久化链路中的位置6.1 写入侧model_allocator_state是 session checkpoint 中 per-team 命名空间的一员。按 S_04 session-and-recovery spec 与 runtime/metadata.py结构为state[teams][team_name] { spec: ..., # TeamAgentSpec.model_dump() context: ..., # TeamRuntimeContext.model_dump() model_allocator_state: ..., # optional —— allocator.state_dict() 输出 lifecycle: running|paused, # optional db_state: pending_create|created|cleaned, pending_resume: {query: ...}, # optional checkpoints: {name: count}, # optional }写入由 recovery_manager.py 的persist_leader_config完成spec/context全量覆盖allocator.state_dict()作为model_allocator_state一并写入round 内增量走persist_allocator_state的merge_team_namespace。6.2 恢复侧冷恢复时TeamAgent.recover_from_session见 team_agent.pyallocator_state bucket.get(model_allocator_state) if allocator_state: agent.restore_allocator_state(allocator_state)restore_allocator_state在 agent_configurator.py 中实现先按当前team_spec.model_pool重建 allocatorfresh 计数器 当前pool_digest再load_state_dict(saved_state)。digest 不匹配 → 计数器归零匹配 → rotation 接续。6.3 完整生命周期spec → build_model_allocator → allocator instancein-memory │ allocate() ←─┤ │ state_dict()─┤── session checkpoint[teams][name][model_allocator_state] │ load_state_dict(saved) ←┘ ← 恢复时七、已知遗留与同类问题处理指引RoundRobinModelAllocator/RouterAllocator不受影响它们的state_dict本来就不含 dict-of-model-name。RoundRobinModelAllocator持久化{index, pool_digest}RouterAllocator/IntelliRouterAllocator无轮转计数器仅持久化{pool_digest}load_state_dict是 no-op详见 allocator.py 与 allocator.py。底层兜底已就位仓库其它地方如果再出现把用户输入字符串当 dict key 塞进 session state的代码靠下层expand_nested_structure的字面递归 fix 兜底。同类 caller 的处理范式未来如发现新的同类 caller按本 feature 同款方式改 list 序列化——把用户输入是 opaque value的语义在数据形态上显式化而不是依赖每个调用方规避./[字符。八、相关设计文档与规约F_16 feature 文档F_16_by-model-name-allocator-list-serialisation.md——本文即基于该 feature 展开S_11 models pool and allocation specS_11_models-pool-and-allocation.md——定义了ModelPoolEntry/ModelRouterConfig/IntelliRouterConfig、四种分配策略语义、ModelAllocator协议、Allocation.to_db_ref持久化身份(model_name, model_index)、state_dict/load_state_dict的 round-trip 契约以及pool_digest只覆盖结构维度(model_name, api_base_url)的不变量S_04 session and recovery specS_04_session-and-recovery.md——model_allocator_state在 checkpoint 中的存放位置与写入/恢复时机。结语ByModelNameAllocator的 list 序列化重构是一次典型的持久化边界修复问题表象在 session 层根因却在 allocator 把模型名当 dict key 的数据形态设计上。通过将出口端数据形态与运行时内部状态解耦——内部继续用dict[str, int]高效轮转出口用 list 承载 opaque model_name——既彻底消除了 nested-path 误解析的崩溃面又以零成本保留旧 session 的兼容加载最终以 81 个通过的单测把不变量钉死。这个模式用户输入字符串不进 dict key 位值得在 agent_teams 乃至全仓库的 session 状态设计中作为通用纪律沿用。赞分享人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习【免费下载链接】agent-coreopenJiuwen agent-core可提供AI Agent开发、运行、调优与演进相关的全套SDK能力项目地址https://gitcode.com/openJiuwen/agent-core点击查看免费下载相关推荐openJiuwen agent-core 演进 checkpointing 全解析Trainer 状态快照与 Skill 经验 EvolutionStoreopenJiuwen agent core 演进 checkpointing 全解析Trainer 状态快照与 Skill 经验 EvolutionStore人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习openJiuwen Agent Core API 文档体系导读从 core、agent_teams 到 harness 与自演进框架openJiuwen Agent Core API 文档体系导读从 core、agent_teams 到 harness 与自演进框架 openJiuwen人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习CANN算子挑战赛Erf实现团队信息 团队名称 JDpan_Lemon 所属单位 南京理工大学 团队成员 潘金铎 负责赛题解读与全部代码开发、实现Host侧与Kernel侧的流程CANN文档高性能计算创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Splash模型怎么选:GGUF、MLX 4-bit与NVFP4量化格式完整选型指南(24GB内存Mac必读)

Splash模型怎么选:GGUF、MLX 4-bit与NVFP4量化格式完整选型指南(24GB内存Mac必读)

【免费下载链接】splash A local inference engine for Apple silicon, built around the model. 项目地址: https://gitcode.com/gh_mirrors/splash20/splash 点击查看 免费下载 Splash 是一款专为 Apple silicon 打造的本地推理引擎,让你在一台 Mac 上…

2026/10/12 22:18:41 阅读更多 →
Cppcheck嵌入式静态分析实战:从代码缺陷到CI门禁

Cppcheck嵌入式静态分析实战:从代码缺陷到CI门禁

1. 为什么嵌入式项目需要静态分析1.1 嵌入式代码的痛苦来源做嵌入式开发的朋友,大概都有过这样的经历:代码在本地编译时一切正常,烧进芯片跑几小时甚至几天后,系统莫名死机;或者某个功能在特定输入下才偶发出错&#x…

2026/10/12 22:18:40 阅读更多 →
xhs-visual-director-skill 完整工作流演示:如何把「Vibe Coding」做成8页小红书图文

xhs-visual-director-skill 完整工作流演示:如何把「Vibe Coding」做成8页小红书图文

AI 技能AI 应用媒体生成 【免费下载链接】xhs-visual-director-skill 这是一个用于规划小红书图文的 Agent Skill。它不是普通文案助手,而是一个“视觉导演”:先判断内容任务,再选择适合的视觉风格,最后输出完整图文结构、逐页视觉…

2026/10/12 22:18:40 阅读更多 →

最新新闻

Label Studio:两条 Docker 命令完成第一次数据标注并导出模型训练格式

Label Studio:两条 Docker 命令完成第一次数据标注并导出模型训练格式

Label Studio:两条 Docker 命令完成第一次数据标注并导出模型训练格式 【免费下载链接】label-studio Label Studio is a multi-type data labeling and annotation tool with standardized output format 项目地址: https://gitcode.com/GitHub_Trending/la/labe…

2026/10/13 2:15:26 阅读更多 →
Gemini cli 源码分析之工具篇:ReadFile 工具从入口到落盘的完整链路拆解

Gemini cli 源码分析之工具篇:ReadFile 工具从入口到落盘的完整链路拆解

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

2026/10/13 2:15:26 阅读更多 →
5 分钟跑通 ArtCraft:一条脚本启动 AI 图像生成桌面应用

5 分钟跑通 ArtCraft:一条脚本启动 AI 图像生成桌面应用

5 分钟跑通 ArtCraft:一条脚本启动 AI 图像生成桌面应用 【免费下载链接】artcraft ArtCraft is an intentional crafting engine for artists, designers, and filmmakers 项目地址: https://gitcode.com/GitHub_Trending/ar/artcraft ArtCraft 是一个面向艺…

2026/10/13 2:15:26 阅读更多 →
AI Agent 架构设计:上下文窗口压缩(OpenClaw、Claude Code、Hermes Agent 对比)——用 TaoToken 统一 Key 跑通三家实测

AI Agent 架构设计:上下文窗口压缩(OpenClaw、Claude Code、Hermes Agent 对比)——用 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/13 2:15:26 阅读更多 →
Claude Code 最全使用指南:CLAUDE.md、rules、skills、memory 一次讲清,TaoToken 统一 Key 接入

Claude Code 最全使用指南:CLAUDE.md、rules、skills、memory 一次讲清,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/13 2:15:26 阅读更多 →
从 “My excellent classmates“ 看辅导型 GPT 自定义指令的完整设计范式

从 “My excellent classmates“ 看辅导型 GPT 自定义指令的完整设计范式

提示工程AI 安全治理 【免费下载链接】TheBigPromptLibrary A collection of prompts, system prompts and LLM instructions 项目地址: https://gitcode.com/gh_mirrors/th/TheBigPromptLibrary 点击查看 免费下载 导读 本文以 TheBigPromptLibrary 仓库中收录的…

2026/10/13 2:14:26 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →