🤖 AI智能体详解

自主完成复杂任务的AI系统

🤖
什么是AI智能体?
Agent = 感知 + 推理 + 行动
智能体核心能力
┌─────────────────────────────────────────────────────────────────┐ │ │ │ 感知环境 → 分析推理 → 制定计划 → 执行行动 → 学习改进 │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 感知 │ ➜ │ 推理 │ ➜ │ 规划 │ ➜ │ 行动 │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘
对比
传统程序
AI智能体
行为模式
预定义规则
自适应学习
决策方式
固定逻辑
动态推理
目标导向
需人工规划
自主规划

📋 智能体类型

🔰 简单反射

基于规则直接响应

条件→动作

🧠 基于模型

维护环境模型

状态→模型→动作

🎯 目标导向

搜索目标路径

目标→规划→执行

🔄 规划智能体

分治策略

分解→解决→整合

📚 学习智能体

从经验学习

试错→强化→改进

👥 多智能体

协作与通信

分工→协作→共识

🧩 智能体核心组件

🛠️ 工具集 (Tools)

搜索 计算 API 数据库

智能体可调用的外部能力

🧠 记忆系统

短期记忆 长期记忆 向量存储

存储对话历史和经验

📝 提示工程

系统提示 few-shot CoT

引导智能体行为模式

🔄 执行引擎

ReAct Plan-Exec Tool Use

决策循环和执行逻辑

💾 记忆系统详解

为什么需要记忆系统?

AI智能体需要记忆来保持上下文一致性、学习用户偏好、在多轮对话中积累知识。没有记忆,智能体每次都是"从零开始"。

记忆类型 作用 存储方式 生命周期
工作记忆 当前任务执行过程中的中间状态 变量、内存 任务内
短期记忆 当前对话的上下文 对话历史(窗口) 会话内
长期记忆 跨会话的知识和经验 向量数据库、文件 永久

🔄 临时记忆(会话内)

📝 1)对话历史(Message History)

最基础的记忆方式,直接保存用户和AI的所有对话记录。

# 对话历史示例
messages = [
    {"role": "system", "content": "你是一个有帮助的助手"},
    {"role": "user", "content": "我叫张三"},
    {"role": "assistant", "content": "你好张三,很高兴认识你!"},
    {"role": "user", "content": "我刚才说的名字是什么?"},  # 需要记住上面的对话
]

# 问题:对话太长会超出上下文限制
# 解决方案:滑动窗口、摘要压缩
✂️ 2)上下文窗口管理

当对话超过模型上下文限制时,需要管理窗口大小。

from collections import deque

class ConversationWindow:
    """滑动窗口管理对话历史"""

    def __init__(self, max_tokens: int = 4000):
        self.max_tokens = max_tokens
        self.messages = deque()

    def add_message(self, role: str, content: str):
        self.messages.append({"role": role, "content": content})
        self._trim()

    def _trim(self):
        """裁剪超出限制的消息"""
        while self._estimate_tokens() > self.max_tokens and len(self.messages) > 1:
            # 移除最旧的消息(保留system消息)
            if self.messages[0]["role"] == "system":
                self.messages.popleft()
                self.messages.popleft()
            else:
                self.messages.popleft()

    def _estimate_tokens(self) -> int:
        # 简单估算:1 token ≈ 4 字符
        return sum(len(m["content"]) // 4 for m in self.messages)

    def get_context(self) -> list:
        return list(self.messages)

# 使用
window = ConversationWindow(max_tokens=4000)
window.add_message("user", "我叫张三")
window.add_message("assistant", "你好张三!")
window.add_message("user", "帮我查下天气")  # 如果超限,会自动裁剪
📜 3)对话摘要(Summarization)

定期将长对话压缩成摘要,减少token消耗同时保留关键信息。

