Lazy loaded image
面试高频题库
Lazy loaded imageFunction Calling 与 Agent Runtime 学习笔记
Words 4178Read Time 11 min
2026-5-17
2026-5-21
slug
Function Calling 与 Agent Runtime 学习笔记
type
Post
status
Published
date
May 17, 2026
tags
推荐
文字
summary
category
面试高频题库
icon
password
本笔记基于费曼学习法对话整理,从 JSON Schema 出发,逐层拆解到 Agent Loop 的工程本质。

一、整体认知链路


二、核心概念:LLM 只是 Token Generator

关键认知(必须刻进 DNA)

LLM 本质上只是一个 token generator,它能做的只有"吐字"。它没有网络访问、没有文件系统、没有执行环境。
所谓"Function Calling"这个名字其实有点误导,叫 "Function Call Suggestion" 更准确 —— 模型只是在建议调用什么,决定权和执行权完全在 Runtime。

由此推出的工程结论

  1. 模型可以 hallucinate 不存在的工具名 —— Runtime 必须做合法性校验。
  1. 模型不知道执行成功还是失败 —— 它对世界的认知完全来自下一轮塞给它的 tool_result
  1. 模型不知道时间过去了多久 —— tool 跑了 30 秒还是 30 毫秒,对它没区别。
  1. "Function Calling 能力"训练的本质 —— fine-tune 模型让它在合适时机输出符合 schema 的 JSON。
Anthropic 官方用 "tool use" 这个词,比 "function calling" 中性,没暗示"模型在调用"。OpenAI 起的 "function calling" 这个名字带偏了一代开发者的心智模型。

三、JSON Schema 的角色

给谁看 + 干什么

视角
目的
模型看 schema
知道"我有哪些工具可用、参数长什么样"——为了产出
Runtime 看 schema
校验模型输出的 tool_call 合不合法——为了验收

在哪个阶段起作用

Schema 能解决什么,不能解决什么

