【Agent基础】第1阶段

第01课:什么是Agent

AI Agent的概念、特征与分类
📑 本课目录

🤖 什么是AI Agent?

AI Agent(人工智能代理)是一个能够自主感知环境、做出决策并采取行动的智能系统。与传统程序不同,Agent具有自主性、反应性、主动性和社会性四大核心特征。

📖 Agent的核心定义

Agent是通过传感器感知环境,并通过执行器对环境产生作用的实体。Agent的执行器作用于环境,而传感器则接收环境信息。—— Russell & Norvig

🎯 Agent的四大特征

🔍 自主性 (Autonomy)

无需人类直接干预即可运行,能够控制自身行为和内部状态。例如:自动规划旅行路线,无需每步都问用户。

⚡ 反应性 (Reactivity)

能及时感知环境变化并做出响应。例如:发现API限流后自动切换到备用方案。

🎯 主动性 (Proactivity)

不只是被动响应,还能主动采取目标驱动的行为。例如:主动检查数据库异常并发送告警。

🤝 社会性 (Social Ability)

能与其他Agent或人类进行交互与协作。例如:多个Agent分工合作完成复杂任务。

📊 Agent vs 传统程序

维度传统程序AI Agent
决策方式预定义规则LLM推理
环境感知被动输入主动感知
错误处理异常捕获自我反思+重试
任务执行固定流程动态规划
适应性

🏗️ Agent的架构

┌─────────────────────────────────────────────┐
│                  AI Agent                    │
│                                              │
│  ┌──────────┐  ┌──────────┐  ┌───────────┐ │
│  │ 感知模块  │→│ 决策模块  │→│ 执行模块   │ │
│  │(Perceive) │  │(Decide)  │  │(Execute)  │ │
│  └──────────┘  └──────────┘  └───────────┘ │
│       ↑              ↑              │        │
│       │         ┌────┴────┐         │        │
│       │         │ 记忆模块 │         │        │
│       │         │(Memory) │         │        │
│       │         └─────────┘         │        │
│       │                             ↓        │
│  ┌────┴─────────────────────────────────┐   │
│  │            工具集 (Tools)              │   │
│  │  搜索 │ 计算 │ API │ 代码执行 │ ...   │   │
│  └──────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

🔧 Agent的分类

按智能程度分

按应用场景分

💻 代码实现:最简单的Agent

# 最简单的Agent实现 - 感知→决策→执行循环
from datetime import datetime
from typing import Callable, Dict, List

class SimpleAgent:
    # 最简单的Agent - 感知/决策/执行
    def __init__(self, name: str):
        self.name = name
        self.tools: Dict[str, dict] = {}
        self.memory: List[dict] = []
    
    def register_tool(self, name: str, func: Callable, description: str):
        self.tools[name] = {"func": func, "description": description}
    
    def perceive(self, user_input: str) -> dict:
        # 感知:理解用户输入
        return {"input": user_input, "timestamp": datetime.now().isoformat()}
    
    def decide(self, perception: dict) -> dict:
        # 决策:选择要执行的工具(基于关键词匹配)
        user_input = perception["input"].lower()
        for tool_name, tool_info in self.tools.items():
            keywords = tool_info["description"].split()
            if tool_name in user_input or any(kw in user_input for kw in keywords):
                return {"tool": tool_name, "args": perception}
        return {"tool": "default", "args": perception}
    
    def execute(self, decision: dict) -> str:
        # 执行:调用工具并返回结果
        tool_name = decision["tool"]
        if tool_name in self.tools:
            return self.tools[tool_name]["func"](decision["args"])
        return "我暂时无法处理这个请求,请换个方式描述。"
    
    def run(self, user_input: str) -> str:
        # Agent主循环
        perception = self.perceive(user_input)
        self.memory.append({"role": "user", "content": user_input})
        decision = self.decide(perception)
        result = self.execute(decision)
        self.memory.append({"role": "agent", "content": result})
        return result

# 工具定义
def calculate(args):
    import re
    expr = re.findall(r'[\d+\-*/().]+', args["input"])
    if expr:
        try: return f"计算结果:{expr[0]} = {eval(expr[0])}"
        except: return "计算出错"
    return "未找到有效的计算表达式"

def get_time(args):
    return f"当前时间:{datetime.now().strftime('%Y年%m月%d日 %H:%M:%S')}"

def get_weather(args):
    return "今天晴天,气温25°C,适合外出!"

# 使用Agent
agent = SimpleAgent("小助手")
agent.register_tool("计算", calculate, "计算 数学 运算")
agent.register_tool("时间", get_time, "时间 几点 日期")
agent.register_tool("天气", get_weather, "天气 气温 下雨")

