第一章 初识智能体 · 学习笔记

第一章 初识智能体 · 学习笔记

学习材料 :《Hello-Agents》第一章 初识智能体

配套代码code/chapter1/FirstAgentTest.py(已在本机跑通)

关键词:智能体四要素 · 传统智能体演进 · PEAS · Agent Loop · Thought-Action-Observation · 提示工程 · ReAct 雏形


一、知识地图

复制代码
第一章 初识智能体
├── 1.1 什么是智能体
│   ├── 1.1.1 传统视角:反射 → 基于模型 → 基于目标 → 基于效用 → 学习型
│   ├── 1.1.2 LLM 驱动的新范式
│   └── 1.1.3 三种分类维度(决策架构 / 时间反应性 / 知识表示)
├── 1.2 构成与运行原理
│   ├── 1.2.1 任务环境定义(PEAS + 环境五特性)
│   ├── 1.2.2 运行机制(Agent Loop)
│   └── 1.2.3 感知与行动(Thought / Action / Observation 交互协议)
├── 1.3 动手:5 分钟实现第一个智能体
│   ├── 1.3.1 准备工作(指令模板 + 两个工具)
│   ├── 1.3.2 接入大语言模型(OpenAI 兼容客户端)
│   ├── 1.3.3 执行行动循环(主循环 + 正则解析)
│   └── 1.3.4 运行案例分析
└── 1.4 协作模式:开发者工具 / 自主协作者 / Workflow vs Agent

一句话主线 :本章先把"智能体是什么"讲清楚,再告诉你它"怎么跑",最后让你亲手写一个不依赖任何框架的裸智能体 ------用 130 行代码把 Thought-Action-Observation 循环跑通。理解了这 130 行,后面所有框架(LangChain / AutoGen / LangGraph)都只是它的工程化封装。


二、核心概念

2.1 智能体的定义与四要素

智能体 = 任何能够通过传感器感知环境,并自主地通过执行器采取行动以达成特定目标的实体。

拆解出四个基本要素:

要素 含义 旅行助手中的对应
环境 Environment 智能体所处的外部世界 天气 API、搜索引擎、用户、其他预订者
传感器 Sensors 感知环境状态的手段 HTTP API 返回的 JSON、用户输入
执行器 Actuators 对环境施加影响的手段 调用 get_weather / get_attraction 函数
自主性 Autonomy 基于感知与内部状态独立决策 LLM 自行决定"先查天气再荐景点"

⚠️ 我理解的易错点 :定义的重心不在"能感知/能行动"(恒温器也能),而在于 自主性 ------它必须能独立决策,而不是被动响应刺激或严格执行预设指令。这也是后面 Agent 与 Workflow 的本质分界线

2.2 传统智能体的演进路线

这条演进线是本章最值得背下来的骨架,它本质上是在回答"当前感知不够用的时候,怎么办?":

类型 核心问题 决策依据 典型案例 局限
简单反射型 ------ 条件-动作规则 恒温器 无记忆、无预测,无法理解上下文
基于模型型 世界现在是什么样? 条件-动作 + 内部世界模型 隧道中行驶的自动驾驶 有记忆但无目标
基于目标型 我该做什么才能达成目标? 世界模型 + 目标 + 搜索/规划(A*) GPS 导航 目标单一,不会权衡
基于效用型 哪种行为结果最让我满意? 世界模型 + 效用函数 多目标路线规划(最快/最省油/避堵) 效用函数仍需人类设计
学习型 ------ 性能元件 + 学习元件(RL) AlphaGo Zero 训练成本高

记忆口诀规则 → 记忆 → 目标 → 权衡 → 自学习。前四类靠人类先验知识,第五类才首次引入"从经验中自我修正"。

关键洞察:学习能力是一种"元能力",可以叠加到前面任何一种架构上。

2.3 LLM 驱动的新范式

核心差异:传统智能体的能力来自工程师的显式编程;LLM 智能体的能力来自海量数据预训练得到的隐式世界模型与涌现能力。

维度 传统智能体 LLM 智能体
核心引擎 规则 / 模型 / 效用函数 大语言模型
知识来源 人工构建 预训练语料(隐式)
交互方式 结构化信号 自然语言
行为边界 确定、有边界 灵活、通用