维度
Schema 解决了吗
模型知道有什么工具
✓ 完全解决
输出格式合法(类型、字段、JSON 语法)
✓ 大幅缓解
Runtime 能验收
✓ 完全解决
语义正确(如 city="2026-05-17"
✗ 没解决
Schema 只管类型 / 结构 / 必填字段这种"语法层"的事,管不了"语义对不对"。语义对错本质上靠模型自己的理解能力 + description 写得好不好。

四、Self-Correction 机制

反馈闭环

关键认知

模型本身没有任何"自我纠错"的内在动力,所谓 self-correction 完全是 runtime 编排出来的幻觉。
  • 模型生成错误的那一刻,它不觉得自己错了(只是 next token prediction)
  • Runtime 不"主动通知"模型 —— 而是被动地准备好材料,等下一次模型推理时被读到
  • LLM 是 pull-based / stateless 的,每次 inference 都是冷启动

Self-correction 可行性判据(核心公式)

可纠正 = ∃ 某一层 L,使得 L 能识别错误 ∧ L 能产生错误反馈 ∧ 反馈能进 contextsilent failure = 上述条件都不成立

错误分类示例

场景
类型
原因
city="西安市"(API 要 "西安"
✓ 可纠正
API 报错"city not found"
city="2026-05-17"(类型对,语义错)
✓ 大概率可纠正
API 查不到此城市会报错(依赖 API 严格程度)
city="西宁"(用户原话"西安")
✗ Silent Failure
Schema 合法、API 正常返回西宁机票,链路无报错
date="2026-05-17"(用户想要 18 号)
✗ Silent Failure
日期合法、有票,链路无报错

对抗 Silent Failure 的手段

手段
做法
逻辑
Human-in-the-loop (HITL)
关键操作前让人 confirm
把"语义判断"交给人
Confirmation step
Agent 自己说"我要订西宁的票,对吗?"
把语义错误显性化
Reflection / Self-critique
调用结束后再让模型反思一遍
用一次额外的 LLM call 当"审稿人"
Constrained decoding
限制模型输出必须从枚举值里选
从自由文本变成 dropdown
Cross-validation
多次调用对比结果 / 多模型投票
用冗余对抗单点错误
工程结论:如果想让 Agent 对某类错误"自动纠错",工作不是教模型"更聪明",而是想办法在链路里植入一层能产生错误信号的 "L"

五、Training vs Inference

核心对比

阶段
模型参数(weights)的状态
在做什么
Training
可变(mutable)
通过 gradient descent 不断更新 weights
Inference
冻结(frozen / read-only)
weights 完全不动,只做一次 forward pass

类比

Training = 学生在上学,做错题大脑神经连接会重塑(参数更新) Inference = 学生毕业进考场,大脑被锁死,无论答得对错神经连接一动不动

"冷启动"的真正含义

模型不存在"经历"的概念。所谓"记得",完全是 runtime 在这一次 inference 的 input 里重新喂给它的 context 制造的幻觉。

三个工程事实

  1. Memory 系统的本质:模型参数永远不变,所有"记忆"都是 runtime 在每次 inference 前临时拼装的 context。
      • In-context memory:完整塞入对话历史
      • Summarization memory:用 LLM call 压缩历史
      • Retrieval-based memory(RAG):vector DB 检索 + 拼进 prompt
  1. Fine-tuning 属于 Training:fine-tuning 是"再训练",发生在部署之前,产出新 weights。一旦上线,weights 又冻结。
    1. 90% 的"让模型更好"的需求都不需要 fine-tuning,而是靠 prompt engineering + tool design + context engineering 解决。
  1. Temperature 控制采样随机性
    1. Temperature
      行为
      T = 0
      永远选概率最高的(greedy decoding)
      T = 0.7(默认)
      按概率采样,偏向高分
      T = 1.5
      分布被"压平",低分 token 也有机会
      Agent 工程里,对精度敏感的任务通常 T=0(tool_call、结构化输出),创意任务才用高 T。

六、Runtime 是什么

关键认知(破除翻译陷阱)

"运行时"这个中文翻译害了一代人。Runtime 在工程语境里指的是「执行者」,不是「时间段」,也不是「动作集合」。
英文原意更准确的翻译应该是 "运行器" 或 "运行环境"。听到"运行时" → 想成"那个跑代码的程序"。

精确定义

Agent Runtime = 你(开发者)自己写的、负责编排整个 Agent 工作流的那段程序。
三个关键词:
  1. "你自己写的" —— Runtime 不是 LLM 自带的,是你作为工程师亲手写的代码
  1. "编排" —— 它的核心动作是"指挥",告诉每一步该干什么
  1. "程序" —— 它是一段实实在在的代码,不是抽象概念

Runtime vs LLM 的分工

破除"Agent 很聪明"的幻觉

LLM 那一侧只会做一件事:text in → text out 其他所有"智能"行为,全是 Runtime 在后台编排出来的:
  • "会调工具" → 是 Runtime 解析 tool_call 然后真去调的
  • "会循环" → 是 Runtime 写了个 while 循环
  • "会纠错" → 是 Runtime 把错误信号塞回 context
  • "有记忆" → 是 Runtime 在每轮请求前重新拼装历史

七、Agent Loop 完整骨架

标准流程(订机票场景)

循环结构(ReAct 的工程实现)

这个循环结构就是 ReAct (Reasoning + Acting) 的工程实现。Hermes-agent、Cursor、Claude Code、LangGraph,全是这个骨架的工业级变种。

八、System Prompt vs Tool Schema(重要区分)

关键直觉的修正

直觉:"最后不都是文本喂给模型吗?" → ✓ 物理上对,工程上错。
关键差异不在"是不是文本",而在"谁负责把它变成文本"。

两种写法对比

写法 A:自己拼到 system prompt(不推荐)
写法 B:用 API 的 tools 参数(业界标准)

为什么必须分两个通道?

【第一层】文本是模型厂商内部"翻译"出来的,不是你拼的
Anthropic/OpenAI 后端会按官方训练时见过的格式把 schema 拼进 prompt。这个格式经过 fine-tune,模型对它极度熟悉
【第二层】响应通道完全不同
  • 写法 A:模型返回一段 text,里面"藏着"JSON,你得自己挖
  • 写法 B:模型在专门的 tool_use 字段输出结构化对象,Runtime 直接用
【第三层】这是模型厂商的"售后保证"边界
用写法 B,厂商保证 tool_use 字段里的 JSON 是合法的(合 schema 的)。用写法 A,全凭模型当时心情。

对比表

维度
System Prompt
Tool Schema
API 参数
messages 字段里 role="system"
独立的 tools 字段
内容形式
自然语言指令
JSON Schema 结构
目的
告诉模型"你是谁、怎么说话、有什么原则"
告诉模型"你有哪些工具、参数怎么传"
响应通道
模型在 text 字段回话
模型在 tool_use 字段输出结构化调用
结构保证
无 —— 模型说啥是啥
强 —— 厂商保证格式合 schema

类比

想象你给秘书发指令:
  • System Prompt = 说明信:"你是我的秘书,请专业、礼貌"
  • Tool Schema = 操作手册:"打印机用法、订餐流程、报销表格在哪"
  • User Message = 具体请求:"帮我订明天的午餐"
这三样都是纸,但秘书拿到时分门别类放在不同抽屉,处理方式完全不同。

九、关键认知速查(要背的几句)

  1. LLM 只是 token generator —— 它从来没有真的"调用"过任何函数。
  1. Function Calling 是整套机制的名字,不是其中某一步。它包括:声明阶段、输出阶段、执行阶段(Runtime 阶段)。
  1. LLM 是无状态的(stateless) —— 每次 inference 都是冷启动。所谓"记忆"全是 Runtime 制造的幻觉。
  1. Self-correction 依赖"错误信号能进 context" —— 不能产生信号的错误就是 silent failure。
  1. Runtime 是"执行者",不是"时间段" —— 它是你写的那段编排代码。
  1. Agent 的"智能"是 LLM + Runtime 的合奏 —— 单独把模型拎出来,它什么也做不了。
  1. Tool Schema 走独立的 tools 字段 —— 不要自己拼到 system prompt 里。

十、待深入的话题(后续讨论)

Tool 设计:description 怎么写、参数粒度、错误信息怎么让模型自我纠正
Context Engineering:多轮交互怎么保留/压缩 history,prompt caching 怎么打
Planning:plan-and-execute vs ReAct
Memory:working memory vs long-term memory
Parallel tool calls:模型一次性吐多个 tool_call,runtime 并发执行
Multi-agent orchestration:子 Agent 作为 tool 暴露给主 Agent
hermes-agent 真实代码走读
上一篇
与claude code相关的资源聚合
下一篇
Nginx 核心概念笔记