Wechaty 集成 wechatferry:用 @wechatferry/puppet 实现 PC Hook 微信机器人的完整实践
即时通讯后端AI 应用【免费下载链接】wechatferry-项目地址https://gitcode.com/gh_mirrors/wec/wechatferry点击查看免费下载本文围绕 wechatferry 仓库中的 Wechaty 集成文档 docs/integrations/wechaty.md 展开讲解如何通过wechatferry/puppet把 wechatferry基于 PC Hook 的微信机器人协议客户端接入 Wechaty 机器人框架从安装、最小可用示例DingDong 机器人、消息事件管线到自定义缓存管理器CacheManager的完整实现路径。读完本篇你将能够独立搭建一个可运行的 Wechaty WechatFerry 机器人并理解 Puppet 内部的登录、缓存与消息分发机制必要时自行替换缓存层。Wechaty 在 wechatferry 集成体系中的位置wechatferry 是 Node 生态下针对 WeChatFerryPC Hook 协议的第三方客户端其包结构按“底层到上层”分为三层wechatferry/core封装 sdk.dll 与 TCP 连接、wechatferry/agent封装核心、更易用的事件式 Agent、wechatferry/puppet对接 Wechaty 的 Puppet 实现。README 中对该包的定位非常直白wechatferry/puppet 的目标是“让 Wechaty 免费协议PC Hook重放荣光”。在 集成指南 中官方给出了三种集成方式Nuxt 模块、Wechaty Puppet、纯 NodeAgent。而 Node 集成文档 中有明确建议始终推荐你使用 Wechaty而不是直接使用 AgentWechaty 能极大的减少你的心智负担。也就是说Wechaty 集成是项目主推的用法之一。Wechaty 本身是一个历史悠久、API 抽象良好的微信机器人框架提供 Bot/Contact/Room/Message 等统一领域模型允许通过替换 Puppet 接入不同协议端因此wechatferry/puppet的职责就是把 WechatFerry 协议的能力映射到 Wechaty 的 Puppet 抽象上让所有 Wechaty 生态代码可以直接跑在 PC Hook 协议上。适用前提来自 集成指南需要 64 位 Windows 系统需要受支持版本的微信客户端文档标注当前需要的版本为 3.9.12.17并提前打开登录机器人账号仓库 README 同时包含免责声明本项目仅供学习交流请遵守相关法规与授权边界。安装Wechaty 集成需要同时安装 Wechaty 本体与wechatferry/puppet两个依赖支持 pnpm / yarn / npm# pnpm pnpm add wechaty wechatferry/puppet # yarn yarn add wechaty wechatferry/puppet # npm npm install wechaty wechatferry/puppet从 packages/puppet/package.json 可以看到wechatferry/puppet的核心运行时依赖包括依赖作用wechatferry/agentworkspacePuppet 的底层数据来源提供 wcf 能力wechatferry/coreworkspace由 agent 传递依赖封装 dll 与 TCP 连接wechaty-puppet(^1.20.2)Wechaty Puppet 基类与 payload 类型unstorage(^1.15.0)默认缓存实现UnstorageCacheManager的存储后端knex(^3.1.0)由 agent 用于直接查询微信数据库file-box图片/文件消息的统一 FileBox 抽象p-retry缓存刷新联系人/群/成员的重试机制xml2js解析 AppMsg 等 XML 负载名片、链接、朋友圈等最小可用示例DingDong 机器人文档给出的最小示例是一个经典的 DingDong 机器人收到文本ding就回复dong。完整代码与逐行说明如下// index.ts import { WechatferryPuppet } from wechatferry/puppet import { WechatyBuilder } from wechaty const puppet new WechatferryPuppet() const bot WechatyBuilder.build({ puppet }) bot.on(message, (msg) { msg.text() ding msg.say(dong) }) .start()逐行解析new WechatferryPuppet()创建 Puppet 实例。构造函数接受一个可选的PuppetWcferryUserOptions定义见 packages/puppet/src/types.tsexport interface PuppetWcferryUserOptions { agent?: WechatferryAgent /** 自定义缓存管理器 */ cacheManager?: CacheManager }不传任何参数时resolvePuppetWcferryOptionspackages/puppet/src/puppet.ts#L17-L23会补齐默认值agent new WechatferryAgent()、cacheManager new UnstorageCacheManager(createStorage())。也就是说默认情况下 Puppet 内部自己创建 Agent 与基于内存的 unstorage 缓存。WechatyBuilder.build({ puppet })用指定的 Puppet 构建 Bot。你也可以在这里挂接 storage持久化、logger 等 Wechaty 标准组件。bot.on(message, ...)Wechaty 的领域事件监听msg.say(dong)最终会落到 Puppet 的messageSendText。bot.start()启动 Wechaty进而触发 Puppet 的onStart。启动与登录的底层调用链WechatferryPuppet继承自wechaty-puppet的Puppet基类其启动流程在 packages/puppet/src/puppet.ts 中可以完整看到onStart()puppet.ts#L42-L49注册 Agent 的login/logout/error事件转发然后调用this.agent.start()启动底层 wcf 连接并启动 Puppet 心跳见下文。Agent 侧的登录检测WechatferryAgent.start()packages/agent/src/agent.ts#L41-L50会wcf.start()、启动每秒一次的checkLoginStatus轮询、监听message/sended事件并转发检测到登录状态变化时 emitlogin携带用户信息或logout。login(userId)puppet.ts#L51-L65Puppet 收到 login 后执行loadContactList()→loadRoomList()→updateContactCache(userId)把全量联系人和群列表含每个群成员写入缓存随后调用基类super.login()、emitready并把onMessage绑定到 Agent 的消息事件上——此后每条微信消息都会进入事件管线下一节。onStop()停止心跳、移除 Agent 全部监听并agent.stop()Agent 侧会先 emitlogout再断开 wcf 连接。此外还有两个值得注意的机制登录二维码authQrCodegetter 会调用this.agent.wcf.refreshQrcode()刷新二维码puppet.ts#L81-L89Wechaty 的扫码登录流程可以据此获取二维码。Puppet 心跳startPuppetHeart每 15 秒 emit 一次heartbeatpuppet.ts#L1015-L1025用于让 Wechaty 的 Puppet 守护机制认为该 Puppet 存活。消息事件管线一条消息如何变成 Wechaty 事件onMessagepuppet.ts#L91-L146是整个 Puppet 的核心分发点处理顺序为系统消息兜底若消息带roomid但没有sender把 sender 置为fmessage微信系统账号保证后续解析不会因空 sender 失败cacheManager.setMessage(messageId, message)先把原始消息写入缓存这是后续messageRawPayload能取到历史消息的前提parseEvent(puppet, message)按注册的解析器链判定事件类型按事件类型 emit 对应的 Wechaty Puppet 事件。事件类型定义在 packages/puppet/src/events/events.tsexport enum EventType { Message, // 普通消息 Post, // 朋友圈 Friendship, // 好友请求/变更 RoomInvite, // 群邀请 RoomJoin, // 入群 RoomLeave, // 退群/被移出 RoomTopic, // 群名变更 }各解析器在 packages/puppet/src/events/index.ts 中通过addEventParser注册parseEvent依次尝试每个解析器第一个成功解析出 payload 的即为最终事件类型全部失败则兜底为普通Message事件。分发逻辑中的几个细节Messageemitmessage仅携带messageIdpayload 从缓存读取——这就是示例中bot.on(message)的来源PostemitpostWechaty 侧对应朋友圈能力postSearch通过messageSearch按Message.Post类型检索实现见 puppet.ts#L785-L808Friendship先把 friendship payload 写入缓存再 emitfriendshipRoomInvite缓存群邀请后 emitroom-inviteRoomJoin仅 emitroom-join注释明确写着DO NOT UPDATE LISTS HERE不在事件流里同步刷新成员列表RoomLeaveemitroom-leave并对每个被移出成员执行cacheManager.deleteRoomMember(roomId, memberId)保持缓存一致RoomTopicemitroom-topic后触发updateRoomCache(roomId)刷新群信息。自发消息的回补机制PC Hook 协议下“发送成功”与“消息入库”存在时间差。Puppet 通过onSendMessage(timeout 5)puppet.ts#L148-L173轮询agent.getLastSelfMessage(localId)最多 5 次、每次间隔 1 秒等待自己发出的消息落到消息库然后把它转换为事件消息、写入缓存并 emitmessage——这样 Wechaty 中say()之后也能收到自己的message事件行为与其他 Puppet 保持一致。所有messageSend*方法末尾都会调用该回补。群消息的 能力messageSendTextpuppet.ts#L408-L455对群聊做了增强显式传入mentionIdList时按成员 wxid 群发 文本中包含all时自动替换为所有人并 全群内部使用notifyall文本匹配[mention:...]占位符时通过mentionTextParser解析、从缓存取群成员列表getRoomMemberList替换成真实昵称再调用agent.sendText(conversationId, text, mentions)发送。能力边界哪些 API 可用哪些不可用wechatferry/puppet参考了 puppet-padlocal 的设计但并非 Puppet 规范的完整实现。从 puppet.ts 的源码可以梳理出明确的能力清单已实现可直接调用联系人contactList/contactRawPayload/contactAlias只读/contactAvatar以FileBox.fromUrl返回头像 URL/tagContactList只读消息messageRawPayload(Parser)/messageImage/messageFile图片、视频、文件、表情/messageRecall基于agent.revokeMsg/messageUrl解析 AppMsg XML/messageMiniProgram/messageContact解析名片消息并回填一个“伪联系人”进缓存发送messageSendText含群 能力/messageSendFile按 mediaType 分流图片与普通文件/messageSendUrl富文本链接额外支持name/account两个扩展字段见文件末尾的declare module声明/messageForward群聊roomList/roomRawPayload(Parser)/roomTopic、roomAnnounce只读/roomAvatar/roomMemberList/roomMemberRawPayload/roomAdd注意成员数超过 40 时自动改用“邀请入群”而非直接添加puppet.ts#L550-L569/roomDel/roomInvitationRawPayload朋友圈postSearch仅 Moment/postRawPayload(Parser)解析 XML 并顺带把附属消息写入缓存。未实现调用即抛出Method not supported错误contactSelfQRCode/contactSelfName/contactSelfSignature、contactPhone/contactDescription/contactCorporationRemark、conversationReadMark、messageSendContact/messageSendLocation/messageSendMiniProgram/messageLocation、roomCreate/roomQuit/roomQRCode群二维码以及群公告写入、全部friendshipSearch/Add/Accept、标签增删tagContactAdd/Remove/Delete、postPublish/tap/tapSearch等。使用建议在编写业务前先对照上面清单确认目标能力是否在“已实现”列表内不可用的能力直接抛错属于设计预期而非故障。缓存管理为什么需要 CacheManager以及如何自定义这是文档中最容易被忽视、却最能体现 wcf 协议特点的一节。PC Hook 方案的特点是数据源是本地微信数据库 实时事件流。对于“当前正在发生的”事件消息、入群、好友请求等原始负载在事件到达后会丢失事件只带 ID而 Wechaty 的 Puppet 协议又要求随时能通过messageRawPayload(id)/roomRawPayload(id)等接口按 ID 取回 payload。因此wechatferry/puppet把“按 ID 取数据”这一层抽象成了独立的CacheManager接口文档原文也点明了这一点“wcf 使用的是 hook 方案不一定需要缓存所以你可以自己实现从 agent 中直接查询”。CacheManager接口完整定义在 packages/puppet/src/cache-manager/cache-manager.ts按领域分为五组分组关键方法MessagegetMessage/setMessage/hasMessageContactgetContact/setContact/deleteContact/getContactIds/getAllContacts/hasContact/getContactCount/setContactListRoomgetRoom/setRoom/deleteRoom/getRoomIds/getRoomCount/hasRoom/setRoomListRoom MembergetRoomMember/setRoomMember/deleteRoomMember/setRoomMemberList/getRoomMemberList/getRoomMemberIds其他getFriendship/setFriendshipgetRoomInvitation/setRoomInvitation/deleteRoomInvitation所有方法均允许返回T | PromiseTMaybePromise因此同步内存实现与异步 Redis/数据库实现都可以直接适配。默认实现UnstorageCacheManager默认实现 UnstorageCacheManager 基于unstorage按前缀划分为多个命名空间wcf:message // 消息 wcf:contact // 联系人 wcf:room // 群 wcf:room-invitation // 群邀请 wcf:friendship // 好友关系 wcf:room-member:roomId // 每个群一个成员命名空间构造时传入任意 unstorageStorage实例即可Puppet 默认使用createStorage()内存后端。这意味着默认情况下缓存是进程内存级的机器人重启后清空登录时会通过loadContactList/loadRoomList重新全量灌入puppet.ts#L995-L1013但历史消息 ID 不会恢复——重启后对旧消息 ID 调用messageRawPayload会抛出Message not found错误。自定义缓存接口写法与完整示例按文档的写法实现CacheManager接口即可import { CacheManager } from wechatferry/puppet class MyCacheManager implements CacheManager { // pass }实际项目中需要补全全部方法。下面给出一个“无缓存”风格的示意实现——即把消息类查询直接丢弃、把联系人/群查询委托给 Agent 实时查询帮助你理解接口各方法的语义实际可用版本还需处理Promise化与批量方法import type { CacheManager } from wechatferry/puppet import type { WechatferryAgentContact, WechatferryAgentChatRoom, WechatferryAgentChatRoomMember, WechatferryAgentEventMessage, } from wechatferry/agent import type * as PUPPET from wechaty-puppet class InMemoryCacheManager implements CacheManager { private messages new Mapstring, WechatferryAgentEventMessage() private contacts new Mapstring, WechatferryAgentContact() private rooms new Mapstring, WechatferryAgentChatRoom() private members new Mapstring, Mapstring, WechatferryAgentChatRoomMember() // Message getMessage(id: string) { return this.messages.get(id) ?? null } setMessage(id: string, p: WechatferryAgentEventMessage) { this.messages.set(id, p) } hasMessage(id: string) { return this.messages.has(id) } // Friendship private friendships new Mapstring, PUPPET.payloads.Friendship() getFriendship(id: string) { return this.friendships.get(id) ?? null } setFriendship(id: string, p: PUPPET.payloads.Friendship) { this.friendships.set(id, p) } // Contact getContact(id: string) { return this.contacts.get(id) ?? null } setContact(id: string, p: WechatferryAgentContact) { this.contacts.set(id, p) } deleteContact(id: string) { this.contacts.delete(id) } getContactIds() { return [...this.contacts.keys()] } getAllContacts() { return [...this.contacts.values()] } hasContact(id: string) { return this.contacts.has(id) } getContactCount() { return this.contacts.size } setContactList(payload: WechatferryAgentContact[]) { for (const c of payload) this.contacts.set(c.userName, c) } // Room getRoom(id: string) { return this.rooms.get(id) ?? null } setRoom(id: string, p: WechatferryAgentChatRoom) { this.rooms.set(id, p) } deleteRoom(id: string) { this.rooms.delete(id) } getRoomIds() { return [...this.rooms.keys()] } getRoomCount() { return this.rooms.size } hasRoom(id: string) { return this.rooms.has(id) } setRoomList(payload: WechatferryAgentChatRoom[]) { for (const r of payload) this.rooms.set(r.userName, r) } // Room Invitation private invitations new Mapstring, PUPPET.payloads.RoomInvitation() getRoomInvitation(id: string) { return this.invitations.get(id) ?? null } setRoomInvitation(id: string, p: PUPPET.payloads.RoomInvitation) { this.invitations.set(id, p) } deleteRoomInvitation(id: string) { this.invitations.delete(id) } // Room Member private memberMap(roomId: string) { if (!this.members.has(roomId)) this.members.set(roomId, new Map()) return this.members.get(roomId)! } getRoomMember(roomId: string, contactId: string) { return this.memberMap(roomId).get(contactId) ?? null } setRoomMember(roomId: string, contactId: string, p: WechatferryAgentChatRoomMember) { this.memberMap(roomId).set(contactId, p) } deleteRoomMember(roomId: string, contactId: string) { this.memberMap(roomId).delete(contactId) } setRoomMemberList(roomId: string, payload: WechatferryAgentChatRoomMember[]) { const m this.memberMap(roomId) for (const member of payload) m.set(member.userName, member) } getRoomMemberList(roomId: string) { return [...this.memberMap(roomId).values()] } getRoomMemberIds(roomId: string) { return [...this.memberMap(roomId).keys()] } }注入方式则是利用PuppetWcferryUserOptionsimport { WechatferryPuppet } from wechatferry/puppet import { WechatyBuilder } from wechaty const bot WechatyBuilder.build({ puppet: new WechatferryPuppet({ cacheManager: new InMemoryCacheManager(), // agent 也可以同时自定义 // agent: new WechatferryAgent({ wcf: myCore }), }), })几点实践提示若需要跨重启保留会话上下文例如记住某条消息 ID 用于messageForward可以基于UnstorageCacheManager的存储构造方式换用 Redis/SQLite 等持久化 unstorage driver而不是从零实现接口若你的架构是“每条消息都实时落库、随时可从数据库重建”则完全可以像文档建议的那样实现一个“直查 Agent/数据库”的 CacheManager跳过内存缓存缓存刷新类操作updateContactCache/updateRoomCache/updateRoomMemberCache等puppet.ts#L901-L993内部使用p-retry重试 3 次命中缓存 miss 时会回源 Agent 查询并回写替换缓存实现时注意保持“miss 可回源”的语义。生产化建议安全模式包装器文档主文之外仓库还提供了一个与 Wechaty Puppet 直接配套的节流插件wechatferry/plugins的createSafeModePuppetdocs/plugins/safe-mode.md。它通过Proxy拦截所有以messageSend开头的方法实现三级限速packages/plugins/src/safe-mode/safe-mode.ts#L5-L38维度默认值同一会话发送间隔1 秒/条不同会话之间的间隔3 ~ 5 秒随机全局发送上限40 条/分钟import { createSafeModePuppet } from wechatferry/plugins import { WechatferryPuppet } from wechatferry/puppet const puppet createSafeModePuppet(new WechatferryPuppet())由于它包装的是 Puppet 实例本身可以与任意 Wechaty 构建方式自由组合。文档同样强调安全模式只控制发送频率不是绕过风控的魔法。测试用例中的集成验证方式仓库的 test/robot.test.ts 展示了在不启动真实微信进程的前提下如何验证 Puppet 集成值得参考其思路用Proxy包装Wechatferrycore实例把所有send*方法替换为打日志的空实现getSelfWxid返回固定的filehelper用该 core 构造WechatferryAgent再new WechatferryPuppet({ agent })最后经createSafeModePuppet包装后交给WechatyBuilder.build({ puppet })通过agent.emit(message, fakeMessage)注入伪造的系统消息如你邀请小茸茸加入了群聊断言room-join/room-leave事件解析出的群 ID、邀请者/被邀请者名称是否正确——这直接验证了上文“事件管线”中RoomJoin/RoomLeave解析器与昵称提取逻辑safeMode用例则连发 10 条消息验证节流包装不阻塞正常发送。这种“core 打桩 agent 注入消息”的模式也为在自己的项目中为wechatferry/puppet编写集成测试提供了模板。小结Wechaty 是 wechatferry 主推的集成方式之一安装wechatywechatferry/puppet即可运行WechatferryPuppet默认自建WechatferryAgent与内存UnstorageCacheManager消息流为Agent 事件 → 写缓存 →parseEvent分类Message/Post/Friendship/RoomInvite/RoomJoin/RoomLeave/RoomTopic→ emit Wechaty Puppet 事件自发消息通过轮询getLastSelfMessage回补CacheManager是理解该 Puppet 的关键抽象它解耦了“按 ID 取 payload”的实现可按需替换为内存、持久化 unstorage driver 或直查 Agent/数据库的实现编写业务前先对照能力清单Method not supported的方法较多如roomCreate、roomQRCode、朋友圈发布等并建议用createSafeModePuppet包装以控制发送频率运行前提64 位 Windows 指定版本的微信客户端当前文档标注 3.9.12.17并遵守仓库 README 的使用声明。相关源码入口WechatferryPuppet 主实现、CacheManager 接口、默认 unstorage 缓存实现、事件解析注册、Puppet 选项类型、集成测试、原始集成文档。赞分享即时通讯后端AI 应用【免费下载链接】wechatferry-项目地址https://gitcode.com/gh_mirrors/wec/wechatferry点击查看免费下载相关推荐wechatferry 微信机器人框架完全指南从 sdk.dll 桥接到 Wechaty 生态的 TypeScript 实践wechatferry 微信机器人框架完全指南从 sdk.dll 桥接到 Wechaty 生态的 TypeScript 实践 wechatferry 是一个基即时通讯后端AI 应用如何快速掌握WeChatFerry微信机器人2025完整实践指南WeChatFerry是一款功能强大的微信机器人底层框架通过Hook技术深度集成微信客户端支持接入各类AI大模型让开发者能够轻松构建智能对话机器人。无论你微信机器人开发实战WeChatFerry框架完整指南微信机器人开发实战WeChatFerry框架完整指南 还在为微信机器人开发头疼吗想要快速构建智能对话助手却不知从何下手今天我们就来深度解析WeChatFe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Web前端MOOC测试题:HTML/CSS/JavaScript考点与答题策略

