术语表
教程正文中的高亮词条汇总于此,共 121 个。在章节正文中悬停高亮词可预览摘要,点击直接打开该词条的详情页。
核心概念 22
- Agent(自主系统) 由「模型 + 环境(工具)+ 控制循环」组成的自主系统:模型负责推理与决策,环境提供可施加作用的工具,控制循环驱动它反复执行「感知 → 决策 → 行动 → 观察」直至任务完成。与一问一答的 chatbot 不同,Agent 的每一次「下一步做什么」都由模型在运行时自主决定,而不是程序员预先写死。见第 01 章。 详情 →
- 控制循环 Agent 最小定义的三要素之一(另两个是模型与环境):指「感知 → 决策 → 行动 → 观察」四步闭路。关键点是循环的每一次「下一步做什么」由模型根据当前观察自主决定,而不是程序员预先写死——这是 Agent 与普通程序的分水岭。 详情 →
- Workflow(预设路径工作流) 把 LLM 编排在预设代码路径里的系统:每一步该干什么由程序员写死,LLM 只是被调用的一个环节,路径本身不改变。与 Agent 的模型自主决策相对,是判断「什么才算 Agent」时最容易混淆的一对概念。 详情 →
- From-scratch(从零手写) 不依赖任何 Agent 框架、从最底层 HTTP 调用开始逐层手写的方法论。原理优先于封装:手写过一遍之后,你既能调试、能裁剪,也能看穿任何框架的抽象到底替你做的是什么。 详情 →
- LLM(大语言模型) 大语言模型(Large Language Model),Agent 的「大脑」:一个通过 HTTP API 暴露的文本生成服务。调用它本质上是一个普通 HTTP POST 请求,请求与响应的形状在第 02 章被逐字段解剖。 详情 →
- Token(词元) 模型计费与处理的基本单位,通常是子词片段而非整词。usage 字段里的 prompttokens / completiontokens / totaltokens 是成本核算的唯一依据;maxtokens 限制输出长度,撞上会被截断(finishreason: 'length')。 详情 →
- Temperature(采样温度) 采样参数,控制输出的随机性:缩放模型对下一个词的概率分布。温度低 → 分布变「尖」,输出稳定保守;温度高 → 分布变「平」,输出多样发散。与 topp 二选一调整;需要确定性时用低温度 + seed。 详情 →
- Streaming(流式输出) 模型边生成边把结果推给客户端,而非等全文完成一次性返回。把「总延迟」转化为「渐进可见的进度」,也是工具调用中间态、审批交互等 Agent 体验的基础。 详情 →
- TTFB(首字节延迟) Time To First Byte,从发出请求到收到第一个字节的时间。它决定用户对「卡不卡」的第一印象,流式把总延迟转化为可感知的渐进进度,正是为了缓解 TTFB 带来的焦虑。 详情 →
- Agent Loop(智能体循环) 驱动 Agent 反复执行的核心循环:把「一轮工具调用」升级成「多轮循环」,让程序自己决定「要不要再来一轮、再来该做什么」。最小形态是约 50 行的 while 循环——把 messages + tools 发给模型,有 toolcalls 就逐个执行并回填后继续,否则把文本作为最终答案返回。agent = 循环 + 状态。见第 07 章。 详情 →
- think → act → observe(思考-行动-观察) 循环的三个环节:think 把完整消息历史和工具清单交给模型做决策;act 由 harness 执行模型要的工具(模型只决定、不执行);observe 把工具结果作为 tool 消息回填进 messages。思考与行动交替进行,行动的结果成为下一次思考的输入——这也是 ReAct 命名的由来。 详情 →
- 停止条件 循环回答「什么时候停」的规则,两类缺一不可:模型不再要求工具(toolcalls 为空,正常结束),或达到 maxIterations(保险丝,模型失控时的兜底)。判断继续与否只看有没有工具调用,不依赖厂商的 stopreason。 详情 →
- system prompt(系统提示词) 随请求发送、定义模型角色与行为规则的顶层提示。工程化做法是分层构建:每一层一个独立来源、按需组装、单层设上限;稳定的 system prompt 前缀能触发服务端 prompt caching,大幅降低多轮会话的费用与延迟。 详情 →
- ReAct(思考-行动循环) 把「思考」与「行动」交替编排的范式:先思考再行动,行动结果成为下一次思考的输入,思考轨迹显式可调。原生 tool calling 时代它是基本免费的。见第 12 章。 详情 →
- 思考-行动交替(Reasoning-Acting) ReAct 的核心编排机制:模型先推理(Thought),harness 执行工具(Action),结果回填为观察(Observation),如此循环直到不再需要工具。见第 12 章。 详情 →
- Plan-and-Execute(计划-执行) 先让模型产出完整计划(当数据,不是散文),再机械执行、一次综合的范式:模型调用少、计划可见可批;代价是计划过期后不再随环境调整。见第 12 章。 详情 →
- Reflection(反思) 生成 → 评审 → 修订的外环范式:评审不过就把评审意见追加进消息历史继续改,直到通过或达到轮数上限。买的是质量,代价是调用翻倍与同源盲区。见第 12 章。 详情 →
- 范式(Paradigm) 同一套「循环 + 注入 callLlm」之上可替换的控制结构模板:只改控制流,就得到 ReAct / Plan-and-Execute / Reflection 三种不同行为。见第 12 章。 详情 →
- 可观测性(observability) 通过结构化日志、追踪与指标回答「系统内部到底发生了什么」的能力。Agent 的事件流瞬时而逝,可观测层在协议之外盖上序号与时间戳、按一次运行聚合出完整记录,让「哪一步出错、token 花到哪、坏在哪一类」都有据可查。见第 20 章。 详情 →
- 结构化日志(structured log) 每个事件盖上全局序号与墙钟时间、序列化为一行可排序可检索的结构化记录(如 JSON)。与普通 print 日志相比,它带归属与次序,是聚合出 trace 的「砖」。见第 20 章。 详情 →
- Trace(轨迹) 一次运行的完整记录:起点、终点、期间每个事件(按序)、累计的资源用量(token)、最终结果。日志回答「发生了什么」,trace 回答「这一次运行发生了什么、花了多少、成没成」。它既是可观测性分析的对象,也是评测的判题对象——只看最终答案会漏掉「答案对了但行为浪费」的失败运行。 详情 →
- 子智能体(subagent) 被委派执行独立子任务的 Agent 实例:同一个循环函数的另一份实例,喂全新消息历史、裁剪过的工具白名单与独立预算。隔离是构造性的,结果以终答字符串回填给主 Agent。见第 22 章。 详情 →
协议 27
- Chat Completions 协议 OpenAI 风格的对话补全接口:POST /v1/chat/completions,请求体是 model / messages / temperature / topp / maxtokens / seed 等字段的 JSON,响应体含 choices[0].message.content、finishreason 与 usage。它是本教程所有厂商接入的起点,也是「OpenAI 兼容服务」的事实标准。 详情 →
- Messages(对话消息数组) chat/completions 请求中携带的完整对话历史,一个有序数组,每条消息必须有 role(system / user / assistant)。服务端是无状态的:每次请求都要把全部历史重新发给模型,对话状态完全由客户端维护——这是理解 Agent「记忆」的关键。 详情 →
- SSE(Server-Sent Events) 基于 HTTP 的单向服务器→客户端推送协议:服务器把 content-type 设为 text/event-stream,一条接一条推送事件,连接保持打开直到主动关闭。浏览器原生 EventSource 只支持 GET、无法带自定义头,所以 LLM 流式接口必须手写客户端。 详情 →
- Chunk(数据块) 流式传输中一次 read() 拿到的字节片段。chunk 边界不对齐行边界:一个完整事件可能被切进多个 chunk,必须用半行 buffer 攒齐 \n\n 再分帧。 详情 →
- Delta(增量) 流式响应中每个事件携带的「增量」:choices[0].delta.content 是一小块文本,完整输出 = 累积所有 delta,与普通响应的 choices[0].message.content 语义等价。 详情 →
- NormalizedMessage(规范化消息) Provider 抽象里统一的消息形状:{role: 'system' | 'user' | 'assistant', content: string}。不管哪家厂商,进到业务代码里的对话都是这个形状;system 在 Anthropic 里要抽到顶层字段,那是 Provider 内部翻译的事。 详情 →
- OpenAI 兼容接口(Chat Completions) 以 OpenAI 的 POST /v1/chat/completions 请求/响应结构为标准的接口风格,DeepSeek、本地 Ollama 等大量服务都提供 OpenAI 兼容端点,messages、temperature、choices、usage 等字段名在兼容服务间通用。 详情 →
- Anthropic Messages API Anthropic 的消息接口:POST /v1/messages,鉴权用 x-api-key + anthropic-version 版本头;maxtokens 必填、system 抽成顶层字段、content 是 block 数组、从 content[0].text 取文本、结束原因是 stopreason、用量字段是 inputtokens / outputtokens。与 OpenAI 的逐项差异对比见第 04 章。 详情 →
- Wire Protocol(线上协议) 客户端与服务端之间实际传输的协议形态——对 LLM 而言就是那个 HTTP 请求/响应 JSON。官方 SDK 只是给同一套 wire protocol 包了层糖:出 bug 时(为什么 400?为什么取到 undefined?)你必须能读懂它在线上发的是什么。 详情 →
- 工具 schema 声明 写给模型看的「说明书」:工具叫什么(name)、什么时候用(description)、参数长什么样(parameters)。模型只能看到这份 schema 声明,看不到实现代码;description 写得越清楚,模型选对工具的概率越高。它基于 JSON Schema 描述参数约束。 详情 →
- 工具结果回填 执行完工具后,把结果作为 role: 'tool' 的消息按 toolcallid 与调用配对、追加进消息数组。工具结果必须是字符串(模型只能读文本);第二次请求必须把 assistant 消息与 tool 消息原样带回,模型才能把结果和「自己刚才的请求」对上。 详情 →
- ReAct 提示式 不声明任何工具 schema,把工具用法写进 system prompt,要求模型按固定文本格式输出 Thought / Action,harness 再用正则/JSON 解析抠出行动并注入真实的 Observation。是原生 tool calling 出现之前的通用后备,也是理解「agent 内核不依赖具体协议」的教学透镜。 详情 →
- schema 生成 从一份声明式 spec 生成 JSON Schema,而不是手抄,从根上消除「schema 与实现互相漂移」。TS 的运行时没有类型(编译后被擦除),所以用一份运行时可见的参数声明(name / type / description / required)作为唯一契约来源,注册时由一个小生成器算出 schema。 详情 →
- 事件协议(Event Protocol) 把 Agent 运行的每一步决策序列化成结构化事件的跨章契约,共七型:textdelta / toolcallstart / toolresult / approvalrequest / approvalresult / done / error。每条带 sessionId、工具事件按 callId 配对、data.type 自描述。见第 15 章。 详情 →
- 事件驱动(Event-Driven) 以事件流为中间产物的架构机制:core 发出结构化事件,传输与界面层只负责消费与转发,事件本身可序列化、可存储、可回放。见第 15 章。 详情 →
- SSE 服务端(SSE Server) 基于 Server-Sent Events 的服务端实现:把事件编码成 event: + data: 帧写出、注释行保活、断线清理。ch03 手写了客户端解析器,本章补上服务端那一半。见第 15 章。 详情 →
- 会话(Session) 服务端隔离各客户端对话上下文的单元:每个会话有独立的状态与事件流,事件按 sessionId 分桶。会话状态在界面层,core 无状态。见第 15 章。 详情 →
- 多会话(Multi-Session) 一个服务同时服务多个客户端,各自持有独立会话、互不串流。协议层用 sessionId 分派事件,服务端用 Map 存每会话历史、缓冲按会话分桶。见第 15 章。 详情 →
- 事件序号(seq) 事件流里为每条事件分配的会话内单调递增的序号,是事件的「可寻址位置」,类似书页码、日志行号或数据库自增主键。客户端凭它精确表达「我从第 N 条之后接着读」,服务端按 seq > since 补发增量。seq 是会话内概念:跨会话独立、跨多轮运行连续,但只保证单调、不保证连续(取消/失败会留下「洞」)。见第 16 章。 详情 →
- 重连(reconnect) 断线后客户端重新建立事件流连接的行为。重连时携带上次看到的进度指针(since=N),服务端只回放 seq > N 的增量,避免全量重放浪费带宽。重连时机由产品决定(重试策略、指数退避、多客户端同时恢复),与 SSE 传输层的自动重连(Last-Event-ID)不同——协议语义走应用层。 详情 →
- 进度指针(resume cursor) 客户端记录的「最后一条完整收到的事件序号」,是断点续传的指针。POST /chat 返回的 lastSeq 让客户端只订阅本轮新事件;GET /events?since=N 里的 N 就是这个指针。缺省 since=0 等于全量回放,向后兼容旧客户端。 详情 →
- 审批双向流(approval flow) 审批事件的下行(approvalrequest 推给前端)与上行(POST /approvals 回传决定)合起来的完整闭环,再以 approvalresult + toolresult 下行收尾。requestId 把请求与回答配对;拒绝则 toolresult 带 denied 标记、跳过执行,callId 配对不变式保持。 详情 →
- MCP(模型上下文协议) Anthropic 于 2024 年开源的开放协议,把「工具如何暴露、如何发现、如何调用」标准化,让 AI 应用以统一方式接入外部工具与数据源。协议只定义消息长什么样、按什么顺序发,角色分为 server 与 client。见第 21 章。 详情 →
- JSON-RPC 2.0 一种无状态、轻量的远程过程调用协议,MCP 的每一种消息都建立在它之上。三种消息形态:request(有 id)、notification(无 id 无响应)、response(id + result 或 error 二选一),id 是响应与在途请求的唯一配对键。见第 21 章。 详情 →
- stdio 传输(stdio transport) MCP 的标准传输之一:client spawn server 子进程,消息经 stdin/stdout 传递,每帧由 Content-Length 头(UTF-8 字节数)+ JSON 体组成,日志一律走 stderr。见第 21 章。 详情 →
- MCP server(工具服务器) 工具的所有者:声明「我提供这些工具」(tools/list)并执行调用(tools/call)。一个能用的工具型 server 只需实现 initialize、tools/list、tools/call 三个方法。见第 21 章。 详情 →
- MCP client(工具客户端) 工具的使用者:发现 server 的工具表,把远程工具当作本地工具调用。连接建模成状态机,先握手(initialize → notifications/initialized)后干活。见第 21 章。 详情 →
工具与循环 6
- Function Calling(工具调用) 让模型声明「我要调用哪个工具、参数是什么」的机制:把工具的 JSON Schema 声明成 inputschema,模型返回结构化的 toolcalls / arguments。它同时是强制 JSON 输出的技巧——模型为了「调用工具」会产出严格符合 schema 的参数。第 06 章做手动全流程。 详情 →
- Tool Calling(工具调用) 模型在回复中声明「我想调用某个工具、参数是什么」,而真正的执行永远发生在我们的进程里。完整闭环:模型返回 toolcalls → 解析参数 → 执行工具 → 把结果作为 tool 消息按 toolcallid 配对回填 → 带扩展后的消息数组发起第二次请求。这是所有 Agent 行动的起点,见第 06 章。 详情 →
- 并行工具调用 模型在同一轮返回多个 toolcalls,这些调用之间相互独立。执行时可用 Promise.all 并发跑,但回填必须按 toolcalls 数组的原始顺序排列结果、按 id 一一配对 toolcallid,否则第二轮模型看到的结果与它请求的顺序对不上。 详情 →
- 工具注册表 一张 name →(spec + 实现 + 生成的 schema) 的映射表,支持 register / list / get。模型要调工具时按名字查表取实现,新增工具只调一次 register,不碰分发逻辑与循环——「加一个工具 = 加一个文件」。循环只面向 list() / get(),不认任何具体工具名,见第 08 章。 详情 →
- 内置工具集 Agent 随身携带的默认工具。原则:纯函数工具优先(gettime、add、search 这类可预测、无副作用、天然幂等),有副作用的危险工具慎入并要配权限层;注册时可挂可用性过滤(没配 key 的工具不发给模型)。 详情 →
- 审批门(permission gate) approve 级工具执行前的拦截点,分两层:主循环的交互门(会问人、会暂停)与 executeTool 的硬门(不认人、只认审批记录,拿不出记录即拒绝)。任何绕过交互门的调用方在硬门前都拿不到执行权——安全默认拒绝(fail closed)。 详情 →
上下文与记忆 13
- 上下文窗口(context window) 模型这一轮真正能一起看到的输入容量(如 8192 tokens),可以理解成「办公桌面积」——桌子就那么大,能同时摊开的文件有限。上下文管理就是在有限的窗口里,让 Agent 跑得久、跑得稳、跑得便宜,见第 09 章。 详情 →
- token 估算 在调用前估计一段文本会占多少 token 的启发式近似:英文大致 4 个字符 1 token、中文大致 1 个字 12 token。它和 API 的 usage 实测值通常只有几个百分点的差距——估算用于调用前做决策(要不要压缩),实测用于调用后记账校准。 详情 →
- 滑动窗口 历史超过预算时,保留头部(system 与最初的用户指令)和尾部(最近的工作),裁掉中间最旧的部分。0 次 API、纯数组切片,代价是被裁掉的信息永久消失——它是「用遗忘换长度」。 详情 →
- 摘要压缩 把中间段旧历史发给一个便宜的辅助模型,让它产出结构化摘要,用一条摘要消息替换整段旧历史——「换一种更短的表示」而非删除。代价是信息衰减:摘要是「有损压缩」,多轮压缩后模型可能连「还剩哪些文件没读」都不知道。 详情 →
- 工具结果截断 在入口处拦下上下文最大的消耗者——工具结果:readfile 一次返回 50KB,直接回填会烧掉大半窗口。截断要带省略号标记,让模型知道「这段结果被截断了」,需要时可以重新读完整内容——截断 ≠ 静默丢弃。 详情 →
- RAG(检索增强生成) 先检索相关知识、再让模型基于它们生成的范式,用于给没有长期记忆的模型补充外部事实。本章把它拆成最小实现:注入式 embedding + 余弦相似度 + 暴力检索。见第 11 章。 详情 →
- Embedding(向量嵌入) 把文本映射成向量的函数,核心性质是语义相近的文本映射后的向量也相近。本章采用注入式设计:测试与判题注入确定性假 embedding,生产环境注入真实 embedding API,机制与语义质量解耦。见第 11 章。 详情 →
- 向量检索(Vector Search) 按向量相似度而非关键词匹配来召回文本的检索方式,解决「同义不同词」的问题。本章手写暴力检索:embed 查询 → 逐条比对 → 阈值过滤 → top-k 排序,不依赖向量库。见第 11 章。 详情 →
- 工作记忆(Working Memory) 当前会话的上下文窗口(messages 数组),会话内有效、有 token 上限,不跨会话。Claude Code 把「工作记忆 = 上下文窗口 + 无长期记忆」视为基线。见第 11 章。 详情 →
- 长期记忆(Long-Term Memory) 跨会话存在的事实/经验库,有选择地写入、按需地召回。长期记忆 = 检索层(第 11 章)+ 持久层(第 10 章):向量是索引,原文必须落盘。见第 11 章。 详情 →
- 检索(Retrieval) 从记忆库中找出与当前问题最相关片段的过程:把查询 embed 成向量、逐条相似度比对、阈值过滤、top-k 排序,再把命中注入当前上下文。见第 11 章。 详情 →
- 提示缓存(prompt cache) 供应商对「与之前某次请求完全一致的 prompt 开头」复用计算结果并按折扣价计费。要命中必须前缀逐字节相同,因此工程铁律是「稳定内容放前面、变化内容放后面」。见第 20 章。 详情 →
- 上下文隔离(context isolation) 让每个 Agent 实例拥有自己独立上下文的设计原则:subagent 从全新消息历史开始,主对话不泄漏进去,两个 subagent 互不可见。隔离防止上下文污染,但结果需要穿过边界回填给主 Agent。见第 22 章。 详情 →
结构化输出 5
- 结构化输出 让模型输出程序可直接消费的数据结构(对象 / 数组 / 布尔值)而不是自由文本。手段有提示词要求 JSON、包进 markdown 代码块、裸 JSON + 严格指令,或 API 内置的强制 JSON 参数——但「约束 ≠ 保证」,输出仍要走「提取 → 校验 → 兜底」流水线,见第 05 章。 详情 →
- JSON Schema 描述 JSON 结构的声明式标准语言。本教程手写其最小子集(type / required / properties)作为校验器:声明是对象就检查「是不是对象 → 必填字段齐不齐 → 逐个属性递归」,错误以路径化的字符串数组返回。工具参数的 inputschema 也用同样的声明。 详情 →
- 校验(Validation) 「提取成功 ≠ 形状符合契约」:把「形状对不对」的检查写进代码,而不是赌模型自觉。校验层是「永远不信任 LLM 输出」这条原则的具体落点,与提取、兜底共同构成结构化输出流水线的三个工位。 详情 →
- extractJson(JSON 提取) 从任意包裹文本里提取 JSON 的两级策略:围栏优先(找 json 代码块)+ 字符串感知的括号平衡扫描兜底,依次尝试 JSON.parse,第一个解析成功的就赢。常见实现漏掉字符串转义(\"、\\)会切错边界。 详情 →
- Zod(模式校验库) 成熟的运行时模式校验库:用声明式 schema 对任意值做类型检查与解析。本教程要求先手写校验器以掌控校验语义(required 缺失报什么错、null 怎么处理、错误路径长什么样),复杂场景再引入库不迟。 详情 →
前端与交互 7
- 视图模型(view model) 界面状态的纯数据投影:不是 DOM,而是一份由 reducer 生成、渲染层唯一读取的数据结构(消息块数组、状态、审批提示、输入队列)。DOM 只是它的投影;它让界面状态可测、可回放、可恢复——断线重连后把持久化事件重放一遍,界面就回来了。 详情 →
- UI 状态机(state machine) 把流式界面建模为显式状态 + 纯函数转移:事件(wire 事件 + 本地事件)是唯一的转移输入,状态机六态(idle/streaming/waitingapproval/interrupted/done/error)决定每个事件是否合法。它解决「状态藏进 DOM 各个角落」导致没有代码能回答「现在界面上到底是什么」的问题。 详情 →
- 工具中间态(tool intermediate state) 工具调用从「发起」到「出结果」之间的可见状态:toolcallstart 插入 running 块,toolresult 把它解析为 done/failed。没有中间态,用户看到的 Agent 就是黑盒——工具出错时错误本身也是 UI 数据(error-as-data 一路延续到浏览器)。 详情 →
- 增量渲染(打字机效果) 流式前端把增量(textdelta)逐帧渲染的效果,文本像打字机一样逐字出现。要点是渲染永远发生在完整文本上而不是增量上——增量只负责「拼」,渲染只负责「读」;把 Markdown 解析放进增量路径是经典失败模式(代码块围栏会被拆进不同增量)。 详情 →
- 状态守卫(state guard) reducer 里每个处理函数的第一道检查:if (state.status !== 'streaming') return state;——不合法的事件原样丢弃。它「只认状态、不认来源」,是打断残留、重复事件、乱序事件在 UI 层的最后防线。 详情 →
- 输入排队(input queue) 忙碌(streaming/waitingapproval/interrupted)时把用户输入入队、done 后经 drainQueue 排空并开新回合的机制。语义是「一件事做完再做下一件」,让用户不必干等或关掉页面。 详情 →
- HITL(人在回路) Human-in-the-Loop 的缩写:在 Agent 主循环里插入人工决策点,破坏性/不可逆动作执行前暂停、经注入的审批回调拿到人的决定再继续。「暂停 → 问 → 恢复」就是本章审批双向流的形态;没注入回调时默认拒绝(fail closed)。见第 18 章。 详情 →
安全与工程 16
- 指数退避(Exponential Backoff) 面对 429 限流与 5xx 等可重试错误时的重试策略:重试间隔随尝试次数指数增长(100ms → 200ms → 400ms …),并加入随机抖动(jitter),防止多个客户端同步重试造成「重试风暴」。429 是「你太快了」,必须退避等待而不是立即重试。 详情 →
- 统一错误协议(error-as-data) 把工具失败当成数据而不是崩溃:工具抛错 → 捕获 → 格式化成字符串 → 作为 toolresult 回填给模型 → 模型读到自己失败的原因,自己纠正重试。错误字符串必须带「工具名 + 非法值 + 期望」,模型才有纠正的抓手;循环本身从不因一个工具而中断。 详情 →
- 工具超时 工具可能挂起(网络请求没响应),用 Promise.race 包一层,超时就按错误协议返回 { ok: false, error: 'timeout after 10s' }——超时本身也是数据,不是崩溃。需要主动中断时接上 AbortController,把 signal 传给工具。 详情 →
- 风险分级(risk tier) 给每个工具声明风险档位:auto(自动放行)/ suggest(提示但不阻断)/ approve(必须人工批准)。风险是策略不是模型知识——risk 字段放在工具 spec 上、不给模型看。分级越准,被打断的次数越少,每一次打断越值得认真对待。 详情 →
- 操作审计(audit log) 记录「谁批了什么、为什么、什么时候」的日志:每个审批决策(requestId/工具/参数/风险/决定/理由/时间)落事件流 + 服务端 GET /approvals 落库副本。approvalresult 本身就是审计事件,不需要单独的审计模块。 详情 →
- 沙箱(sandbox) 把 Agent 的能力关进笼子的机制集合:工作目录路径约束(resolveWithinRoot)、命令白名单、无 shell 执行。与 ch18 权限层的分工是——权限层管意图(该不该做),沙箱管能力(能做多坏);即使人类批准了危险参数,沙箱仍然拒绝。 详情 →
- 提示注入(prompt injection) 把恶意指令藏进模型会读取的内容(文件、网页、工具输出)里劫持 Agent 目标的攻击。直接注入来自用户输入本身;间接注入藏在第三方内容里、由 Agent 自己「读」进上下文,是 Agent 时代头号风险(OWASP ASI01 目标劫持)。缓解靠纵深防御而不是单点解药。 详情 →
- 路径遍历(path traversal) 用 .. 上溯、绝对路径或前缀碰撞等手段,让「读工作目录内文件」变成「读任意文件」的逃逸。防御算法是「先规范化、后包含检查」(resolve-then-check):自己完成 .. 弹栈后,再做段感知的包含检查(root + '/'),绝不把规范化交给操作系统。 详情 →
- Shell 隔离(shell isolation) 让 Agent 执行命令时也受约束的机制:命令白名单(fail-closed,只放行只读命令)+ execFile 参数数组执行(不经 /bin/sh,没有 shell 元字符注入通道)。诚实局限:白名单拦命令名不拦参数,彻底隔离需要容器/虚拟机级。 详情 →
- 最小权限(least privilege) 只给 Agent 完成任务所需的最小能力的安全原则:白名单默认拒绝、只放行只读命令、路径约束在根目录内、approve 级工具先过审批门。每一层都不完美,但叠加后攻击者无处可绕。 详情 →
- 纵深防御(defense-in-depth) 不依赖单点防线、用多层独立机制叠加的安全策略:通道隔离(工具输出只回填不进 system prompt)、能力限制(路径约束/命令白名单/审批门)、人工兜底(审批门)、持续监控。微软的建议是假设注入一定会发生,设计系统让它发生时损失可控。 详情 →
- 配置(config) 把可变参数(模型名、密钥、端口、预算)从代码中分离出来、集中加载与合并的一层。本章采用三段式:默认值 < .env 文件 < 环境变量,按优先级合并成纯数据对象。见第 23 章。 详情 →
- 环境变量(environment variable) 进程环境中携带的键值配置来源,优先级最高、可覆盖默认值与 .env 文件。它天然不进代码、不进 git,是传递密钥与按环境切换配置的标准通道。见第 23 章。 详情 →
- 密钥管理(secret management) 对 API key、token、密码等敏感配置的处理规范,三条铁律:不进代码、不进 git、不落日志。真实密钥放 .env 且加入 .gitignore,仓库只提交占位模板 .env.example,文件权限收紧到仅当前用户可读。见第 23 章。 详情 →
- 密钥脱敏(secret redaction) 对敏感配置输出前的遮蔽处理:按键名判定敏感项,只保留前几个字符、其余替换为掩码。防的是「日志里的被动泄漏」,不是加密。见第 23 章。 详情 →
- 部署(deployment) 把产品运行到生产环境的过程。单机部署的最小骨架是进程管理(常驻、崩溃自愈、开机自启)、结构化日志轮转与反向代理(TLS 终结、路由、限流)。见第 23 章。 详情 →
评测与工程 6
- Mock Model(确定性脚本模型) 不调用真实 LLM、按固定规则回复的确定性脚本模型,通过一个模拟 OpenAI chat/completions 接口的本地服务暴露。判题无需 API key、结果可复现,且与真实模型走同一个 HTTP 协议、同一种消息结构,学到的知识 100% 迁移。 详情 →
- Eval(评估) 给 AI 系统写的测试:给定输入,用判定逻辑检查输出,衡量成功与否。Agent 是概率系统,没有评估就是盲改——改一行提示词可能修好一个任务、弄坏另一个。见第 13 章。 详情 →
- 任务集(Test Set) 一簇测同一能力的任务集合,每个任务 = 输入 + 成功标准(断言 + 步骤预算)。任务集一旦建立就冻结,改动前后跑同一批任务才能对比回归。见第 13 章。 详情 →
- Grader(判分器) 给某方面表现打分的逻辑,可含多个断言。规则 grader 用代码断言(字符串匹配 / 工具调用 / 工具参数),快、确定、便宜但僵化;规则表达不了的维度才交给 LLM-as-judge。见第 13 章。 详情 →
- 回归评估(Regression) 改动前后各跑一遍同一个冻结任务集,用通过率与失败模式分布确认「没变坏」。两个前提缺一不可:任务集冻结 + 判分可复现(mock model 让回归零成本进 CI)。见第 13 章。 详情 →
- LLM-as-judge(LLM 判分) 用一个(通常更强、更便宜的)模型按 rubric 给输出打分,用于规则表达不了的维度。两条红线:rubric 必须可判;别用同一个模型又出题又判分。见第 13 章。 详情 →
产品与架构 19
- Provider 抽象 把不同厂商(OpenAI / Anthropic / 兼容服务)在端点、鉴权头、消息结构、响应解析、用量字段上的差异收进一个薄层,让业务代码只面对统一的形状。手写的最小接口是 chat(messages) → {text, stopReason, usage},见第 04 章。 详情 →
- Adapter(适配器 / 翻译层) Provider 抽象里每家厂商各一层的「翻译官」(如 createOpenAIProvider / createAnthropicProvider):负责把统一的规范化消息翻译成该厂商的请求格式,再把响应解析回统一形状。业务代码只面向 { chat },换厂商只改一行。 详情 →
- 持久层(持久化) 把会话状态变成进程外、可重放、可隔离的数据:每次对话变成一条条事件存进 SQLite,让 Agent 学会「忘不掉」。没有持久层 = 断线即失忆、无法回放、无法多会话——状态在内存里,进程死,状态死,见第 10 章。 详情 →
- 事件溯源(event sourcing) 一种存储模型:存「怎么一步步变成现在的样子」而非「现在的样子」。每次发生的事(用户发了消息、Agent 回复了、调用了工具)是一条事件,事件只能追加、永不更新删除;需要当前状态时把事件按顺序重放、由事件序列折叠得出。Agent 场景选它的三个理由:审计调试、崩溃安全、断线恢复的前置。 详情 →
- 事件日志 追加式的事件序列,唯一事实源。eventid 用 AUTOINCREMENT 自增主键保证全局单调、跨会话不重复;每行带 sessionid 外键归属会话。事件日志只 INSERT 绝不 UPDATE——事实只能追加,修正也只能追加新事件。 详情 →
- 崩溃恢复 进程被杀(SIGKILL、segfault)后数据怎么活下来的机制:journalmode=WAL + synchronous=NORMAL 下,已提交事务的数据先顺序追加进 -wal 日志文件,SQLite 下次打开数据库时自动回放 WAL,已提交事务一条不丢——崩溃恢复不靠你的 finally 块,而靠数据库引擎自己的日志。 详情 →
- 会话回放 从事件序列折叠重建出可重发的对话:usermessage / assistantmessage 事件折叠成消息,toolcall 与 toolresult 事件折叠成带 toolCalls 的 assistant 消息和 role: 'tool' 消息——输出的正是模型期望的消息形状,可以直接重新塞给模型,会话恢复不需要任何特殊逻辑。 详情 →
- CLI(命令行界面) 阶段二主线产品 v01 的第一交互面:读 stdin → 调 core → 打印输出与日志,是唯一的组合根。界面层依赖 core,core 不认识界面。见第 14 章。 详情 →
- 产品骨架(Product Skeleton) 把阶段一拆好的零件组装成可运行、可演进的产品所需的框架:拼装、配置、日志、分层四样缺一不可。ch15–ch23 将在这套代码上逐章演进。见第 14 章。 详情 →
- 分层架构(Layered Architecture) 按「这段代码属于哪个层」组织代码,并让依赖方向单向:界面层依赖 core,core 不 import 界面,因此 core 可以脱离 CLI 被测试、被复用。见第 14 章。 详情 →
- Core 与界面分层(Core/Interface) 产品骨架中最本质的分界:core(配置 / 传输 / 工具 / 主循环)负责决策,界面(CLI / 服务)负责组装与表达,通过注入与回调连接。判断标准:删掉 cli.mjs,core 还能不能单独跑、单独被测试。见第 14 章。 详情 →
- 组合根(Composition Root) 把 core 各模块组装成产品的唯一入口:读配置、建 Provider、建工具注册表、注入 callLlm 与 tools。界面层是唯一的组合根。见第 14 章。 详情 →
- Harness(运行框架) 模型与真实世界之间的第一道连接:本身不是智能,而是让模型能持续行动的最小运行框架——循环 + 工具执行器 + 注入的模型接口。见第 14 章。 详情 →
- 断线恢复(resume) 客户端断线后带进度指针重连、只补收未看事件的能力。断线不丢事件——Agent 照常运行、事件照常落存储,重连只是「从断点续读」;放弃连接 ≠ 放弃任务。产品形态参照 Claude Code 的 --resume 会话恢复,本教程把它做进了协议层(since 参数 + lastSeq)。 详情 →
- 后台运行(background task) 「Agent 的运行」与「客户端的连接」解耦后获得的能力:断开连接后 Agent 照常跑完,事件落存储、与有没有订阅者无关。前提是事件存储的 append 不要求任何人在听——存储是运行的落点,连接只是读取进度的窗口。用户关掉页面任务照常完成,重新打开带上进度指针即可补齐。 详情 →
- token 成本核算(token cost) 按 token 用量与单价模型把模型调用折算成金钱。输入/输出按不同单价、按会话累计,prompt cache 命中部分按折扣价计费,是 Agent 可观测性的核心派生指标。见第 20 章。 详情 →
- 多智能体(multi-agent) 用多个 Agent 实例协作完成任务的组织方式:一个 orchestrator 分派子任务、多个 worker 并行执行、结果回填汇总。核心思想是「subagent = 独立的 loop 实例」,用于缓解单 Agent 的上下文窗口与工具列表膨胀瓶颈。见第 22 章。 详情 →
- 编排者-工人模式(orchestrator-worker) 一种多智能体编排模式:中央 orchestrator 拆任务、派给多个 worker 并行执行并汇总,控制权始终在 orchestrator 手里,worker 是「用完即弃」的执行单元。见第 22 章。 详情 →
- 交接(handoff) 一种多智能体编排模式:一个 Agent 干完自己那部分后,把对话状态整体交给下一个 Agent,自己退出,典型场景是串行流水线。与 orchestrator-worker 相比,控制权随移交转移、状态整体转移。见第 22 章。 详情 →