真实问答记录
这是学习过程中真实产生的问答,保留原始问题形态和完整答案。与 Sessions 中经过"面试题化"处理的深题不同,这里记录的是原始知识点和直接答案,作为查漏补缺的基准。
Q1 · AI 的 message 接口或 response 接口有哪些参数?含义是什么?
提问背景:直接列举主流 LLM API 的请求参数和响应字段,作为理解 API 契约的基准。
Anthropic Messages API
Endpoint: POST /v1/messages
| 参数 | 类型 | 必填 | 含义 |
|---|---|---|---|
model | string | 是 | 模型名称,如 claude-opus-4-6、claude-sonnet-4-6 |
messages | array | 是 | 对话消息列表,每条含 role(user/assistant)和 content |
max_tokens | int | 是 | 模型输出的最大 token 数 |
system | string | 否 | 系统提示词,用于设定模型行为(顶层参数,与 messages 平级) |
temperature | float | 否 | 控制随机性,0.0~1.0,越高越随机 |
top_p | float | 否 | nucleus sampling,与 temperature 二选一使用 |
top_k | int | 否 | 限制候选 token 数量(Anthropic 独有) |
stop_sequences | array | 否 | 遇到这些字符串时停止生成 |
stream | bool | 否 | 是否流式返回 |
tools | array | 否 | 可用工具定义列表 |
tool_choice | object | 否 | 工具调用策略(auto/any/tool) |
metadata | object | 否 | 元数据,如 user_id |
Response 返回字段(Anthropic)
| 字段 | 含义 |
|---|---|
id | 请求唯一标识 |
type | 响应类型(message) |
role | assistant |
content | 输出内容数组(text/tool_use blocks) |
model | 实际使用的模型 |
stop_reason | 停止原因(end_turn / max_tokens / tool_use / stop_sequence) |
usage | token 用量(input_tokens / output_tokens,含 cache 细分) |
OpenAI Chat Completions API
Endpoint: POST /v1/chat/completions
| 参数 | 类型 | 必填 | 含义 |
|---|---|---|---|
model | string | 是 | 模型名称,如 gpt-4o、gpt-4 |
messages | array | 是 | 消息列表,含 role(system/user/assistant/tool)和 content;system 放在 messages[0] |
max_tokens | int | 否 | 最大输出 token 数 |
temperature | float | 否 | 随机性控制,0.0~2.0(范围比 Anthropic 宽) |
top_p | float | 否 | nucleus sampling |
n | int | 否 | 生成多个候选结果 |
stream | bool | 否 | 流式返回 |
stop | string/array | 否 | 停止序列 |
presence_penalty | float | 否 | 鼓励新话题(-2.0~2.0,OpenAI 独有) |
frequency_penalty | float | 否 | 降低重复(-2.0~2.0,OpenAI 独有) |
tools | array | 否 | 函数/工具定义 |
tool_choice | string/object | 否 | 工具选择策略 |
response_format | object | 否 | 输出格式(json_object / text) |
seed | int | 否 | 可复现的种子 |
Response 返回字段(OpenAI)
| 字段 | 含义 |
|---|---|
id | 请求标识 |
object | chat.completion |
model | 实际模型 |
choices | 结果数组,每条含 message(role/content/tool_calls)、finish_reason |
usage | token 用量(prompt_tokens / completion_tokens / total_tokens) |
两者核心差异
- Anthropic 的
system是顶层参数,OpenAI 放在messages里 role=system - Anthropic 没有
frequency_penalty/presence_penalty - Anthropic 支持
top_k,OpenAI 不支持 - OpenAI 支持
n、seed、response_format,Anthropic 不支持 - 两者都支持流式(stream)和工具调用(tools)
- 停止原因命名不同:
stop_reason(Anthropic)vsfinish_reason(OpenAI),值也不同
Q2 · 怎么权衡 cache 和长上下文?
提问背景:Prompt Caching 要求前缀稳定才能命中;长上下文意味着每次对话前缀都在变化,缓存命中率下降。核心矛盾是缓存效率与上下文丰富度之间的权衡。
核心矛盾
缓存效率 ←————————→ 上下文丰富度 (成本低、延迟低) (信息全、理解准)
三种策略对比
1. 全量上下文(不缓存)
- 优点:模型拥有完整对话历史,理解最准确
- 缺点:token 成本高、延迟大,随对话增长线性恶化
- 适用:短对话、高价值场景(如代码审查、复杂分析)
2. 激进缓存(固定前缀)
- 优点:成本最低、延迟最低
- 缺点:丢弃历史细节,模型可能"忘记"早期内容
- 做法:将 system prompt 缓存,对话历史只保留最近 N 轮
- 适用:高频、低成本场景(如客服、简单问答)
3. 分层策略(推荐)
┌─────────────────────────────────────┐ │ System Prompt(缓存,稳定前缀) │ ← 高命中率 ├─────────────────────────────────────┤ │ 长期记忆摘要(缓存,低频更新) │ ← 中命中率 ├─────────────────────────────────────┤ │ 近期对话(不缓存,每轮更新) │ ← 低命中率但内容少 └─────────────────────────────────────┘
具体权衡指标
| 指标 | 倾向缓存 | 倾向长上下文 |
|---|---|---|
| 对话轮数 | < 10 轮 | > 20 轮 |
| 单轮 token | < 1k | > 5k |
| QPS 要求 | 高并发 | 低并发 |
| 成本敏感度 | 高 | 低 |
| 上下文依赖 | 弱(独立问答) | 强(连续推理) |
实用技巧
- 滑动窗口 + 摘要:保留最近 5-10 轮原文,更早的对话用 LLM 压缩成摘要放入缓存区
- 结构化缓存 key:将稳定部分(system prompt、用户画像)放最前,变化部分(对话历史)放最后,最大化缓存命中
- 按需召回:用向量检索从历史中召回相关片段,而非全量塞入上下文
- 成本监控:对比 cache read(便宜 10x)vs cache miss 的成本,动态调整缓存粒度
一句话总结
稳定的放缓存,变化的放上下文,用摘要做桥梁,用检索补细节。
Q3 · Skill 渐进式加载怎么实现?依赖哪些工具?
提问背景:理解 agent 系统中 skill 的按需加载机制,以及它依赖的工具链。
核心思路
全量加载:启动时把所有 skill 内容塞进 context → 浪费 token、启动慢 渐进加载:只加载索引,按需加载完整内容 → 节省 token、响应快
实现机制
第一层:元数据索引(启动时加载)
system-reminder 中只注入 skill 名称 + 一句话描述。例如:
- superpowers:brainstorming — You MUST use this before any creative work - superpowers:test-driven-development — Use when implementing any feature - lark-im — 飞书即时通讯:收发消息和管理群聊
这一层占用极小,只够模型判断"要不要用这个 skill"。每个 skill 约 50 tokens。
第二层:完整内容(按需加载)
当模型决定使用某个 skill 时,调用 Skill 工具:
Skill(skill: "superpowers:brainstorming")
工具返回该 skill 的完整 prompt 内容,注入当前对话上下文,模型按指令执行。
第三层:子依赖(链式加载)
某些 skill 内部会引用其他 skill 或资源,按需进一步加载,而非预先全部展开。
依赖的工具链
| 工具 | 作用 |
|---|---|
Skill tool | 核心入口,触发 skill 加载,将内容注入对话 |
Read tool | 读取 skill 文件原始内容(~/.claude/skills/*.md) |
Glob tool | 发现 skill 文件路径,建立索引 |
system-reminder | 在每轮对话中注入 skill 列表摘要,维持索引可见性 |
Agent tool | 部分 skill 会 dispatch 子 agent 执行独立任务 |
设计要点
1. 索引与内容分离
索引(始终在 context 中):skill name + 1句描述 → ~50 tokens/skill 内容(按需加载):完整 prompt → 500~5000 tokens/skill
2. 触发判断由模型完成
- 模型根据用户意图 + 索引信息判断是否需要某个 skill
- 判断标准写在每个 skill 的 description 字段里
3. 加载即执行
- Skill 加载后直接变成当前轮的指令,模型立即遵循
- 不需要额外的"激活"步骤
通用化设计(伪代码)
class SkillRegistry:
def __init__(self):
self.index = {} # name -> description (always in context)
self.content = {} # name -> full prompt (lazy loaded)
def get_index(self) -> str:
# 返回所有 skill 的摘要,注入 system prompt
return "\n".join(f"- {k}: {v}" for k, v in self.index.items())
def load(self, skill_name: str) -> str:
# 按需读取完整内容
if skill_name not in self.content:
self.content[skill_name] = read_file(f"skills/{skill_name}.md")
return self.content[skill_name]
关键设计选择
- 索引粒度:名称+描述 vs 名称+触发条件 vs 名称+完整 schema
- 缓存策略:加载后缓存 vs 每次重新读取(允许 skill 热更新)
- 冲突处理:多个 skill 同时触发时的优先级(当前实现:process skill > implementation skill)
一句话总结
索引常驻、内容懒加载、模型决策触发、工具链执行 —— 用最小的 context 成本覆盖最大的能力范围。
Q4 · 哪些工具适合 tools,哪些适合 skill/cli?如何权衡?
提问背景:AI Agent 系统中,能力应该实现为 Tool、Skill 还是 CLI,判断依据是什么。
三者本质区别
Tool:模型直接调用的原子能力,返回结构化结果 Skill:注入模型的流程/方法论,指导"怎么做" CLI:终端原生命令,模型通过 Bash 间接调用
适合做成 Tool 的特征
| 特征 | 说明 |
|---|---|
| 原子操作 | 单一动作,输入输出明确 |
| 需要确定性 | 不能靠 LLM 推断,必须精确执行 |
| 结构化数据 | 返回 JSON/文件路径等可解析结果 |
| 高频使用 | 每次对话可能调用多次 |
| 权限控制 | 需要用户审批/沙箱隔离 |
| 副作用可控 | 文件读写、网络请求等 |
典型例子:文件操作(Read/Write/Edit/Glob/Grep)、代码执行(Bash)、网络请求(WebFetch/WebSearch)、浏览器控制(Playwright)、子任务调度(Agent/TaskCreate)。
适合做成 Skill 的特征
| 特征 | 说明 |
|---|---|
| 流程/方法论 | 不是单一动作,而是一系列步骤 |
| 需要判断 | 模型需要根据上下文决策如何执行 |
| 组合现有工具 | 不引入新原子能力,而是编排已有工具 |
| 低频/条件触发 | 特定场景才需要,不适合常驻 |
| 可解释性 | 用户需要知道模型在遵循什么流程 |
| 可演进 | 流程经常更新,不想改代码 |
典型例子:开发流程(TDD、brainstorming、code review)、工作流编排(会议纪要整理、日报生成)、最佳实践(debugging 方法论、git 提交规范)、领域知识(API 使用指南)。
适合做成 CLI 的特征
| 特征 | 说明 |
|---|---|
| 已有成熟工具 | 不需要重新造轮子 |
| 用户直接使用 | 人也会用,不只是 AI |
| 复杂配置 | 需要大量参数和环境配置 |
| 跨平台 | 不依赖特定 AI 运行时 |
| 调试友好 | 可以独立测试和调试 |
典型例子:包管理(npm/yarn/pip)、版本控制(git/gh)、构建工具(webpack/vite/make)、部署工具(docker/kubectl/terraform)、云服务 CLI(aws/gcloud/az)。
决策矩阵
原子性高
│
▼
┌────────┴────────┐
│ │
高频使用 低频使用
│ │
▼ ▼
Tool CLI
(Read/Write) (git/npm)
原子性低
│
▼
┌────────┴────────┐
│ │
流程固定 需要判断
│ │
▼ ▼
CLI Skill
(固定脚本) (TDD/debug)
灰色地带的权衡
场景:代码审查
- 做成 Tool:
review_code(file_path)→ 返回审查结果。优点:调用简单;缺点:审查标准硬编码,难以自定义 - 做成 Skill:加载 code-review skill,模型按流程审查。优点:标准可演进,能结合上下文;缺点:消耗 token,执行慢
- 做成 CLI:
eslint/pylint/sonar。优点:成熟稳定;缺点:只能做静态分析,缺乏语义理解
推荐:Skill + CLI 组合 —— skill 指导审查流程,CLI 做静态检查,模型做语义审查。
场景:数据库查询
- 做成 Tool:
query_db(sql)→ 返回结果。优点:直接;缺点:安全风险,需要模型写 SQL - 做成 Skill:加载 db-query skill,教模型安全查询规范。优点:可以注入安全最佳实践;缺点:仍需配合 tool 或 CLI
- 做成 CLI:
psql/mysql客户端。优点:功能完整;缺点:输出解析麻烦
推荐:Tool(封装连接和安全检查)+ Skill(注入查询规范)。
一句话总结
Tool 做原子能力,Skill 做流程方法,CLI 做现有工具 —— 复杂场景三者组合使用。
拓展问题
以下是基于上述 4 个原始问题可以进一步深挖的方向,部分已在 Session 10 和 Session 11 中展开为面试题。
围绕 Q1(API 参数)可拓展
- Streaming 模式下 SSE 事件类型有哪些?如何组装 tool_use 的流式 chunk?
- tool_choice 的 auto/any/tool 三种策略在什么场景下用哪种?
- stop_reason 的每种值对应用层意味着什么?如何据此决定下一步动作?
- response_format 的 json_object 模式有什么陷阱?和 tool calling 取 JSON 哪个更可靠?
- OpenAI 的 n>1 多候选返回如何影响成本和延迟?什么场景值得用?
围绕 Q2(Cache vs 上下文)可拓展
- Anthropic 的 cache_control 有哪些断点控制?如何手动指定缓存边界?
- 缓存盈亏平衡点怎么算?给定 QPS 和平均 token 数,缓存策略是否划算?
- 对话超过窗口时,摘要保留哪些内容、丢弃哪些?如何验证摘要没丢关键状态?
- 多用户场景下,用户画像摘要应该放在缓存层还是每轮注入?
- RAG 检索结果和对话历史的缓存策略有何不同?
围绕 Q3(Skill 加载)可拓展
- Skill 的 description 字段写多长合适?太短误触发,太长浪费索引 token,怎么平衡?
- 多个 Skill 同时被触发时,如何决定执行顺序和优先级?
- Skill 内部引用其他 Skill 时,如何避免循环加载和 context 爆炸?
- Skill 热更新如何通知运行中的 agent?是否需要中断当前会话?
- 如何评估一个 Skill 是否真的有效?有 skill 和无 skill 的 paired eval 怎么设计?
围绕 Q4(能力分层)可拓展
- 什么时候应该把 CLI 包装成 Tool?包装的边界在哪?
- Tool schema 变更是 breaking change,如何做版本管理和灰度发布?
- 50 个 Tool 平铺给模型 vs 分组注册,选择准确率差异有多大?
- Skill 和 system prompt 中的指令有什么本质区别?什么时候用哪个?
- MCP(Model Context Protocol)如何解决跨厂商的工具注册和发现问题?
与 Sessions 的对应关系
| 原始问题 | 对应 Session | 说明 |
|---|---|---|
| Q1 · API 参数 | Session 10 | 在 Session 10 中被面试题化为深题 01(system prompt 差异)和深题 02(stop_reason 语义),本页保留原始的完整参数对照表 |
| Q2 · Cache vs 上下文 | Session 10 | 在 Session 10 中被面试题化为深题 04(缓存机制)和深题 05(分层策略),本页保留原始的策略对比和权衡指标 |
| Q3 · Skill 渐进式加载 | Session 11 | 在 Session 11 中被面试题化为深题 02(渐进式加载机制),本页保留原始的三层架构和工具链依赖 |
| Q4 · Tool/Skill/CLI 选型 | Session 11 | 在 Session 11 中被面试题化为深题 01(选型决策框架),本页保留原始的特征清单和决策矩阵 |
建议学习路径:先读本页保留的原始答案建立知识基准,再进入对应 Session 做面试题化训练。