hello-agents第一章笔记

216 阅读7分钟

Hello-Agents 是Datawhale社区的系统性智能体学习教程。
如今Agent构建主要分为两派,
一派是Dify,Coze,N8N这类软件工程类Agent,其本质只是将模型作为返回字符串的后端;
另一派则是AI原生的Agent,即真正以AI驱动的Agent。
本教程旨在带领大家深入理解并构建后者——真正的AI Native Agent。
教程将带领你穿透框架表象,从智能体的核心原理出发,深入其核心架构,理解其经典范式,并最终亲手构建起属于自己的多智能体应用。
我们相信,最好的学习方式就是动手实践。希望这本教程能成为你探索智能体世界的起点,能够从一名大语言模型的"使用者",蜕变为一名智能体系统的"构建者"。

项目地址:hello-agents
在线浏览

hello-agents项目内容概括:

  • 第一部分:智能体与语言模型基础(第1章~第3章),我们将从智能体的定义、类型与发展历史讲起,为你梳理"智能体"这一概念的来龙去脉。随后,我们会快速巩固大语言模型的核心知识,为你的实践之旅打下坚实的理论地基。
  • 第二部分:构建你的大语言模型智能体(第4章~第7章),这是你动手实践的起点。你将亲手实现 ReAct 等经典范式,体验 Coze 等低代码平台的便捷,并掌握 Langgraph 等主流框架的应用。最终,我们还会带你从零开始构建一个属于自己的智能体框架,让你兼具“用轮子”与“造轮子”的能力。
  • 第三部分:高级知识扩展(第8章~第12章),在这一部分,你的智能体将“学会”思考与协作。我们将使用第二部分的自研框架,深入探索记忆与检索、上下文工程、Agent训练等核心技术,并学习多智能体间的通信协议。最终,你将掌握评估智能体系统性能的专业方法。
  • 第四部分:综合案例进阶(第13章~第15章),这里是理论与实践的交汇点。你将把所学融会贯通,亲手打造智能旅行助手、自动化深度研究智能体,乃至一个模拟社会动态的赛博小镇,在真实有趣的项目中淬炼你的构建能力。
  • 第五部分:毕业设计及未来展望(第16章),在旅程的终点,你将迎来一个毕业设计,构建一个完整的、属于你自己的多智能体应用,全面检验你的学习成果。我们还将与你一同展望智能体的未来,探索激动人心的前沿方向。

第一章:智能体

什么是智能体/agent?

智能体的四要素:环境、传感器、执行器、自主性

  • 环境:可以简单理解为除了智能体之外的外部总和;
  • 传感器:雷达、红外传感器、摄像头等等(也包括文件读取组件等看不着的部分),这些组件帮助智能体感知环境;
  • 执行器:智能体控制的机械结构/装置或者计算器、编程器、文件读写等,这些组件帮助智能体改变状态,从而和环境互动;
  • 自主性:智能体最突出的特征,即自主决策、自主规划、自主执行等特点。

智能体的分类

按(快速)反应性和规划性分类:

  • 反应式智能体:需要瞬时响应
    • 优势:速度快、计算开销低
    • 劣势:短视,难以完成复杂任务
    • 例子:安全气囊系统、高频交易
  • 规划式智能体:需要复杂规划能力
    • 优势:决策战略性强、有远见
    • 劣势:时间和计算成本高
    • 例子:棋类AI、商业规划系统
  • 混合式智能体:既需要快速响应又需要一定的规划能力
    • 规划(Reasoning):在"思考"阶段,LLM分析当前状况,规划出下一步的合理行动。这是一个审议过程。
    • 反应(Acting & Observing):在"行动"和"观察"阶段,智能体与外部工具或环境交互,并立即获得反馈。这是一个反应过程。

五分钟简易demo:

# pip install requests tavily-python openai
import os,requests,json
from tavily import TavilyClient
from openai import OpenAI
import re

# 从环境变量获取API密钥等。请根据实际进行修改
# getting api key, base url,model name from environment variables
api_key = os.getenv("ZHIPUAI_API_KEY")
base_url = os.getenv("ZHIPUAI_BASE_URL")
model_name = os.getenv("ZHIPUAI_MODEL_NAME")
TAVILY_API_KEY=os.getenv("TAVILY_API_KEY")

# pormpt for ai assistant
AGENT_SYSTEM_PROMPT = """
你是一个智能旅行助手,能够帮助用户规划旅行并提供相关信息。

你有以下工具可以使用:
1. get_weather(city): 获取指定城市的天气信息
2. search_attraction(city, weather): 根据城市和天气搜索合适的旅游景点

请按照以下格式回复:
Thought: [你的思考过程]
Action: [要执行的动作,格式为函数调用]

如果不需要使用工具,请直接回复用户。
"""

# define the tool function get_weather
import requests
import json