class SummarizedConversation:
    """对话摘要模式"""

    def __init__(self, llm):
        self.llm = llm
        self.summary = ""
        self.recent_messages = []  # 保留最近N条消息
        self.summary_threshold = 10  # 多少条消息后摘要

    def add_message(self, role: str, content: str):
        self.recent_messages.append({"role": role, "content": content})

        # 达到阈值时生成摘要
        if len(self.recent_messages) >= self.summary_threshold:
            self._generate_summary()
            self.recent_messages = []  # 清空只保留摘要

    def _generate_summary(self):
        """调用LLM生成摘要"""
        prompt = f"请简要总结以下对话的核心要点(不超过100字):\n"
        for msg in self.recent_messages:
            prompt += f"{msg['role']}: {msg['content']}\n"

        self.summary = self.llm.call(prompt)
        print(f"📝 生成摘要: {self.summary}")

    def get_context(self) -> list:
        context = [{"role": "system", "content": f"会话摘要: {self.summary}"}]
        context.extend(self.recent_messages)
        return context

💾 永久记忆(跨会话)

🗄️ 1)向量数据库存储

将重要信息存入向量数据库,支持语义检索。

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.schema import Document

class VectorMemory:
    """向量数据库记忆"""

    def __init__(self):
        self.embeddings = OpenAIEmbeddings()
        self.vectorstore = None

    def add(self, text: str, metadata: dict = None):
        """添加记忆"""
        doc = Document(page_content=text, metadata=metadata or {})

        if self.vectorstore is None:
            self.vectorstore = FAISS.from_documents([doc], self.embeddings)
        else:
            self.vectorstore.add_documents([doc])

    def search(self, query: str, k: int = 3) -> list:
        """语义检索相关记忆"""
        if self.vectorstore is None:
            return []

        results = self.vectorstore.similarity_search(query, k=k)
        return [doc.page_content for doc in results]

    def save(self, path: str):
        """持久化保存"""
        self.vectorstore.save_local(path)

    def load(self, path: str):
        """加载已有记忆"""
        self.vectorstore = FAISS.load_local(path, self.embeddings)

# 使用示例
memory = VectorMemory()

# 保存用户偏好
memory.add(
    "用户喜欢简洁的技术方案,不喜欢太复杂的架构",
    metadata={"type": "preference", "topic": "architecture"}
)

memory.add(
    "用户主要使用Python开发",
    metadata={"type": "preference", "topic": "language"}
)

# 检索相关记忆
related = memory.search("应该用什么语言开发新项目?")
# 返回: ["用户主要使用Python开发", ...]
📁 2)结构化存储(JSON/SQL)

适合存储明确的结构化信息(用户信息、配置等)。

import json
from datetime import datetime

class StructuredMemory:
    """结构化记忆存储"""

    def __init__(self, storage_path: str = "memory.json"):
        self.storage_path = storage_path
        self.data = self._load()

    def _load(self) -> dict:
        try:
            with open(self.storage_path, "r", encoding="utf-8") as f:
                return json.load(f)
        except FileNotFoundError:
            return {"users": {}, "preferences": {}, "knowledge": []}

    def save(self):
        with open(self.storage_path, "w", encoding="utf-8") as f:
            json.dump(self.data, f, ensure_ascii=False, indent=2)

    def set_user_info(self, user_id: str, key: str, value):
        """保存用户信息"""
        if user_id not in self.data["users"]:
            self.data["users"][user_id] = {}
        self.data["users"][user_id][key] = value
        self.save()

    def get_user_info(self, user_id: str, key: str, default=None):
        """获取用户信息"""
        return self.data["users"].get(user_id, {}).get(key, default)

    def add_knowledge(self, fact: str, category: str):
        """添加知识"""
        self.data["knowledge"].append({
            "fact": fact,
            "category": category,
            "timestamp": datetime.now().isoformat()
        })
        self.save()

    def get_knowledge(self, category: str = None) -> list:
        """获取知识"""
        if category:
            return [k for k in self.data["knowledge"] if k["category"] == category]
        return self.data["knowledge"]