Web前端MOOC测试题:HTML/CSS/JavaScript考点与答题策略

1. 这里不是“背答案”那么简单:先看这门课的测试题到底在考什么先纠正个笔误——标题里写的“前段开发”,应该是“前端开发”。这不是抠字眼,是因为我在给学生答疑时发现,很多人在搜索引擎里输入的关键词本身就带着错别字&#x…

2026/10/14 17:38:02 阅读更多 →
STM32 F103C8T6驱动AHT10温湿度传感器:模拟I2C实现与避坑指南

STM32 F103C8T6驱动AHT10温湿度传感器:模拟I2C实现与避坑指南

简介:面向嵌入式初学者的STM32 F103C8T6学习笔记工程包,主题是AHT10温湿度传感器驱动与数据采集。内容围绕I2C(集成电路总线)通信展开,涵盖引脚复用配置、库函数收发、传感器初始化与校准、温湿度原始数据移位换算、校…

2026/10/14 17:38:02 阅读更多 →
WhoDB Impeccable 的 shape 命令详解:写代码前的三阶段 UX/UI 规划工作流

WhoDB Impeccable 的 shape 命令详解:写代码前的三阶段 UX/UI 规划工作流

数据库客户端后端前端CLI桌面应用数据可视化AI 应用 【免费下载链接】whodb Where data access meets operational intelligence 项目地址: https://gitcode.com/gh_mirrors/wh/whodb 点击查看 免费下载 在 WhoDB 仓库中,.agents/skills/impeccable/ 目…

