P320分钟

LLM 与 Prompt

大语言模型是 Agent 的「大脑」。Prompt 工程是构建高效 Agent 的关键技能。
SDK FocussystemPromptoutputFormatZod schemastructured_outputthinking / effort

LLM 在 Agent 中的角色

LLM 是 Agent 系统的核心决策引擎:

  • 理解 - 解析用户意图和上下文
  • 推理 - 分析问题并制定解决方案
  • 决策 - 选择使用哪些工具以及如何行动
  • 生成 - 产出代码、文档、回复等

System Prompt 设计

System Prompt 定义了 Agent 的「人设」和行为边界。一个好的 System Prompt 应该包括:

system-prompt.ts
import { query } from "@anthropic-ai/claude-agent-sdk";

// 形式 1:简单字符串
const agent1 = query({
prompt: "Review this PR",
options: {
  systemPrompt: "You are a senior code reviewer. Be thorough but constructive.",
},
});

// 形式 2:预设 + 追加(保留 Claude Code 默认值)
const agent2 = query({
prompt: "Review this PR",
options: {
  systemPrompt: {
    type: "preset",
    preset: "claude_code",
    append: "\n\nFocus on security vulnerabilities and performance.",
  },
},
});

身份定义

text
你是一个专业的软件工程助手。
你帮助用户编写、调试和改进代码。
你精确、有帮助、且注重安全。

能力描述

text
你可以使用以下工具:
- read_file: 读取文件内容
- write_file: 创建或修改文件
- run_command: 执行 Shell 命令
- search_code: 在代码库中搜索模式

行为准则

text
行为准则:
- 修改文件前必须先读取
- 在执行操作前解释你的推理
- 需求不明确时主动询问
- 未经确认不得执行破坏性命令

输出格式

text
响应格式:
1. 首先,分析请求
2. 然后,解释你的方案
3. 执行必要的操作
4. 总结完成的工作

Prompt 技巧

思维链与可验证推理脚手架

要求简洁、可评审的证据与决策,而不是展示私有思维链:

text
返回:
1. 会影响答案的假设
2. 支撑每个结论的证据或工具结果
3. 不确定性及消除方式
4. 推荐行动

少样本学习(Few-shot Learning)

提供示例来引导模型的行为:

text
示例 1:
User: "创建一个计算斐波那契数列的 Python 函数"
Action: write_file("fib.py", "def fibonacci(n):...")

示例 2:
User: "修复 app.js 中的 bug"
Action: read_file("app.js")
Action: write_file("app.js", "// fixed version...")

结构化输出

使用 JSON 或特定格式保持输出可解析:

text
以下列 JSON 格式响应:
{
  "evidence": ["observable fact or source"],
  "action": "tool_name",
  "action_input": { ... }
}
structured-output.ts
import { query } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";

// 使用 Zod 定义输出 Schema
const ReviewSchema = z.object({
summary: z.string().describe("One-line summary"),
issues: z.array(z.object({
  severity: z.enum(["critical", "warning", "info"]),
  file: z.string(),
  line: z.number(),
  message: z.string(),
})),
approved: z.boolean(),
});

const response = query({
prompt: "Review the code in src/auth.ts",
options: {
  model: "sonnet",
  outputFormat: {
    type: "json_schema",
    schema: z.toJSONSchema(ReviewSchema) as Record<string, unknown>,
  },
},
});

for await (const message of response) {
if (
  message.type === "result" &&
  message.subtype === "success" &&
  message.structured_output !== undefined
) {
  // 在应用边界验证 unknown payload。
  const review = ReviewSchema.parse(message.structured_output);
  console.log(`Approved: ${review.approved}`);
  review.issues.forEach(i =>
    console.log(`[${i.severity}] ${i.file}:${i.line}: ${i.message}`)
  );
}
}

SDK 洞察:Schema 约束输出

outputFormat 要求 SDK 按 schema 约束最终响应,结果以 unknown 形式通过 message.structured_output 暴露。仍需本地验证;模型无法满足 schema 时,查询可能以 error_max_structured_output_retries 结束。

上下文管理

LLM 有上下文长度限制,因此需要策略性地管理上下文:

上下文窗口

上下文限制取决于具体模型、API 和账户配置。部署时查看提供商的最新模型文档, 并为工具结果与最终回答预留余量。

管理策略

  • 滑动窗口 - 保留近期对话,丢弃较早的
  • 摘要压缩 - 将历史压缩为摘要
  • 检索增强 - 按需获取相关上下文
  • 分层存储 - 将重要信息存入长期记忆

模型选择

针对不同任务使用不同模型:

  • 高难判断 - 从能力较强的档位开始,衡量正确性与审阅负担
  • 常规转换 - 通过代表性评估后,再选择更快的档位
  • 长上下文 - 核对具体端点限制,同时测试检索或压缩方案
  • 本地部署 - 衡量质量、延迟、内存与运维约束

Thinking 控制

较新的 SDK 用法应优先使用 thinkingeffort 来控制推理深度。你仍会在旧示例里看到 maxThinkingTokens,但更适合把它视为兼容旧写法的控制项,而不是主路径接口。

最佳实践

  • 保持 System Prompt 简洁但完整
  • 使用具体示例而非抽象描述
  • 明确定义输出格式
  • 只调整当前 SDK 与模型暴露的控制项,再评估结果
  • 测试边缘情况和错误处理

生产落差

本课的提示词示例是静态字符串。生产系统使用版本化的提示词模板、A/B 测试和自动化回归测试,以防止提示词变更导致质量下降。

延伸阅读

动手试试Schema 约束输出

构建一个返回经验证 JSON、让真实同事能据此行动的 Agent。

  1. 明确用户和决策,再定义:{ task, complexity, estimatedMinutes, requiredTools }
  2. 使用 outputFormat 强制执行 Schema
  3. 测试 5 个代表性任务,同时检查 Schema 有效性和必要字段能否支撑决策
  4. 不用 outputFormat 再对比,分别统计格式破损与格式正确但值不可信的输出

关卡:P3 完成——结构化输出通过测试集,失败处理有效,理解 System Prompt 预设,并衡量思考投入的权衡。

登录后可保存课程进度、解锁闪卡,并从上次阅读的位置继续