def get_weather(city):
    """
    获取指定城市的天气信息
    这里使用模拟数据,实际应用中可以接入真实的天气API
    """
    # 模拟天气数据
    weather_data = {
        "北京": {"temperature": 25, "condition": "晴", "wind": "微风"},
        "上海": {"temperature": 28, "condition": "多云", "wind": "东南风"},
        "广州": {"temperature": 32, "condition": "雷阵雨", "wind": "南风"},
        "深圳": {"temperature": 30, "condition": "阴", "wind": "无风"}
    }
    
    if city in weather_data:
        data = weather_data[city]
        return f"{city}当前天气:{data['condition']},气温{data['temperature']}°C,{data['wind']}"
    else:
        return f"抱歉,暂时无法获取{city}的天气信息"


# define the tool function search_attraction
def search_attraction(city, weather):
    """
    根据城市和天气条件搜索合适的旅游景点
    """
    try:
        # 初始化Tavily客户端
        tavily = TavilyClient(api_key=TAVILY_API_KEY)
        
        # 构建搜索查询
        query = f"{city} {weather} 适合的旅游景点推荐"
        
        # 执行搜索
        response = tavily.search(query=query, max_results=3)
        
        # 处理搜索结果
        attractions = []
        for result in response.get('results', []):
            attractions.append({
                'title': result.get('title', ''),
                'content': result.get('content', '')[:200] + '...'
            })
        
        return f"根据{city}{weather}天气,推荐以下景点:" + \
               "\n".join([f"- {attr['title']}: {attr['content']}" for attr in attractions])
    
    except Exception as e:
        return f"搜索景点时出现错误:{str(e)}"

# 可用工具字典
available_tools = {
    "get_weather": get_weather,
    "search_attraction": search_attraction
}

# define the Client class
class OpenAICompatibleClient:
    def __init__(self):
        self.client = OpenAI(
            api_key=api_key,
            base_url=base_url
            #,
            #model_name=model_name
        )
    # glm-4.6貌似会出错
    def chat_completion(self, messages, model="glm-4.5"):
        """调用LLM进行对话"""
        try:
            response = self.client.chat.completions.create(
                model=model,
                messages=messages,
                temperature=0.7,
                max_tokens=1000
            )
            return response.choices[0].message.content
        except Exception as e:
            return f"调用LLM时出现错误:{str(e)}"
    
    def parse_action(self, response):
        """解析LLM响应中的Action"""
        # 使用正则表达式提取Action
        action_pattern = r'Action:\s*([a-zA-Z_]+)\((.*?)\)'
        match = re.search(action_pattern, response)
        
        if match:
            function_name = match.group(1)
            # 简单解析参数(实际应用中需要更robust的解析)
            params_str = match.group(2).strip('"\'')
            params = [p.strip().strip('"\'') for p in params_str.split(',') if p.strip()]
            return function_name, params
        
        return None, None

# define the agent runing function
def run_agent():
    """运行智能体主循环"""
    client = OpenAICompatibleClient()
    
    # 初始化对话历史
    messages = [{"role": "system", "content": AGENT_SYSTEM_PROMPT}]
    
    print("🤖 智能旅行助手已启动!输入 'quit' 退出。\n")
    
    while True:
        # 获取用户输入
        user_input = input("👤 用户: ").strip()
        if user_input.lower() == 'quit':
            print("👋 再见!")
            break
        
        # 添加用户消息到历史
        messages.append({"role": "user", "content": user_input})
        
        # 开始智能体循环
        max_iterations = 5  # 防止无限循环
        for iteration in range(max_iterations):
            print(f"\n🔄 循环 {iteration + 1}:")
            
            # 1. 思考阶段:调用LLM
            response = client.chat_completion(messages)
            print(f"🧠 智能体响应:\n{response}")
            
            # 2. 解析行动
            function_name, params = client.parse_action(response)
            
            if function_name and function_name in available_tools:
                # 3. 执行行动
                print(f"⚡ 执行工具: {function_name}({', '.join(params)})")
                
                try:
                    tool_result = available_tools[function_name](*params)
                    observation = f"Observation: {tool_result}"
                    print(f"👁️ 观察结果: {tool_result}")
                    
                    # 4. 将观察结果添加到对话历史
                    messages.append({"role": "assistant", "content": response})
                    messages.append({"role": "user", "content": observation})
                    
                except Exception as e:
                    error_msg = f"Observation: 工具执行出错 - {str(e)}"
                    print(f"❌ 错误: {str(e)}")
                    messages.append({"role": "assistant", "content": response})
                    messages.append({"role": "user", "content": error_msg})
            else:
                # 没有工具调用,直接结束循环
                messages.append({"role": "assistant", "content": response})
                print("✅ 任务完成!")
                break
        
        print("\n" + "="*50 + "\n")

# 运行智能体
if __name__ == "__main__":
    run_agent()