# 使用
memory = StructuredMemory("user_memory.json")
memory.set_user_info("user_123", "name", "张三")
memory.set_user_info("user_123", "language", "Python")
memory.add_knowledge("项目使用FastAPI框架", "tech_stack")
memory.add_knowledge("数据库是PostgreSQL", "tech_stack")
🧠 3)混合记忆系统

结合短期记忆和长期记忆,根据重要性自动分层。

class HybridMemory:
    """混合记忆系统:短期 + 长期"""

    def __init__(self):
        # 短期记忆:对话窗口
        self.short_term = ConversationWindow(max_tokens=2000)

        # 长期记忆:向量存储
        self.long_term = VectorMemory()

        # 重要信息:需要存入长期记忆
        self.important_patterns = ["偏好", "喜欢", "讨厌", "记住", "以后"]
        self.llm = None  # 需要注入LLM用于判断重要性

    def add_message(self, role: str, content: str):
        # 1. 加入短期记忆
        self.short_term.add_message(role, content)

        # 2. 判断是否需要存入长期记忆
        if self._is_important(content):
            self._store_to_long_term(content, role)

    def _is_important(self, content: str) -> bool:
        """判断内容是否重要"""
        # 方式1:关键词匹配
        for pattern in self.important_patterns:
            if pattern in content:
                return True
        # 方式2:LLM判断(更准确但更慢)
        # return self.llm.judge_importance(content)
        return False

    def _store_to_long_term(self, content: str, role: str):
        """存储到长期记忆"""
        self.long_term.add(
            text=f"{role}: {content}",
            metadata={"timestamp": datetime.now().isoformat()}
        )
        print(f"💾 已存入长期记忆: {content[:50]}...")

    def retrieve_context(self, current_query: str) -> list:
        """获取当前上下文"""
        # 1. 获取短期记忆(对话历史)
        short_context = self.short_term.get_context()

        # 2. 检索长期记忆(相关知识)
        long_context = self.long_term.search(current_query, k=3)

        # 3. 合并
        result = short_context.copy()

        if long_context:
            result.append({
                "role": "system",
                "content": f"相关记忆: {'; '.join(long_context)}"
            })

        return result

# 使用
memory = HybridMemory()

# 对话
memory.add_message("user", "我叫张三,从事Python开发")
memory.add_message("assistant", "好的张老师,很高兴认识你!")
memory.add_message("user", "帮我写个排序算法")  # "从事Python开发"会被存入长期记忆

# 检索
context = memory.retrieve_context("排序算法")
# 自动包含用户是Python开发者的信息

⚡ 记忆系统实践要点

场景 推荐方案 注意事项
单轮问答 无需记忆 简洁高效
简单多轮对话 对话历史窗口 控制窗口大小
复杂任务 工作记忆 + 对话摘要 定期压缩
个性化助手 混合记忆(短期+长期) 向量检索
知识库问答 RAG(向量检索) 定期更新

🔄 ReAct模式

ReAct = Reasoning + Acting
┌─────────────────────────────────────────────────────────────────┐ │ │ │ 思考(Thought) → 行动(Action) → 观察(Observation) → 循环 │ │ │ │ 1. Thought: 我需要搜索信息来回答这个问题 │ │ 2. Action: search[AI发展历史] │ │ 3. Observation: AI始于1956年达特茅斯会议... │ │ 4. Thought: 找到答案了,可以总结了 │ │ 5. Final Answer: ... │ │ │ └─────────────────────────────────────────────────────────────────┘

🔧 常见工具类型

工具类型 示例 用途
搜索SerpAPI, Wikipedia网络信息查询
计算Python REPL, Calculator数学计算
数据库SQL, MongoDB数据查询
APIHTTP请求第三方服务
文件读/写文件文档处理

🚀 应用场景

💬 智能客服

多轮对话、问题解答

📊 研究助手

信息搜集、分析总结

💻 代码助手

代码编写、调试、测试

📝 写作助手

内容创作、编辑校对

🔄 工作流

自动化流程编排

🌐 数据采集

信息抓取、整理

💻 代码示例

