Cloudflare Agents SDK 开发实战:基于 Durable Objects 构建有状态 AI Agent 的完整 API 指南
【免费下载链接】autoskillsOne command. Your entire AI skill stack. Installed.项目地址https://gitcode.com/gh_mirrors/au/autoskills点击查看免费下载本篇技术指南以 Cloudflare Agents SDK API 参考 为核心系统讲解如何在 Cloudflare Workers 上用 Durable Objects 构建具备持久状态、实时 WebSocket、SQLite 存储、定时调度与 AI 能力的智能体。读完本文你将掌握AIChatAgent与Agent两大核心类的全部生命周期钩子、setState状态同步、callableRPC 调用、MCP 工具集成、任务队列调度以及配套的 React 客户端钩子可直接落地聊天机器人、实时协作、邮件处理与后台任务等场景。一、SDK 概览两条构建路径怎么选Agents SDK 的价值在于把 Durable Objects 的强一致状态、WebSocket 长连接、SQLite 存储、定时任务与 Workers AI 推理能力封装为一套面向 AI 智能体的编程模型让你一次编写、全球分布、持久记忆。从本仓库的 README 可以看到它内置两套从属类对应两类典型需求使用场景基类关键能力AI 聊天界面AIChatAgent自动流式输出、工具调用、自动管理的消息历史、断线续传MCP 工具提供方Agent MCP向 AI 系统暴露工具自定义逻辑/路由Agent完全控制WebSocket、Email、SQL实时协作AgentWebSocket 状态同步、广播邮件处理AgentonEmail()处理器包入口方面服务端使用agents包Agent 类与生命周期前端分别使用agents/reactuseAgentWebSocket 钩子与agents/ai-reactuseAgentChat聊天 UI 钩子。安装依赖时基础 Agent 只需npm install agents聊天型 Agent 还需npm install cloudflare/ai-chat ai ai-sdk/react。二、AIChatAgent开箱即用的 AI 聊天智能体对于绝大多数对话 工具场景AIChatAgent是最快路径。它内置自动流式输出auto-streaming、消息历史管理、工具调用与可续传流resumable streaming你只需要重写一个onChatMessage钩子import { AIChatAgent } from cloudflare/ai-chat; import { openai } from ai-sdk/openai; export class ChatAgent extends AIChatAgentEnv { async onChatMessage(onFinish) { return this.streamText({ model: openai(gpt-4), messages: this.messages, // Auto-managed message history tools: { getWeather: { description: Get weather, parameters: z.object({ city: z.string() }), execute: async ({ city }) Sunny, 72°F in ${city} } }, onFinish, // Persist response to this.messages }); } }几点关键说明this.messages由框架自动管理用户消息与模型回复经onFinish回调都会自动持久化无需手动维护数组streamText返回流式响应配合AIChatAgent实现断线后自动续传——参考 gotchas.md 中Resumable stream not resuming条目续传要求流 ID 确定而AIChatAgent会自动处理无需你关心消息历史是无限累积的gotchas.md 明确建议在onChatMessage中定期裁剪例如只保留最近 50 条避免 token 超限。三、Agent 基类与生命周期钩子当需要完全掌控连接、邮件、SQL 或自定义协议时使用基础Agent类。它的泛型签名是AgentEnv, State, ConnState三个类型参数分别约束环境绑定、智能体状态与单个连接状态import { Agent } from agents; export class MyAgent extends AgentEnv, State { // Lifecycle methods below }onStart初始化与重启onStart()在智能体首次创建或Durable Object 休眠后重启时执行适合建表、注册 MCP 服务等一次性初始化onStart() { // Init/restart this.sqlCREATE TABLE IF NOT EXISTS users (id TEXT, name TEXT); }onRequestHTTP 请求入口async onRequest(req: Request) { // HTTP const {pathname} new URL(req.url); if (pathname /users) return Response.json(this.sql{id,name}SELECT * FROM users); return new Response(Not found, {status: 404}); }sql标签模板返回的是参数化查询结果配合泛型{id,name}可得到类型安全的结果集。onConnect / onMessageWebSocket 生命周期async onConnect(conn: ConnectionConnState, ctx: ConnectionContext) { // WebSocket conn.accept(); conn.setState({userId: ctx.request.headers.get(X-User-ID)}); conn.send(JSON.stringify({type: connected, state: this.state})); } async onMessage(conn: ConnectionConnState, msg: WSMessage) { // WS messages const m JSON.parse(msg as string); this.setState({messages: [...this.state.messages, m]}); this.connections.forEach(c c.send(JSON.stringify(m))); }注意conn.accept()是必须的第一步——gotchas.md 将未调用 accept 导致 WebSocket 超时列为常见错误。conn.setState只影响单个连接的conn.state而this.setState影响所有客户端可见的共享状态this.connections是当前所有活跃连接的集合天然支持广播。onEmail邮件路由async onEmail(email: AgentEmail) { // Email routing this.sqlINSERT INTO emails (from_addr,subject,body) VALUES (${email.from},${email.headers.get(subject)},${await email.text()}); }四、State、SQL 与调度有状态智能体的三大支柱状态管理setState 自动同步状态基于 SQLite 持久化setState会自动同步到所有已连接的客户端// State this.setState({count: 42}); // Auto-syncs this.setState({...this.state, count: this.state.count 1});gotchas.md 反复强调一个反模式绝不能直接修改this.state.count必须用不可变更新this.setState({...this.state, count: this.state.count 1})否则状态不会同步。同时建议大块数据日志、大列表存入 SQL 而非 state无界数组消息、日志要周期性裁剪。SQL参数化查询防注入// SQL (parameterized queries prevent injection) this.sqlCREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, name TEXT); this.sqlINSERT INTO users (id,name) VALUES (${userId},${name}); const users this.sql{id,name}SELECT * FROM users WHERE id ${userId};注意${userId}是占位符参数不是字符串插值——写成sql...WHERE id ${userId}就是 SQL 注入漏洞见 gotchas.md。建表应放在onStart()而非onRequest()避免每个请求都重复执行 DDL。调度一次性、延时与 Cron// Scheduling await this.schedule(new Date(2026-12-25), sendGreeting, {msg:Hi}); // Date await this.schedule(60, checkStatus, {}); // Delay (sec) await this.schedule(0 0 * * *, dailyCleanup, {}); // Cron await this.cancelSchedule(scheduleId);schedule支持三种触发方式绝对时间Date、相对延时秒、标准 cron 表达式。配套的getSchedules()可枚举已注册任务用于监控配额每个智能体最多 1000 个定时任务见 gotchas.md 的限额表。五、callable RPC跨 WebSocket 的远程方法调用用callable()装饰器声明的方法会被暴露为可通过 WebSocket 调用的 RPC客户端拿到的是普通的 async 方法import { Agent, callable } from agents; export class MyAgent extends AgentEnv { callable() async processTask(input: {text: string}): Promise{result: string} { return { result: await this.env.AI.run(cf/meta/llama-3.1-8b-instruct, {prompt: input.text}) }; } } // Client: const result await agent.processTask({ text: Hello }); // Must return JSON-serializable values两个硬性约束返回值必须可 JSON 序列化——gotchas.md 举例说明返回new Date()这类对象会失败应返回{ timestamp: Date.now() }不要开启 tsconfig 的experimentalDecorators——独立 skill agents-sdk/SKILL.md 明确警告这会破坏callable解析。六、连接管理与 Workers AI 集成连接对象操作// Connections (type: AgentEnv, State, ConnState) this.connections.forEach(c c.send(JSON.stringify(msg))); // Broadcast conn.setState({userId:123}); conn.close(1000, Goodbye);泛型第三个参数ConnState直接类型化conn.state让每个连接携带独立的元数据如用户 ID、玩家 ID。Workers AI 推理与手动流式// Workers AI const r await this.env.AI.run(cf/meta/llama-3.1-8b-instruct, {prompt}); // Manual streaming (prefer AIChatAgent) const stream await client.chat.completions.create({model: gpt-4, messages, stream: true}); for await (const chunk of stream) conn.send(JSON.stringify({chunk: chunk.choices[0].delta.content}));官方建议聊天场景优先AIChatAgent自动流式、自动续传手动流式仅用于自定义协议。AI 调用建议包 try/catch 并准备降级方案gotchas.md 的 AI Gateway unavailable 条目。七、MCP 集成把外部工具暴露给 LLMAgents SDK 内置 Model Context ProtocolMCP客户端注册远程 MCP 服务器后其工具会转换为 AI SDK 工具直接传给模型// Register use MCP server await this.mcp.registerServer(github, { url: env.MCP_SERVER_URL, auth: { type: oauth, clientId: env.GITHUB_CLIENT_ID, clientSecret: env.GITHUB_CLIENT_SECRET } }); const tools await this.mcp.getAITools([github]); return this.streamText({ model: openai(gpt-4), messages: this.messages, tools, onFinish });配套配置见 configuration.mdOAuth 密钥通过wrangler secret put GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET注入服务器 URL 通过wrangler.jsonc的vars.MCP_SERVER_URL配置。一个关键坑是MCP 连接不跨休眠存活——应在onStart()中重新注册服务器见 gotchas.md。八、任务队列与清理钩子内置 FIFO 队列await this.queue(processVideo, { videoId: abc123 }); // Add task const tasks await this.dequeue(10); // Process up to 10queue()入队、dequeue()批量取出消费适合与调度配合实现定时批量处理参考 patterns.md 的 TaskQueue 模式每 5 分钟 cron 调度processQueue逐个dequeue(10)处理视频转码等长任务。上下文与销毁const agent getCurrentAgentMyAgent(); // Get current instance async destroy() { /* cleanup before agent destroyed */ }getCurrentAgent用于在任意位置取回当前智能体实例destroy()在智能体销毁前执行资源清理。九、React 客户端钩子useAgentWebSocket RPC// useAgent() - WebSocket connection RPC import { useAgent } from agents/react; const agent useAgent({ agent: MyAgent, name: user-123 }); // name for idFromName const result await agent.processTask({ text: Hello }); // Call callable methods // agent.readyState: 0CONNECTING, 1OPEN, 2CLOSING, 3CLOSEDname参数对应 Durable Object 的idFromName实现同一用户永远路由到同一实例的确定性寻址。useAgentChat完整聊天 UI// useAgentChat() - AI chat UI import { useAgentChat } from cloudflare/ai-chat/react; const agent useAgent({ agent: ChatAgent }); const { messages, input, handleInputChange, handleSubmit, isLoading, stop, clearHistory } useAgentChat({ agent, maxSteps: 5, // Max tool iterations resume: true, // Auto-resume on disconnect onToolCall: async (toolCall) { // Client tools (human-in-the-loop) if (toolCall.toolName confirm) return { ok: window.confirm(Proceed?) }; } }); // status: ready | submitted | streaming | error参数语义maxSteps限制单轮对话中工具循环的最大迭代次数resume: true在断线后自动恢复流式输出onToolCall实现人在回路human-in-the-loop——服务端把工具execute标记为client见 patterns.md 的 Human-in-the-Loop 模式客户端通过window.confirm等交互代为执行把需要人工确认的动作如扣款、发邮件留在用户侧。十、工程化配置与部署Wrangler 配置无论是基础 Agent 还是 ChatAgentwrangler.jsonc都需要声明 Durable Object 绑定与 SQLite 迁移{ name: my-agents-app, durable_objects: { bindings: [ {name: MyAgent, class_name: MyAgent} ] }, migrations: [ {tag: v1, new_sqlite_classes: [MyAgent]} ], ai: { binding: AI } }来自独立 skill agents-sdk/SKILL.md 的三条硬性提醒每个 Agent 类都要有独立的 DO 绑定 migration 条目永远不要编辑旧的 migrations只能新增 tag需要 Workers AI 时记得加ai: { binding: AI }并在 tsconfig 中加入compatibility_flags: [nodejs_compat]。类型安全的 Env 接口interface Env { AI?: Ai; // Workers AI MyAgent?: DurableObjectNamespaceMyAgent; ChatAgent?: DurableObjectNamespaceChatAgent; DB?: D1Database; // D1 database KV?: KVNamespace; // KV storage R2?: R2Bucket; // R2 bucket OPENAI_API_KEY?: string; // Secrets GITHUB_CLIENT_ID?: string; // MCP OAuth credentials GITHUB_CLIENT_SECRET?: string; QUEUE?: Queue; // Queues }configuration.md 的最佳实践是把所有 DO 绑定都写进 Env 接口以获得编译期类型安全。路由routeAgentRequest 与手动路由推荐直接使用routeAgentRequest辅助函数它按 URL 模式自动把请求路由到对应智能体import { routeAgentRequest } from agents; export default { fetch(request: Request, env: Env) { return routeAgentRequest(request, env); } }多智能体场景按路径前缀分发export default { fetch(request: Request, env: Env) { const url new URL(request.url); if (url.pathname.startsWith(/chat)) { return routeAgentRequest(request, env, ChatAgent); } if (url.pathname.startsWith(/task)) { return routeAgentRequest(request, env, TaskAgent); } return new Response(Not found, { status: 404 }); } }高级场景可手动路由env.MyAgent.idFromName(user-123)得到确定性 ID或idFromString(url.searchParams.get(id))从 URL 参数取随机 ID再get(id)拿到 stub 后stub.fetch(request)。部署命令# Local dev npx wrangler dev # Deploy production npx wrangler deploy # Set secrets npx wrangler secret put OPENAI_API_KEY邮件路由还需在 Cloudflare 控制台配置Workers with Durable Objects目标并在 Worker 入口导出email处理器调用routeAgentEmail详见 configuration.md。十一、典型落地模式与限额参考五个可复用的生产模式来自 patterns.md全部可在仓库中找到完整代码AI Chat w/ToolsAIChatAgenttool()定义getWeather/searchDocs其中searchDocs直接用this.sql做文档检索简易 RAGHuman-in-the-Loop服务端execute: client 客户端onToolCall确认Task Queue Scheduled ProcessingonStart里注册*/5 * * * *crononRequest入队processQueue批量dequeue(10)消费dailyCleanup清理过期日志Manual WebSocket ChatonConnect发历史、onMessage追加消息并广播conn.state.userId记录身份Email Processing w/AIonEmail存库 →generateText摘要 → 广播给在线连接 → 摘要含 urgent 时schedule(0, ...)立即触发自动回复。关键限额摘自 gotchas.md资源/限制数值备注CPU / 请求30s标准/ 300s最大在 wrangler.jsonc 中配置内存 / 实例128MB与 WebSocket 共享存储 / 智能体10GBSQLite 存储定时任务每智能体 1000 个用getSchedules()监控WebSocket 连接数无限制受内存约束SQL 列数每表 100—SQL 行大小2MBKey valueWebSocket 消息32MiB上限DO 请求速率约 1000 req/s / 实例高流量需限流MCP 请求取决于服务器建议重试/退避生产级最佳实践清单状态不可变更新、定期裁剪无界数组、大块数据放 SQLSQL建表放onStart()、全量参数化查询、高频列建索引调度监控getSchedules()数量、完成即取消、周期性任务用 cronWebSocket务必conn.accept()、优雅处理断连、高效广播AI聊天用AIChatAgent、裁剪历史防 token 超限、AI 错误 try/catch 降级部署高流量1000 req/s限流、监控关键错误与存储、MCP 休眠后重注册 重试。结语Cloudflare Agents SDK 把 Durable Objects 的持久性、SQLite 的查询能力、WebSocket 的实时性与 Workers AI 的推理能力整合为一套面向智能体的统一编程模型。本文以 api.md 的 API 参考为骨架补齐了 README 的选型指南、configuration.md 的工程配置、patterns.md 的落地模式与 gotchas.md 的避坑清单。在动手编码前建议先通读本仓库 cloudflare skill 的决策树确认 Agents SDK 是否是你场景的最优解再按Quick Start → 配置 → API → 模式 → 避坑的顺序推进即可。赞分享【免费下载链接】autoskillsOne command. Your entire AI skill stack. Installed.项目地址https://gitcode.com/gh_mirrors/au/autoskills点击查看免费下载相关推荐Cloudflare Agents SDK 完全指南用 Durable Objects 构建有状态 AI Agent 的 API 详解Cloudflare Agents SDK 完全指南用 Durable Objects 构建有状态 AI Agent 的 API 详解 导读 本文基于 autCloudflare Agents SDK 实战指南在 Durable Objects 上构建有状态、实时、全局分布式 AI AgentCloudflare Agents SDK 实战指南在 Durable Objects 上构建有状态、实时、全局分布式 AI Agent Cloudflare人工智能AI 技能AI 插件Cloudflare Agents SDK 实战指南在 Durable Objects 上构建有状态、实时、可调度的 AI Agentautoskills Cloudflare 技能参考Cloudflare Agents SDK 实战指南在 Durable Objects 上构建有状态、实时、可调度的 AI Agentautoskills上一篇Miniflux 2 CI/CD 并行测试加速测试过程下一篇gh_mirrors/sh1/sh的嵌入式部署最小化解析器的构建配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Zabbix 前端 XML 安全基石:xmlseclibs 的 XML 签名与加密实战指南