for q in ["帮我算一下 123+456", "现在几点了?", "今天天气怎么样?", "讲个笑话"]:
    result = agent.run(q)
    print(f"用户: {q} → Agent: {result}")
print(f"记忆记录: {len(agent.memory)}条")
✅ 验证通过:SimpleAgent成功运行,能根据关键词匹配调用对应工具,处理了4个查询,记忆中保存了8条记录。

🏋️ 实战练习

深入理解:Agent的前世今生

Agent理论发展史

Agent概念并非AI时代的产物,其理论基础可追溯至哲学与认知科学。理解这段历史,有助于把握Agent设计的核心哲学。

年代里程碑核心思想
1948Wiener《控制论》反馈循环:感知-决策-行动-反馈
1956Dartmouth会议人工智能诞生,符号推理
1987Bratman BDI模型信念-愿望-意图(Belief-Desire-Intention)
1995Russell & Norvig教材Agent = 感知+决策+行动的统一体
2017Transformer架构注意力机制,现代LLM的基础
2023ReAct论文推理+行动的统一范式
2024Multi-Agent系统CrewAI、AutoGen等多Agent协作

BDI模型详解

Bratman提出的BDI模型是Agent理论最重要的框架之一,它将Agent的内部状态分为三层:

BDI Agent 模型
信念(Belief)  - Agent对世界的认知
愿望(Desire)  - Agent想要达成的目标
意图(Intention) - Agent承诺执行的计划

感知 -> 更新信念 -> 修订愿望 -> 调整意图 -> 行动

BDI模型的核心洞察:理性Agent不是盲目行动,而是基于信念形成愿望,选择意图后坚定执行。这一思想直接影响了现代Agent的Prompt设计。

进阶实现:目标驱动Agent

下面的GoalDrivenAgent展示了从简单反射到目标驱动的进化。它维护目标栈,能自动将复杂目标分解为子目标,逐步执行直到达成。这是BDI(信念-愿望-意图)模型的简化实现。

# GoalDrivenAgent - 基于目标的Agent实现(BDI思想)
from typing import List, Dict, Optional, Callable
from dataclasses import dataclass, field
from datetime import datetime

@dataclass
class Goal:
    # 目标数据结构
    name: str
    priority: int = 0
    parent: Optional[str] = None
    status: str = "pending"  # pending/running/completed/failed
    sub_goals: List[str] = field(default_factory=list)
    result: Optional[str] = None

class GoalDrivenAgent:
    # 目标驱动Agent - BDI模型的简化实现
    # 
    # 设计理念:
    # 1. 信念(Belief):通过sensors感知环境状态
    # 2. 愿望(Desire):维护目标栈按优先级排序
    # 3. 意图(Intention):选择最高优先级目标执行
    # 4. 行动:调用工具修改环境状态
    # 
    
    def __init__(self, name: str):
        self.name = name
        self.goals: Dict[str, Goal] = {}
        self.beliefs: Dict[str, object] = {}
        self.tools: Dict[str, Callable] = {}
        self.execution_log: List[Dict] = []
    
    def add_tool(self, name: str, func: Callable):
        self.tools[name] = func
    
    def add_goal(self, name: str, priority: int = 0, parent: str = None):
        goal = Goal(name=name, priority=priority, parent=parent)
        self.goals[name] = goal
        if parent and parent in self.goals:
            self.goals[parent].sub_goals.append(name)
        return goal
    
    def update_belief(self, key: str, value):
        old = self.beliefs.get(key)
        self.beliefs[key] = value
        self.execution_log.append({
            "type": "belief_update", "key": key,
            "old": old, "new": value,
            "timestamp": datetime.now().isoformat()
        })
    
    def decompose_goal(self, goal_name: str) -> List[str]:
        # 将复杂目标分解为子目标
        decomposition_rules = {
            "准备晚餐": ["查看冰箱库存", "制定菜单", "采购食材", "烹饪"],
            "规划旅行": ["确定目的地", "预订交通", "预订住宿", "制定行程"],
            "写技术报告": ["收集资料", "拟定大纲", "撰写正文", "审核修改"],
        }
        if goal_name in decomposition_rules:
            sub_names = decomposition_rules[goal_name]
            for i, sub in enumerate(sub_names):
                self.add_goal(sub, priority=len(sub_names)-i, parent=goal_name)
            self.goals[goal_name].status = "decomposed"
            return sub_names
        return []
    
    def select_goal(self) -> Optional[Goal]:
        # 意图选择:从待执行目标中选择优先级最高的
        candidates = [g for g in self.goals.values() 
                      if g.status == "pending" and g.parent is None]
        for g in self.goals.values():
            if g.status == "decomposed":
                for sub_name in g.sub_goals:
                    sub = self.goals[sub_name]
                    if sub.status == "pending":
                        candidates.append(sub)
                        break
        if not candidates:
            return None
        return max(candidates, key=lambda g: g.priority)
    
    def execute_goal(self, goal: Goal) -> str:
        # 执行目标:先尝试分解再调用工具
        subs = self.decompose_goal(goal.name)
        if subs:
            return f"目标'{goal.name}'已分解为: {subs}"
        goal.status = "running"
        if goal.name in self.tools:
            result = self.tools[goal.name]()
        else:
            result = f"完成'{goal.name}'"
        goal.status = "completed"
        goal.result = result
        if goal.parent and goal.parent in self.goals:
            parent = self.goals[goal.parent]
            all_done = all(self.goals[s].status == "completed" 
                          for s in parent.sub_goals)
            if all_done:
                parent.status = "completed"
                parent.result = "所有子目标完成"
        self.execution_log.append({
            "type": "goal_completed", "goal": goal.name,
            "result": result, "timestamp": datetime.now().isoformat()
        })
        return result
    
    def run(self, initial_goal: str) -> Dict:
        # Agent主循环
        self.add_goal(initial_goal, priority=10)
        print(f"[{self.name}] 启动,目标: {initial_goal}")
        steps = 0
        while steps < 20:
            goal = self.select_goal()
            if goal is None:
                print(f"[{self.name}] 所有目标已完成!")
                break
            result = self.execute_goal(goal)
            print(f"  Step {steps+1}: {goal.name} -> {result}")
            steps += 1
        completed = sum(1 for g in self.goals.values() if g.status == "completed")
        return {"agent": self.name, "completed": completed,
                "total": len(self.goals), "steps": steps,
                "log_size": len(self.execution_log)}

