Prompt设计最佳实践:精简上下文优于巨型提示
强调长期运行的AI自动化任务应采用小规模、动态结构化的上下文生成器替代硬编码的巨型提示,避免指令漂移和规则冲突。
强调长期运行的AI自动化任务应采用小规模、动态结构化的上下文生成器替代硬编码的巨型提示,避免指令漂移和规则冲突。
我很喜欢 AI 自动化,但我不信任那种试图在每次 cron 任务运行时,把整个世界都塞进去的巨型 prompt。它们一开始看起来很惊艳,随后却慢慢变成一个杂物抽屉:旧规则迟迟没有清理,主题覆盖逐渐偏移,写作者还要花费太多精力,反复决定那些本该提前结构化的基本事项。
对于周期性任务,我发现,在写作者前面加一个小型 context builder,效果反而更好。由一个脚本收集当前账号、近期历史记录、约束条件,以及少量经过筛选的输入。然后,写作者基于这份紧凑的 payload 工作,而不是面对一个怪兽般的 prompt。这样做也许没那么浪漫,但实用得多。
一个定时工作流的存续时间,往往比其中假设条件的有效期更长。问题正是从这里开始的。
起初,大型 prompt 看起来很灵活。你可以往里面塞入策略、示例、主题列表和兜底规则。一个月后,却没人能完全确定哪些部分仍然重要。有些指令会悄无声息地相互冲突,另一些虽然在技术上仍然正确,却早已过时。任务依然能够“正常运行”,但输出会变得有些含糊,也有些重复。
因此,我更喜欢小而明确的 context 对象。它们会迫使系统清楚说明当前真实有效的信息:
当前启用的是哪个账号
哪些主题属于允许范围
可以使用哪些内部链接
哪些约束是必须满足的硬性要求
应该避开哪些近期发布过的内容
这本质上与自动化系统中清晰的状态边界,以及重复任务中稳定的后端规则,是同一个道理。要构建可靠的系统,就应该明确命名并限定决策输入的作用域,而不是把它们涂抹在一整面文字墙上。
builder 不需要多么复杂。事实上,通常越简单越好。我需要的只是一个 JSON 对象,其中包含足以写出优质内容的信息。
对于内容生产任务,这通常意味着:
选中的账号及其语言
近期发布历史
符合该账号定位的主题关键词
标题长度、标签数量等平台约束
预先筛选的内部链接
可以自然融入文章的可选 SEO 词汇
注意这里没有哪些内容:完整的历史存档、曾经制定过的所有策略,以及堆积如山的示例。如果写作者每一次都需要这些东西,说明系统设计本身已经在向你传递某种信号了。
我采用的思维模型是:builder 决定游乐场的边界,写作者在其中发挥。这样的职责拆分可以消除定时任务中的许多怪异问题,也能让后续的故障排查更加容易。
这个模式是刻意设计得如此朴素的:
type WriterContext = {
account: { username: string; language: string; topics: string[] };
constraints: { titleMax: number; backlinkCount: number };
internalLinks: Array<{ url: string; anchor: string }>;
recentHistory: Array<{ title: string; publishedAt: string }>;
primaryKeywords: string[];
typoKeywords: string[];
};
const context = await buildWriterContext();
const plan = planArticle(context);
const article = writeArticle(plan);
await publish(article);
关键不在于 TypeScript,而在于执行顺序。先构建 context,再冻结写作方案,只写一次,最后根据已经批准的产物进行发布。如果发布步骤失败,不要偷偷进行第二次改写,然后祈祷没人发现。这样很快就会变得一团糟,而且说实话,也会让调试变得相当烦人。
我喜欢这种模式,还有一个原因:它能让写作者保持诚实。当源 payload 足够小时,你可以看清楚究竟是哪些杠杆影响了输出结果。文章的“聪明”并不是因为 prompt 极其庞大,而是因为输入经过了精心塑造。
这种模式并不只适用于发布系统。它同样会出现在注册测试、收件箱检查和预览环境中——在这些场景里,临时邮箱流程也是任务的一部分。
假设你的自动化任务需要使用 tempmail.so 收件箱进行验证。builder 可以决定本次运行应该采用哪种收件箱规则、超时时间和环境标签。写作者或执行器不应该再从大段文字中重新推断这些信息。你的团队可能还会在日志中看到一些干扰性搜索词,例如 dummy e mail 或 temp mailid,道理也是一样。这些字符串可以作为相关 context,但应该以明确字段的形式进入本次运行,而不是作为被遗忘的片段,隐藏在一个巨型 prompt 里。
这种区别听起来很小,却会改变团队的工作方式。人们不再把自动化视为一个神秘的黑盒,而会开始将它视作一条拥有明确命名输入的 pipeline。少一点魔法,多一点杠杆效应。我认为这是一笔相当划算的交易。
不会。它只是让运行时事实变得明确。你仍然可以在 context builder 之外维护一份稳定的写作指南。关键在于,不要把长期有效的指导原则与每次运行时的决策混在一起。
应该小到让人能在一分钟内快速浏览完。如果 JSON 读起来像一部长篇小说,那就删减它。如果缺少重要选择,也只添加那些必要的信息。
我会避免这么做。一旦某个步骤既负责收集输入,又负责生成输出,就很难对每个部分进行清晰、独立的测试。职责分离看起来没那么炫酷,但在经历数周的 cron 任务运行后,会更值得信赖。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。