以"规划厦门之旅"为例,LLM 智能体展现出三种能力:

  1. 规划与推理 :把高层模糊目标分解为子任务链 [确认偏好] → [查目的地] → [订行程] → [订票务]
  2. 工具使用:识别信息缺口并主动调用外部工具(查天气 → 发现下雨 → 倾向室内活动)
  3. 动态修正 :把用户反馈("酒店超预算")当作新约束,重新搜索

💡 思维转变 :从"开发专用自动化工具"变成"引导一个通用大脑去规划、行动和学习"。核心工作从写代码 变成了写提示 + 设计工具

2.4 智能体的三种分类维度

维度一:按内部决策架构 (源自 Russell & Norvig《AIMA》)

即 2.2 节的演进阶梯;学习能力是叠加在上述所有类型上的元能力。

维度二:按时间与反应性(本章最有工程指导意义的分类)

类型 特点 优势 代价 例子
反应式 感知→行动直接映射 快、开销低 短视,易陷局部最优 安全气囊、高频交易
规划式 先探索未来可能性再行动 战略性、有远见 慢、算力贵 下棋 AI、商业计划
混合式 分层:底层快速反应 + 高层审慎规划 兼得二者 架构复杂 现代 LLM 智能体

重点 :现代 LLM 智能体就是一种灵活的混合式架构------它把宏大的长期任务拆成一连串"规划-反应"微循环:

  • Thought(思考) 阶段做审议/规划(慢思考)
  • Action / Observation 阶段与环境交互并即时拿到反馈(快反应)

维度三:按知识表示(一场持续半个多世纪的辩论)

范式 知识形态 类比 优势 缺陷
亚符号主义(连接主义) 分布式统计模式 凭直觉认猫的孩童 模式识别强、抗噪、擅非结构化数据 黑箱、不擅逻辑推理、会幻觉
符号主义 显式规则与知识图谱 一丝不苟的图书管理员 透明、可解释、可追溯 脆弱、知识获取瓶颈
神经符号主义 二者融合 卡尼曼的系统 1 + 系统 2 既能学又能推理 工程实现难