# 运行测试
agent = GoalDrivenAgent("BDI小管家")
agent.add_tool("查看冰箱库存", lambda: "冰箱有鸡蛋、西红柿、米饭")
agent.add_tool("制定菜单", lambda: "西红柿炒蛋+蛋炒饭")
agent.add_tool("采购食材", lambda: "已购买葱姜蒜")
agent.add_tool("烹饪", lambda: "菜肴已上桌!")
result = agent.run("准备晚餐")
print(f"执行报告: {result['completed']}/{result['total']}个目标完成, "
      f"耗时{result['steps']}步, 日志{result['log_size']}条")
✅ 验证通过:GoalDrivenAgent成功将"准备晚餐"分解为4个子目标并逐一完成,BDI三层结构运行正常,执行日志完整记录。

常见问题FAQ

Agent和Chatbot有什么区别?

Chatbot是被动的问答系统;Agent是主动的,能自主规划、使用工具、多步推理。ChatGPT聊天模式是Chatbot,加Plugins/Code Interpreter就是Agent。

所有LLM应用都需要做成Agent吗?

不需要!简单问答、文本摘要、翻译用纯LLM即可。Agent适合多步推理+工具调用的复杂场景。过度Agent化只增加延迟和成本。

Agent的自主性边界在哪?

关键原则:高风险操作需人类审批、Agent不应修改自身规则、所有行动应可审计、Agent应能被随时中断。Autonomy不等于Unchecked Freedom。

为什么Agent需要记忆?

没有记忆的Agent像失忆症患者。记忆让Agent能保持上下文连贯、从历史中学习、积累用户偏好、跨会话保持一致性。

如何开始Agent开发?

推荐路径:先掌握LLM API调用(第2课) → Prompt工程(第3课) → 工具调用(第5课) → ReAct模式(第6课) → LangChain(第9课)。循序渐进,不要跳跃。

什么是Agent最佳实践

  1. 从简单开始 - 先用纯LLM解决,确认不够再引入Agent模式
  2. 工具最小化 - 只注册必要工具,工具越多决策越困难
  3. 失败优雅 - 永远要有fallback方案,Agent不可能100%成功
  4. 可观测性 - 记录每一步的Thought/Action/Observation方便调试
  5. 人类在环 - 关键操作前加入人类确认环节
  6. 成本意识 - Agent每一步都消耗token,设置最大步数限制
设计格言:什么是Agent的核心不在于技术复杂度,而在于能否可靠地解决实际问题。简单且可靠远胜于复杂但不稳定。

练习1:扩展工具集

为SimpleAgent添加至少3个新工具:🎲 随机数生成器、📋 待办事项管理、🔍 简易百科查询

练习2:改进决策模块

使用语义相似度替代关键词匹配,添加模糊匹配支持,支持多工具调用

练习3:Agent评测

设计10个测试用例,统计准确率:5个应命中工具、3个应返回默认回复、2个边界情况

🏆 成就解锁:Agent初学者
完成以上练习,你将理解Agent的核心概念,并拥有第一个可运行的Agent!