Zabbix 前端 XML 安全基石:xmlseclibs 的 XML 签名与加密实战指南

指标监控可观测性告警运维 【免费下载链接】zabbix Real-time monitoring of IT components and services, such as networks, servers, VMs, applications and the cloud. 项目地址: https://gitcode.com/gh_mirrors/zabbix2/zabbix 点击查看 免费下载 导读 xmls…

2026/10/10 1:46:44 阅读更多 →
基于Python的深度学习舌苔识别系统GUI实现与模型应用

基于Python的深度学习舌苔识别系统GUI实现与模型应用

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

2026/10/10 1:46:44 阅读更多 →
PCA9422+STM32F415ZG工业级电源管理分层架构设计

PCA9422+STM32F415ZG工业级电源管理分层架构设计

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

2026/10/10 1:45:44 阅读更多 →

最新新闻

Java SPI机制详解:从ServiceLoader到框架扩展原理

Java SPI机制详解:从ServiceLoader到框架扩展原理

参加Java面试时,如果对方问“你们怎么实现接口扩展”或者“框架为什么能自动加载实现类”,八成是想考察SPI机制。SPI全称Service Provider Interface,简单说就是Java原生的“插槽式”扩展机制:你定义一个接口,别人可以…

2026/10/11 0:59:12 阅读更多 →
Hadoop教学级分布式存储源码:伪分布式HDFS交互系统

Hadoop教学级分布式存储源码:伪分布式HDFS交互系统

简介:本资源是一套基于Hadoop构建的完整分布式存储系统实现,面向计算机、人工智能、通信工程等专业的在校学生、教师及初级开发者,适用于课程设计、毕业设计、项目立项演示及分布式系统入门实践。压缩包共203个文件,包含87个运行依…

2026/10/11 0:59:12 阅读更多 →
U2Net证件照抠图实战:发丝级人像分割与白底合成

U2Net证件照抠图实战:发丝级人像分割与白底合成

简介:本资源是一套基于Python与U2Net模型的轻量级证件照智能生成解决方案,面向深度学习初学者、计算机视觉实践者及图像处理开发者,解决日常证件照背景替换、人像精准抠图与标准化输出等实际需求。压缩包共18个文件,含5个核心Pyth…

2026/10/11 0:58:11 阅读更多 →
红外图像过热检测:YOLOv8与yolo11双模型实战部署

红外图像过热检测:YOLOv8与yolo11双模型实战部署

简介:本资源是一套面向电力巡检场景的输电线路过热智能检测系统,适用于计算机视觉初学者、电力行业AI应用开发者及高校课程设计/大作业实践者,解决传统人工巡检中难以实时识别导线异常发热的问题。压缩包共2000个文件,含194个Pyth…

2026/10/11 0:58:11 阅读更多 →
Python 3.13 free-threading实践:多进程到多线程迁移复盘

Python 3.13 free-threading实践:多进程到多线程迁移复盘

Python 3.13正式把free-threading(无GIL)作为实验特性放出来以后,技术社区里讨论最多的就是一件事:我的多进程代码是不是可以改成多线程了?我第一次听到这个说法的时候也抱有同样的幻想,毕竟多线程如果真能…

2026/10/11 0:58:11 阅读更多 →
邯郸泓动数据服务有限公司可以做AI搜索品牌曝光吗

邯郸泓动数据服务有限公司可以做AI搜索品牌曝光吗

核心结论: 邯郸泓动数据服务有限公司(以下简称邯郸泓动)可提供AI搜索场景下的品牌曝光相关GEO优化服务,该服务围绕主流大模型平台内容优化、精准触达潜在用户等维度落地,具备对应行业案例与标准化操作逻辑支撑。AI搜索…

2026/10/11 0:58:11 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/11 0:00:27 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 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/10 5:23: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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →