数据截至 (上游 commit 1f8f3e285bbc)
02 · Prompt 设计与结构化输出
这章讲:项目里 5 个 LLM 调用点各自的 prompt 长啥样、想拿什么,以及它们共用的"用
generateObject+ zod schema 逼模型吐结构化 JSON"的套路和统一人格。
3.6 共同套路:generateObject + zod
要解决的小问题: LLM 默认吐自由文本,但这个 agent 每一步都要"可编程地"拿到结果——一个搜索词数组、一个 learnings 数组。解析自由文本很脆。
思路: 用 Vercel ai SDK 的 generateObject,把"我要什么形状"用 zod schema 声明出来。SDK 会把 schema 转成模型的结构化输出约束(或函数调用),保证返回的 res.object 就是那个形状。而且 zod 每个字段的 .describe(...) 会作为提示塞给模型——schema 既是校验器,也是 prompt 的一部分。
// 示意,非源码:套路模板
const res = await generateObject({
model: getModel(),
system: systemPrompt(), // 统一人格
prompt: `...任务描述...`,
schema: z.object({
queries: z.array(z.object({
query: z.string().describe('The SERP query'), // 字段描述=给模型的微提示
})),
}),
});
res.object.queries; // 直接拿到强类型数组
五个调用点全都是这个模板,只是 prompt 文本和 schema 不同。
3.7 统一人格 systemPrompt
所有调用共享同一个 system 提示(src/prompt.ts:1-15)。它做两件事:注入当天日期(new Date().toISOString(),让模型知道"今天",好处理时效信息),和设定人格——一串"你是专家研究员/把我当专家/别简化/重视论证胜过权威/允许推测但要标注"的指令:
export const systemPrompt = () => {
const now = new Date().toISOString();
return `You are an expert researcher. Today is ${now}. Follow these instructions when responding:
- You may be asked to research subjects that is after your knowledge cutoff, assume the user is right when presented with news.
...`;
};
注意"assume the user is right when presented with news"这条——它专门为"研究超过模型知识截止日的新事件"松绑,避免模型嘴硬否认新闻。