示例:ReAct智能体实现
"""
ReAct智能体实现:Thought → Action → Observation → ...
- 搜索工具
- 计算工具
- 文件读取工具
- 智能体核心逻辑
"""
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from enum import Enum
import json
import math
import re

class ActionType(Enum):
    SEARCH = "search"
    CALCULATE = "calculate"
    READ_FILE = "read_file"
    LIST_FILES = "list_files"
    FINISH = "finish"

@dataclass
class Action:
    type: ActionType
    input: str

@dataclass
class Step:
    thought: str
    action: Optional[Action]
    observation: str

class Tool:
    """工具基类"""
    
    @property
    def name(self) -> str:
        raise NotImplementedError
    
    @property
    def description(self) -> str:
        raise NotImplementedError
    
    def execute(self, input: str) -> str:
        raise NotImplementedError

class SearchTool(Tool):
    """搜索工具(模拟)"""
    
    @property
    def name(self) -> str:
        return "search"
    
    @property
    def description(self) -> str:
        return "搜索网络信息,返回相关结果"
    
    def execute(self, query: str) -> str:
        # 模拟搜索结果
        knowledge_base = {
            "人工智能": "AI是 Artificial Intelligence 的缩写,研究让机器具有智能的科学。",
            "机器学习": "Machine Learning,让计算机从数据中学习规律的技术。",
            "深度学习": "Deep Learning,使用多层神经网络的机器学习方法。",
            "python": "Python是一种流行的编程语言,适合AI开发。",
            "langchain": "LangChain是一个LLM应用开发框架。"
        }
        
        for key, value in knowledge_base.items():
            if key in query.lower():
                return value
        return f"关于'{query}'的搜索结果:这是一条模拟的搜索结果。"

class CalculatorTool(Tool):
    """计算工具"""
    
    @property
    def name(self) -> str:
        return "calculate"
    
    @property
    def description(self) -> str:
        return "执行数学计算,支持四则运算和函数"
    
    def execute(self, expression: str) -> str:
        try:
            # 安全计算
            allowed_chars = set("0123456789+-*/(). ")
            if not all(c in allowed_chars for c in expression):
                return "错误:包含不允许的字符"
            
            result = eval(expression)
            return f"计算结果: {result}"
        except Exception as e:
            return f"计算错误: {e}"

class FileTool(Tool):
    """文件操作工具"""
    
    def __init__(self):
        self.files = {
            "readme.txt": "这是一个示例文件。\n包含多行文本。",
            "notes.txt": "待办事项:\n1. 学习AI\n2. 实践项目"
        }
    
    @property
    def name(self) -> str:
        return "read_file"
    
    @property
    def description(self) -> str:
        return "读取文件内容"
    
    def execute(self, filename: str) -> str:
        if filename in self.files:
            return self.files[filename]
        return f"文件不存在: {filename}"

class ListFilesTool(Tool):
    """列出文件工具"""
    
    @property
    def name(self) -> str:
        return "list_files"
    
    @property
    def description(self) -> str:
        return "列出可用文件"
    
    def execute(self, input: str) -> str:
        return "可用文件: readme.txt, notes.txt"