2026/10/14 17:38:02 阅读更多 →

最新新闻

插件加载失败排查:从生命周期到激活机制,一篇搞定

插件加载失败排查:从生命周期到激活机制,一篇搞定

先说一句,我带过好几个插件化改造的项目,也修过无数跟插件相关的启动报错,所以看到 "failed to load plugins web boot: 2 entries did not activate" 这种日志时,第一反应不是翻框架文档,而是看插件的激活方…

2026/10/14 18:19:43 阅读更多 →
Linux下源码编译安装PostgreSQL 12.0实战指南

Linux下源码编译安装PostgreSQL 12.0实战指南

我们聊聊怎么在Linux环境下把PostgreSQL 12.0老老实实装好、配好。写这篇是因为我最近刚好在一台CentOS 7.9的机器上从源码编译部署了一套PG 12.0,整个过程踩了几个不大不小的坑,网上很多教程都只讲“敲命令”,不讲“为什么”,导致…

2026/10/14 18:19:43 阅读更多 →
插件加载失败?从 MusicFree 到 web boot 激活链路全拆解

插件加载失败?从 MusicFree 到 web boot 激活链路全拆解

最近在很多技术社区和问答平台看到同一个热搜词:plugins。具体一点说,是“musicfree plugins”和“failed to load plugins web boot: 2 entries did not activate”这类带着具体上下文的长尾热词。如果你也和几千个点进这些关键词的人一样,刚…

