
前言
在独立博客的排版与呈现中,一篇精炼的摘要能极大提升读者的阅读体验。但是鉴于本人比较懒,所以就让打算让AI代劳。最近我尝试为 Typecho 博客配置一款名为 AIContentSummary的 AI 摘要插件,本以为填个 API Key 就能用了,结果在 AI 的帮助下还是折腾了好久,过程中踩了不少坑。
这里把这次 debug 和重构的完整过程记录下来。
一、初遇 Bug
配置好 API 地址和密钥后,我满怀期待地点击“发布”,却只看见一个Server Error,回到文章列表,发现文章发布了,但 AI 摘要字段依然是空的。即使我去修改已经存在的文章并重新发布,摘要也没有任何变化。
为了找出原因,我借助 AI,扒开了插件的源码 Plugin.php,顺着文章保存与发布的生命周期理了一遍逻辑:
-
时序冲突
在Plugin.php中,生成逻辑挂载在finishPublish钩子上,通过ensureSummary()方法来实现。而该方法内部有一行安全检查:if (\(exists && trim((string) \)exists['str_value']) !== '') { return null; }看似合情合理──如果文章已经有了摘要,就不重复生成。
然而,在 Typecho 写入文章的事务中,自定义字段的保存方法applyFields()在finishPublish钩子被触发之前就已经执行了。当用户点击“发布”时,表单提交了空的(或旧的)自定义字段,并写入了数据库。到了执行finishPublish时,数据库里其实已经存在了这个字段,导致上述检查永远返回null,自动更新和生成机制直接失效! -
同步请求
由于 API 请求是同步发起的,如果接口响应缓慢或网络超时,整个发布文章的页面就会卡死;更严重的是,原代码中没有任何try-catch保护,一旦 API 服务异常或者鉴权失败抛出错误,会导致整个 Typecho 页面崩掉,这就是之前“Server Error”的根源所在。
二、排查诊断
为了在不崩掉页面的前提下定位错误,AI辅助我做了两件事:
- 在
finishPublish中包裹了try-catch,并使用 Typecho 自带的Notice机制,如果生成失败,就在页面重定向后以红条警告展示具体报错,而不是直接白屏。 - 在博客根目录下输出了一个临时的
debug.log,打印钩子触发的参数状态。
这一测,一下子就发现了问题:
- 模型参数限制
在开启了配置后,重新发布,日志里爆出了真正的接口报错:async ensureSummary failed. Error: invalid temperature: only 1 is allowed for this model原来插件在调用大模型接口时,将温度值(
temperature)硬编码成了0。而我配置的 KIMI 的 API 为了输出稳定性,强制要求温度值必须为1。
三、AI 辅助下的插件改良
既然定位到了所有的痛点,那就开始解决!我给这个插件做了一次改良升级:
-
生成逻辑
- 拦截
write钩子 ── 精准判定是否需要重绘
我注册了Widget\Contents\Post\Edit下的write过滤器。在文章真正写入数据库前: - 比对旧正文与新正文,确认文章内容是否真的改变了。
- 比对旧摘要与表单提交的摘要。如果两者相同,说明作者并没有手动编辑过摘要,此时如果正文变了,就可以安全地将
$shouldRegenerate状态标记为true。 - 如果用户手动修改了摘要输入框,则主动放弃自动生成。
- 拦截
-
参数调优
- 增加温度(Temperature)设置:在插件配置后台中,新增了
temperature字段,并将其默认值设定为1.0,从而避免因为某些模型 API 参数限制报错。 - 按需独立控制:在文章编辑页新增了一个专门的 “自动 AI 总结” (启用/禁用) 单选按钮,让写作者在撰写单篇文章时,能根据需要灵活决定是否启用 AI 摘要生成。
- 保留日志输出:所有的调试日志全部在同级目录的
log/debug.log下,方便用户检查错误原因。
- 增加温度(Temperature)设置:在插件配置后台中,新增了
总结
经过以上折腾,AI 总结已经能完美地运行在我的博客上,文章发布与更新流畅自如,AI 摘要如丝般顺滑地自动运作,折腾完毕,收工!
相关折腾成果已发布至Github - AIContentSummary_Plus,如有需要自行取用!
评论