class ReActAgent:
    """ReAct智能体 - Reasoning + Acting"""
    
    def __init__(self, tools: List[Tool], max_steps: int = 10):
        self.tools = {tool.name: tool for tool in tools}
        self.max_steps = max_steps
        self.history: List[Step] = []
    
    def think(self, query: str) -> str:
        """生成思考(使用LLM时这里是LLM调用)"""
        # 简化版:基于规则生成思考
        history_text = "\n".join([
            f"思考: {step.thought}\n行动: {step.action}\n观察: {step.observation}"
            for step in self.history[-3:]
        ]) if self.history else "无历史"
        
        prompt = f"""你是一个ReAct智能体,需要通过思考和行动来回答问题。

任务:{query}

历史:
{history_text}

请按照以下格式思考下一步:
Thought: [分析当前情况,决定下一步行动]
Action: [工具名称]([参数]) 或 Finish([最终答案])

可用的工具:
{self._format_tools()}"""

        # 这里简化处理,实际应调用LLM
        return self._simple_reasoning(query)
    
    def _simple_reasoning(self, query: str) -> str:
        """简化推理逻辑(实际使用LLM)"""
        query_lower = query.lower()
        
        # 检查是否需要搜索
        if any(kw in query_lower for kw in ["什么", "定义", "解释", "介绍"]):
            if "计算" in query or any(op in query for op in ["+", "-", "*", "/", "×", "÷"]):
                return "我需要先提取表达式,然后使用计算工具。"
            return "我需要搜索相关信息来回答这个问题。"
        
        # 检查是否需要文件
        if any(kw in query_lower for kw in ["文件", "内容", "read"]):
            return "我需要读取文件来获取信息。"
        
        # 检查是否完成
        if any(kw in query_lower for kw in ["谢谢", "好的", "明白了"]):
            return "Finish(任务完成)"
        
        return "我需要搜索更多信息来回答这个问题。"
    
    def _format_tools(self) -> str:
        return "\n".join([f"- {t.name}: {t.description}" for t in self.tools.values()])
    
    def parse_action(self, thought: str) -> Tuple[Optional[Action], str]:
        """解析行动"""
        # 检查是否结束
        if "Finish(" in thought:
            answer = re.search(r'Finish\((.+?)\)', thought)
            return Action(ActionType.FINISH, answer.group(1) if answer else ""), "finished"
        
        # 解析行动
        for tool_name in self.tools:
            if f"{tool_name}(" in thought:
                param = re.search(rf'{tool_name}\((.+?)\)', thought)
                return Action(ActionType(tool_name), param.group(1) if param else ""), tool_name
        
        return None, "continue"
    
    def run(self, query: str) -> str:
        """执行ReAct循环"""
        self.history = []
        current_query = query
        
        for step_num in range(self.max_steps):
            print(f"\n🔄 步骤 {step_num + 1}")
            
            # 1. Thought
            thought = self.think(current_query)
            print(f"💭 Thought: {thought}")
            
            # 2. Parse Action
            action, status = self.parse_action(thought)
            observation = ""
            
            # 3. Action & Observation
            if action and action.type != ActionType.FINISH:
                print(f"⚡ Action: {action.type.value}[{action.input}]")
                
                tool = self.tools.get(action.type.value)
                if tool:
                    observation = tool.execute(action.input)
                else:
                    observation = "未知工具"
                
                print(f"👀 Observation: {observation}")
            elif status == "finished":
                print(f"✅ 完成: {action.input}")
                return action.input
            
            # 4. 记录步骤
            self.history.append(Step(thought, action, observation))
            
            # 5. 更新查询(包含观察结果)
            current_query = f"基于观察:{observation}\n继续回答:{query}"
        
        return "达到最大步数限制"


# 使用示例
def main():
    # 1. 创建工具
    tools = [
        SearchTool(),
        CalculatorTool(),
        FileTool(),
        ListFilesTool()
    ]
    
    # 2. 创建智能体
    agent = ReActAgent(tools, max_steps=6)
    
    # 3. 测试不同任务
    test_queries = [
        "什么是人工智能?",
        "计算 25 * 4 + 10",
        "readme.txt的内容是什么?"
    ]
    
    for query in test_queries:
        print(f"\n{'='*50}")
        print(f"📝 任务: {query}")
        print("="*50)
        result = agent.run(query)
        print(f"\n🎯 最终答案: {result}")

main()
代码说明

🛠️ 工具类型

  • SearchTool - 搜索信息
  • CalculatorTool - 数学计算
  • FileTool - 读取文件
  • ListFilesTool - 列出文件

🔄 ReAct循环

  • Thought - 分析情况
  • Action - 选择工具
  • Observation - 观察结果
  • 循环直到完成

📊 关键组件

  • Tool基类 - 定义工具接口
  • Action类型 - 区分行动
  • 历史记录 - 上下文记忆
  • 最大步数 - 防止无限循环