🔑 本章点睛之笔LLM 智能体本身就是神经符号主义的一个绝佳实践范例。

  • 内核是巨大的神经网络 → 提供模式识别与语言生成(系统 1 / 亚符号
  • 运行中生成结构化的中间步骤(Thought、计划、API 调用)→ 这些是明确可操作的符号系统 2 / 符号

换句话说,"Thought-Action-Observation" 这套文本协议,就是给神经网络装上的符号接口


三、智能体如何运行

3.1 PEAS 模型

用四个字段精确描述任务环境:P erformance(性能度量)、E nvironment(环境)、A ctuators(执行器)、Sensors(传感器)。

以智能旅行助手为例:

维度 内容
Performance 推荐结果的准确性/相关性、用户满意度、响应速度
Environment 天气 API、搜索结果、用户对话、其他预订者
Actuators 调用 get_weather、调用 get_attraction、输出最终答案
Sensors 用户文本输入、API 返回的 JSON

3.2 数字环境的五个特性(直接影响设计)

特性 含义 对设计的要求
部分可观察 一次 API 调用拿不到全局信息 需要记忆 (记住查过的)+ 探索(换查询条件)
随机性 两次同样调用结果可能不同 需要处理不确定性、监控变化
多智能体 环境中有其他行动者(其他用户、调价系统) 需要快速响应与策略选择
序贯 当前动作影响未来 要维护上下文历史(案例里的 prompt_history
动态 决策时环境自身还在变 循环必须快而灵活

3.3 Agent Loop(智能体循环)

复制代码
        ┌──────────────────────────────────────┐
        │                                      │
   [环境 Environment] ──观察──▶ [感知 Perception]
        ▲                            │
        │                            ▼
   状态变化 State Change      [思考 Thought]
        │                     ├── 规划 Planning
        │                     └── 工具选择 Tool Selection
        │                            │
        └────行动 Action ◀───────────┘
                 (调用执行器/工具)

三个阶段:

  1. 感知 Perception:接收 Observation(可能是用户初始指令,也可能是上一步行动的反馈)
  2. 思考 Thought :核心决策阶段,细分为 规划 (分解目标、更新理解)与 工具选择(选工具 + 定参数)
  3. 行动 Action:通过执行器施加影响(调 API、跑代码)

行动不是终点:行动 → 环境状态变化 → 新观察 → 下一轮循环。循环往复,从初始状态逼近目标状态。

3.4 交互协议:Thought-Action-Observation

为了让 LLM 能驱动这个循环,需要一套明确的交互协议来规范输出格式。

复制代码
Thought: 用户想知道北京的天气。我需要调用天气查询工具。
Action: get_weather(city="北京")
    ↓ (外部解析器 Parser 捕获并执行)
Observation: 北京当前天气为晴,气温25摄氏度,微风。
    ↓ (作为下一轮循环的输入)

两个关键工程点:

  1. Thought 是给"人看"的:自然语言的内部推理快照,帮助提升推理质量与可调试性。
  2. Observation 需要"翻译" :环境返回的原始 JSON 含有 LLM 不需要的冗余信息,感知系统要负责把它封装成简洁的自然语言再喂回去。

这套模式就是后来 ReAct(Reasoning + Acting) 范式的思想内核:用自然语言把推理和行动交织在一起


四、代码精读(FirstAgentTest.py

4.1 整体架构

复制代码
┌─────────────────────────────────────────────────┐
│  AGENT_SYSTEM_PROMPT   ← 提示工程:角色/工具/格式  │
├─────────────────────────────────────────────────┤
│  get_weather()         ← 工具 1(wttr.in)        │
│  get_attraction()      ← 工具 2(Tavily Search)  │
│  available_tools{}     ← 工具注册表(名字→函数)   │
├─────────────────────────────────────────────────┤
│  OpenAICompatibleClient ← 大脑(任何 OpenAI 兼容)│
├─────────────────────────────────────────────────┤
│  主循环 for i in range(5)                        │
│    构建 Prompt → 调 LLM → 截断 → 解析 → 执行 → 记录│
└─────────────────────────────────────────────────┘

设计精髓 :不在代码里写 if 天气==晴天 then 推荐颐和园,而是把决策权完全交给 LLM,代码只负责"解析意图 + 执行工具 + 回填观察"。这就是 Agent 与 Workflow 的分野。

4.2 系统提示词:智能体的"说明书"

python 复制代码
AGENT_SYSTEM_PROMPT = """
你是一个智能旅行助手。你的任务是分析用户的请求,并使用可用工具一步步地解决问题。

# 可用工具:
- `get_weather(city: str)`: 查询指定城市的实时天气。
- `get_attraction(city: str, weather: str)`: 根据城市和天气搜索推荐的旅游景点。

# 输出格式要求:
你的每次回复必须严格遵循以下格式,包含一对Thought和Action:

Thought: [你的思考过程和下一步计划]
Action: [你要执行的具体行动]

Action的格式必须是以下之一:
1. 调用工具:function_name(arg_name="arg_value")
2. 结束任务:Finish[最终答案]

# 重要提示:
- 每次只输出一对Thought-Action
- Action必须在同一行,不要换行
- 当收集到足够信息可以回答用户问题时,必须使用 Action: Finish[最终答案] 格式结束

请开始吧!
"""

提示词的四段式结构拆解:

段落 作用 对应理论
角色定义 告诉模型"你是谁、要干什么" 设定目标
可用工具 声明 Action 空间与参数签名 Actuators
输出格式 约定协议的语法 交互协议
重要提示 约束行为,防止跑偏 输出稳定性

⚠️ "每次只输出一对 Thought-Action" 是最关键的一条约束 。不加这条,模型倾向于一口气把多轮推理全写出来,导致正则解析拿到错误的 Action。即便如此,代码里仍然保留了截断逻辑作为兜底(见 4.5)。

4.3 工具层

工具 1:真实天气查询(免费服务 wttr.in

python 复制代码
def get_weather(city: str) -> str:
    url = f"https://wttr.in/{city}?format=j1"
    try:
        response = requests.get(url)
        response.raise_for_status()          # 状态码非 200 时抛异常
        data = response.json()
        current_condition = data['current_condition'][0]
        weather_desc = current_condition['weatherDesc'][0]['value']
        temp_c = current_condition['temp_C']
        return f"{city}当前天气:{weather_desc},气温{temp_c}摄氏度"
    except requests.exceptions.RequestException as e:
        return f"错误:查询天气时遇到网络问题 - {e}"
    except (KeyError, IndexError) as e:
        return f"错误:解析天气数据失败,可能是城市名称无效 - {e}"

要点

  • format=j1wttr.in 返回 JSON 而非网页
  • 两层异常捕获:网络层(RequestException)+ 数据解析层(KeyError/IndexError
  • 错误也是字符串返回值 ,而不是抛出------这样错误会变成一条 Observation 回喂给 LLM,模型有机会自我修正(比如换个城市名重试)。这是智能体工具设计的通用原则。

工具 2:景点搜索(Tavily AI 搜索)

python 复制代码
def get_attraction(city: str, weather: str) -> str:
    api_key = os.environ.get("TAVILY_API_KEY")
    if not api_key:
        return "错误:未配置TAVILY_API_KEY。"
    tavily = TavilyClient(api_key=api_key)
    query = f"'{city}' 在'{weather}'天气下最值得去的旅游景点推荐及理由"
    try:
        response = tavily.search(query=query, search_depth="basic", include_answer=True)
        if response.get("answer"):
            return response["answer"]
        # 兜底:手动拼接原始结果
        formatted_results = [f"- {r['title']}: {r['content']}" for r in response.get("results", [])]
        if not formatted_results:
            return "抱歉,没有找到相关的旅游景点推荐。"
        return "根据搜索,为您找到以下信息:\n" + "\n".join(formatted_results)
    except Exception as e:
        return f"错误:执行Tavily搜索时出现问题 - {e}"

要点

  • include_answer=True 让 Tavily 直接返回一段综合性总结,省去自己拼接结果 ------ 这正是 3.4 节说的"把原始数据翻译成自然语言"的现成实现
  • 查询串构造融入了 weather 参数,体现上一步的 Observation 作为下一步的输入

工具注册表

python 复制代码
available_tools = {
    "get_weather": get_weather,
    "get_attraction": get_attraction,
}

一个字典就把"字符串工具名"映射到"可调用函数",主循环里 available_tools[tool_name](**kwargs) 一行完成分发。这是所有智能体框架 Tool/Function Calling 机制的极简原型。

4.4 大脑:OpenAI 兼容客户端

python 复制代码
class OpenAICompatibleClient:
    def __init__(self, model: str, api_key: str, base_url: str):
        self.model = model
        self.client = OpenAI(api_key=api_key, base_url=base_url)

    def generate(self, prompt: str, system_prompt: str) -> str:
        messages = [
            {'role': 'system', 'content': system_prompt},
            {'role': 'user',   'content': prompt}
        ]
        response = self.client.chat.completions.create(
            model=self.model, messages=messages, stream=False
        )
        return response.choices[0].message.content

要点

  • 只要服务商兼容 OpenAI 接口规范(OpenAI 官方 / Azure / Ollama / vLLM / DeepSeek...),这一份代码通吃 → 换服务只需改 base_url + model
  • 只用了 system + user 两种角色 :整段对话历史被压成一个 user 字符串 (见 4.5 的 full_prompt)。这是最朴素的"记忆"实现------用上下文窗口当记忆

💭 我的思考 :这种"历史拼成一个字符串"的做法,在生产环境会有问题(token 膨胀、角色混淆)。更规范的做法是用真正的 messages 数组,system / user / assistant 分明。这也是后续章节会升级的点。

4.5 主循环:逐行拆解

① 初始化
python 复制代码
user_prompt = "你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。"
prompt_history = [f"用户请求: {user_prompt}"]

prompt_history 是整个智能体的短期记忆 ,后续每轮都会追加 模型输出Observation

② 构建 Prompt 并调用 LLM
python 复制代码
full_prompt = "\n".join(prompt_history)
llm_output = llm.generate(full_prompt, system_prompt=AGENT_SYSTEM_PROMPT)

每轮都把完整历史重新喂给 LLM。LLM 本身是无状态的,"记忆"完全靠每次重放上下文。

③ 输出截断(防御性编程)
python 复制代码
match = re.search(r'(Thought:.*?Action:.*?)(?=\n\s*(?:Thought:|Action:|Observation:)|\Z)',
                  llm_output, re.DOTALL)
if match:
    truncated = match.group(1).strip()
    if truncated != llm_output.strip():
        llm_output = truncated
        print("已截断多余的 Thought-Action 对")

这个正则值得逐块读

片段 含义
(Thought:.*?Action:.*?) 捕获组:从 Thought:Action:非贪婪内容
`(?=\n\s*(?:Thought: Action:
re.DOTALL . 也能匹配换行符

目的 :即使模型不听话吐出了 3 对 Thought-Action,也只保留第一对 ,保证后面 Action: (.*) 解析到的是本轮该执行的那一个。

⭐ 这是本章最"工程"的一个细节。凡是靠 Prompt 约束 LLM 输出格式的地方,都必须有代码兜底。

④ 解析 Action
python 复制代码
action_match = re.search(r"Action: (.*)", llm_output, re.DOTALL)
if not action_match:
    observation = "错误: 未能解析到 Action 字段。请确保你的回复严格遵循 'Thought: ... Action: ...' 的格式。"
    prompt_history.append(f"Observation: {observation}")
    continue          # ← 注意:不是 break,而是把错误回喂后继续下一轮

解析失败不终止,而是把错误信息当作 Observation 回喂 ,让模型自己纠正格式。这是一个非常优雅的容错设计

⑤ 分支:结束 or 调工具
python 复制代码
action_str = action_match.group(1).strip()

# 分支 A:任务完成
if action_str.startswith("Finish"):
    final_answer = re.match(r"Finish\[(.*)\]", action_str).group(1)
    print(f"任务完成,最终答案: {final_answer}")
    break

# 分支 B:调用工具
tool_name = re.search(r"(\w+)\(", action_str).group(1)      # → get_weather
args_str  = re.search(r"\((.*)\)", action_str).group(1)     # → city="北京"
kwargs    = dict(re.findall(r'(\w+)="([^"]*)"', args_str))  # → {'city': '北京'}

if tool_name in available_tools:
    observation = available_tools[tool_name](**kwargs)   # 动态分发
else:
    observation = f"错误:未定义的工具 '{tool_name}'"

四个正则就是一套迷你"函数调用解析器"

正则 输入示例 输出
(\w+)\( get_weather(city="北京") get_weather
\((.*)\) 同上 city="北京"
(\w+)="([^"]*)" 同上 {'city': '北京'}

设计亮点 :未知工具不抛异常,而是返回 错误:未定义的工具 'xxx' 作为 Observation。让 LLM 知道"这条路走不通",从而换个工具------这是智能体自主性的体现。

⑥ 记录观察、进入下一轮
python 复制代码
observation_str = f"Observation: {observation}"
prompt_history.append(observation_str)

至此完成一轮闭环,prompt_history 增长一条,for i in range(5) 进入下一轮。

最大循环次数 5 的意义 :防止 LLM 陷入"思考-调工具-再思考"的死循环,是一种安全阀


五、我的调试记录(环境配置)

章节原文用占位符写死了密钥,但是对后续使用API-key都得重新声明,且在代码内不安全。我做了如下改造,把配置抽到项目根目录的 .env

python 复制代码
from pathlib import Path
import requests
from dotenv import load_dotenv

env_path = Path(__file__).parent.parent.parent / ".env"
load_dotenv(env_path, override=True)
python 复制代码
API_KEY  = os.getenv("API_KEY")
BASE_URL = os.getenv("BASE_URL")
MODEL_ID = os.getenv("MODEL_NAME")          

要点记录

说明
路径计算 __file__chapter1/code/项目根.env 放在仓库根目录
override=True 强制用 .env 覆盖系统已有的同名环境变量,避免被旧值污染
变量名不一致 代码里变量叫 MODEL_ID,但 .env 里的键是 MODEL_NAME ⚠️
依赖安装 pip install requests tavily-python openai python-dotenv
密钥获取 Tavily 需在 tavily.com 注册获取

🔐 安全提醒.env 已在 .gitignore 中,切勿把真实密钥提交到仓库。


六、运行结果分析

成功的执行流程是一个标准的三轮循环

轮次 Thought(推理) Action(行动) Observation(反馈)
1 需要先拿到北京天气 get_weather(city="北京") 北京当前天气:Sunny,气温 26℃
2 已知晴天、温度适中,可以推荐景点了 get_attraction(city="北京", weather="Sunny") 颐和园(湖景+古建)、长城(壮观+历史)
3 信息够了,可以给用户答复 Finish[今天北京天气晴朗...推荐颐和园或长城...] ------ 任务结束

四项核心能力的体现(对应 1.3.4):

  1. 任务分解 ------ 轮 1 就把"查天气+荐景点"拆成了两步
  2. 工具调用 ------ 自主构造参数 weather="Sunny"(把轮 1 的观察值准确传递给了工具 2)
  3. 上下文理解 ------ 轮 2 的推理明确引用了"北京今天的天气是晴朗且温度适中"
  4. 结果合成 ------ 轮 3 把天气与景点融合成一段人性化回答

⭐ 特别注意第 2 点:模型不是机械地把 weather 参数填成 "晴天",而是填了 API 返回的原始值 Sunny 。这说明它真正读懂了 Observation,而不是在猜。


七、踩坑与改进思考

7.1 现有实现的潜在问题

# 问题 说明 改进方向
1 历史被拼成单一 user 串 角色信息丢失,长对话 token 膨胀 改用 messages 数组,按 role 组织
2 正则解析脆弱 参数值含引号/换行/中文括号就可能解析失败 改用 JSON 格式输出 + json.loads;或用原生 Function Calling
3 无重试机制 网络抖动时工具直接返回错误字符串 加指数退避重试
4 最大轮次写死为 5 简单任务够用,复杂任务不够 结合 token 预算与任务复杂度动态控制

八、习题思路速记

习题 1 · 判断是否是智能体

Case 是否智能体 分析要点
A. 冯·诺依曼超算 只有算力,无感知-行动闭环,无自主性。它是工具而非智能体
B. 特斯拉自动驾驶(刹车/变道) 混合式:毫秒级反应 → 反应式;路径规划 → 规划式。环境:部分可观察、动态、多智能体
C. AlphaGo 典型规划式 + 学习型(基于效用:胜率即效用函数)
D. ChatGPT 智能客服 LLM 智能体,混合式;任务分解 + 工具调用(查订单库)+ 多目标(解决问题 & 安抚情绪 → 效用权衡)

习题 2 · 智能健身教练 PEAS

  • P:训练目标达成度(减脂/增肌/耐力提升)、动作标准度、用户留存/满意度、安全性(避免受伤)
  • E:用户身体、可穿戴设备、健身房/居家场景、饮食环境
  • A:语音播报指导、调整训练计划、推送饮食建议、震动/提醒
  • S:心率/配速/加速度传感器、用户手动输入(目标、反馈)、训练历史
  • 环境特性 :部分可观察(看不到饮食作息)· 随机性(生理反应个体差异)· 动态(心率实时变化)· 序贯(今日训练影响明日状态)· 含人(用户本身也是环境中的行动者)

习题 3 · Workflow vs Agent(退款审批)

方案 A:Workflow 方案 B:Agent
优点 确定、可审计、快、成本低、合规友好 灵活、能处理规则外情形、用户体验好
缺点 脆弱,遇规则外情形就卡住 不确定、难审计、成本高、可能误判
  • Workflow 更合适:规则明确、金额敏感、需强合规审计(金融/医疗)、量大且标准化
  • Agent 更有优势:情形复杂模糊、需综合多源信息、长尾案例多、追求用户满意度
  • 方案 C(推荐)Workflow 主流程 + Agent 兜底 ------ 明确的规则走确定性流程;规则未覆盖或置信度低的 case 转交 Agent 决策,并对 Agent 的决策保留人工复核与审计日志。既守住合规底线,又覆盖长尾。

习题 4 · 给旅行助手加功能

  1. 记忆用户偏好
    • 简单版:把偏好写进 prompt_history 开头,或单独维护一个 user_profile 字典
    • 进阶版:引入外部长期记忆(向量库),按相关性检索后注入 System Prompt
  2. 门票售罄自动备选
    • get_attraction 的返回约定为结构化列表(含余票字段)
    • 在 Thought 中提示模型:"若首选不可用,须给出至少 2 个备选"
  3. 连续被拒 3 次后反思
    • prompt_history 中维护一个计数器
    • 达到阈值时,主动注入一条 Observation,如 "用户已连续拒绝3次推荐,请反思并调整策略(如更换风格/提高预算弹性/主动询问偏好)" ------ 这其实就是**Reflection(反思)**模式的雏形

习题 5 · 系统 1 / 系统 2 协同(以医疗诊断助手为例)

  • 系统 1(快、直觉):医学影像初筛、生命体征异常检测、急诊分诊、常见病快速初判
  • 系统 2(慢、审慎):鉴别诊断推理、药物相互作用核查、结合病史的个体化方案、罕见病排查
  • 协同 :系统 1 做高召回 的快速初筛并给出候选 → 系统 2 对候选做高精度 的深度推理与验证 → 两者结论不一致时必须升级到系统 2(或人类医生) 。这与 LLM 智能体的结构完美对应:神经网络直觉 + 符号化推理链

习题 6 · 局限与评估

  • 幻觉来源:预训练知识有噪声/过时;缺乏对事实的实时校验;目标是"生成流畅文本"而非"保证真实";上下文不足以约束 → 缓解:接工具查证、要求引用来源、输出后自检
  • 不设最大轮次会怎样 :陷入无限循环 ------反复调用同一工具、在两个方案间来回摇摆、误判"信息不足"而不断探索,最终烧光 token 与 API 费用。所以必须有预算/步数/timeout 三重护栏
  • 如何评估智能体 :仅看准确率远远不够 。至少还需关注:
    • 过程指标:步数效率、工具调用正确率、是否走弯路、是否陷入循环
    • 鲁棒性:面对异常输入/工具失败时的恢复能力
    • 成本:token 消耗、延迟、API 花费
    • 安全与合规:有无越权操作、有无幻觉输出
    • 可解释性:Thought 链条是否合理可追溯

九、本章小结

本章回顾

  1. 是什么 :智能体 = 感知 + 思考 + 行动 的自主闭环,核心是自主性
  2. 怎么跑Observation → Thought(规划+工具选择) → Action → Observation → ...,LLM 提供大脑,工具提供手脚,上下文提供记忆
  3. 怎么写好的 System Prompt(定义人设/工具/协议) + 健壮的输出解析(正则 + 截断 + 容错) + 安全的循环控制(最大轮次)

核心公式

复制代码
LLM 智能体 = 大语言模型(大脑)
           + 工具集(手脚)
           + 提示词模板(说明书)
           + 解析器 & 循环控制(神经反射)

Agent vs Workflow 一句话

Workflow 是让 AI 按部就班地执行指令;Agent 是赋予 AI 自由度去自主达成目标。

判据:是否存在写死的 if 条件 then 动作 规则 。旅行助手里没有写 if 晴天 then 推荐颐和园------所以它是 Agent。

自测清单

  • 能说出智能体四要素,并解释为什么"自主性"最关键
  • 能画出传统智能体的五级演进阶梯及各阶段的核心局限
  • 能用 PEAS 描述任意一个智能体的任务环境
  • 能画出 Agent Loop 图,并说明 Thought 阶段的两个子环节
  • 能默写 Thought-Action-Observation 协议,并解释 Observation 为什么要"翻译成自然语言"
  • 能从零复现 FirstAgentTest.py,说清每个正则的作用
  • 能解释"输出截断"和"解析失败 continue 而非 break"这两个设计的用意
  • 能举出 2 个神经符号主义在 LLM 智能体中的对应关系
  • 能说清 Agent 与 Workflow 的本质区别,并各举一个适用场景

下一步

下一章将追溯智能体的发展历史。带着本章留下的一个问题继续前进:

今天的 LLM 智能体,在架构上究竟是全新范式,还是传统智能体演进的延续?从本章看,答案偏向后者------LLM 智能体本质上是"学习型 + 效用型 + 混合式"架构在神经符号主义下的一次大融合

相关推荐
Dshaw1 小时前
写Prompt卡壳?2000+ AI提示词模板一键复制
人工智能·prompt
乱码三千1 小时前
关于让我的 AI 智能体去当三陪帮我打工赚钱这件事,需要从长计议
人工智能·开源·产品
海宇大数据1 小时前
分布式网关架构实战:基于海宇数据公安二要素认证即时版构建自动化司机准入网关
人工智能·分布式·架构·自动化
宁渡AI大模型1 小时前
河南宁渡科技有限公司|宁渡课堂 AI 全栈面试分享,大模型 API 开发与流式输出面试题
人工智能·python·ai·大模型
Raas1001 小时前
AI网关核心功能?MAI Gateway(魔芋企业级AI网关)如何赋能企业AI能力
大数据·人工智能·gateway·mai gateway·企业级产品
IT·陈寒1 小时前
我的React组件莫名其妙重新渲染了8次
人工智能·大模型·api·创业·变现·简历优化
Java后端的Ai之路1 小时前
Git冲突完整排查与实战:本地修改覆盖报错到成功推送全流程复盘
开发语言·人工智能·git·python·pop
skywalk81631 小时前
AI 中台记录:使用码道基于deepseek harness制作AI数字中台9.14日
开发语言·人工智能·ai中台
寻道码路1 小时前
大模型工程化实战(十):Human-in-the-Loop 反馈闭环——三层清洗打造 Golden Set,拒绝“点赞即真理”
人工智能·大模型·ai工程化·hitl·反馈闭环·goldenset·数据回流