2026/10/14 18:19:43 阅读更多 →
Linux下PostgreSQL 12.0编译安装与配置实战

Linux下PostgreSQL 12.0编译安装与配置实战

开头PostgreSQL 12.0这个版本虽然已经不算最新,但我一直认为它是近年里“最值得部署的版本”之一——性能优化覆盖面广、分区表体验大幅改善、日志和监控机制也更成熟。到现在,我身边还有不少生产环境跑在12.x上,稳定得让人懒得升级。这篇博文…

2026/10/14 18:19:43 阅读更多 →
Python Selenium复用已打开Chrome实例的完整指南

Python Selenium复用已打开Chrome实例的完整指南

1. 项目概述:为什么“复用已打开的Chrome”比从零启动更值得深挖你有没有遇到过这种场景:写好了一段 Selenium 脚本,运行起来一切正常,但每次执行都得重新打开一个全新的 Chrome 窗口——登录态没了、Cookie 清空了、插件没加载、…

2026/10/14 18:19:43 阅读更多 →
Kiln AI Server 实战指南:REST API 服务与 MCP 工具服务器的安装、配置与二次集成

Kiln AI Server 实战指南:REST API 服务与 MCP 工具服务器的安装、配置与二次集成

人工智能AI 应用AI 评测RAG微调提示工程开发工具桌面应用 【免费下载链接】Kiln Build, Evaluate, and Optimize AI Systems. Includes evals, RAG, agents, fine-tuning, synthetic data generation, dataset management, MCP, and more. 项目地址: https://gitcod…

2026/10/14 18:18:42 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →