1 智能体是什么?

1.1 智能体定义

智能体: 能感知外界环境、自己做决定、主动行动,最终完成既定目标的人工智能实体
智能体流程

1.1.1 四大基本组成

  1. 环境:智能体所处的外部世界(自动驾驶面对马路、交易算法面对股市)

  2. 传感器:眼睛 / 耳朵,用来收集外界信息(摄像头、雷达、数据接口 API都算)

  3. 执行器:手脚,用来改变外界环境(方向盘、机械臂、代码指令都算)

  4. 自主性:核心智能,不是死板执行预设代码,能结合收集的信息独立做判断

  • 例: 自动驾驶领域,汽车上的摄像头、雷达等传感器时刻感知路况信息,包括道路标志、车辆位置、行人动态等环境。智能体根据这些信息,自主运用复杂的算法规划行驶路线、控制车速和方向,通过执行器操作方向盘、刹车和油门等部件,确保车辆安全、高效地运行。

1.2 传统智能体

按时间出现顺序

  1. 简单反射智能体(Simple Reflex Agent):基于"条件–动作"规则(if–then), 只会按固定规则做事,只看当下、没有记忆。
    例子:恒温器,温度高就制冷,不会预判、不会变通

  2. 基于模型的反射智能体(Model-Based Reflex Agent):拥有内部世界模型(World Model),用于追踪和理解环境中无法被直接感知的方面。自带记忆,能预判看不见的环境状态。
    例子:隧道里自动驾驶,摄像头看不到前车,依旧能记住前车位置、速度

  3. 基于目标智能体(Goal-Based Agent):带着目的主动规划行动,为了达成目标主动选路径,主要回答“如何才能达成目标?”
    例子:GPS 导航,以抵达目的地为目标,自主规划最佳行车路线

  4. 基于效用智能体(Utility-Based Agent):会权衡多个利弊目标,选最优最省心方案
    例子:导航不止到目的地,还会权衡省钱、省时、避堵,选最优路线

  5. 学习型智能体(Learning Agent):不靠人类预设规则,靠和环境试错、奖惩自主进化学习
    例子:AlphaGo Zero,从零自学下棋,摸索出人类不知道的下棋技巧

1.3 智能体分类

1.3.1 按内部决策架构分类

依据智能体内部思考逻辑、决策复杂程度划分,也是最经典分类:

  1. 反应式智能体:只看当下环境,靠固定规则做事,无长远思考
  2. 模型式智能体:自带环境记忆,能记住看不到的环境状态
  3. 目标式智能体:明确最终目的,主动规划行动路线
  4. 效用式智能体:兼顾多重需求,权衡利弊选出最优方案
  5. 学习型智能体:可叠加在以上所有类型上,靠实战经验自主优化决策,越用越聪明

1.3.2 按决策速度与反应性分类

核心区分:立刻行动还是深思熟虑再行动

  1. 反应式智能体
    收到信息马上响应,反应快、消耗资源少,适合紧急场景(安全气囊、高频交易);缺点目光短浅,做不了复杂长线任务。

  2. 规划式智能体
    行动前提前推演多种结果,擅长长远布局、统筹规划(制定行程、商业方案);缺点思考耗时久,容易错过最佳时机。

  3. 混合式智能体
    结合两者优势,底层快速应急反应,高层统筹长远规划。
    如今主流大模型智能体都属于此类,先思考规划,再行动观察反馈,灵活适配各类复杂场景。

1.3.3 按知识存储与表达形式分类

决定智能体靠什么产生智慧,是 AI 两大主流路线融合

  1. 符号主义 AI
    把知识整理成清晰文字、规则、逻辑公式,推理过程透明好解释;缺点死板,遇到没设定过的新问题容易出错。
  2. 亚符号主义 AI
    不靠明文规则,从海量数据里自学规律,擅长识图、语音、自然语言;缺点是黑箱决策,说不清判断依据,还容易出现逻辑错误。
  3. 神经符号主义 AI(主流新式)
    融合前两者优点,既拥有深度学习的直觉感知能力,又具备符号逻辑的严谨推理能力。
    类比人类思维:凭直觉快速判断,靠逻辑理性思考,也是当下大模型智能体的核心发展方向。
    符号主义、亚符号主义与神经符号混合主义的知识表示范式

1.3.4 按协作方式分类

  1. 单智能体:独立完成任务,无需与其他智能体协作;实现简单、调试方便,适合边界清晰的独立场景。
    示例: 个人语音助手
  2. 多智能体:多个智能体通过协作 / 竞争共同完成复杂任务;能应对大规模分布式场景,容错性强,是解决复杂系统问题的关键范式。
    示例: 交通信号协同控制、多机器人协作。

1.3.5 按自主分类

  1. 自主智能体
    独立完成全流程决策,无需持续人工干预;可自主感知环境、规划行动并应对变化,适合高无人化场景。
    示例: 火星探测车
  2. 半自主智能体
    需部分依赖人类输入或关键节点确认;AI 提供方案与建议,人类负责决策把关,常见于医疗、金融等高风险辅助场景。
    示例: 医疗诊断AI(医疗辅助决策)
  3. 从属智能体
    完全受控于用户或其他系统,仅执行预设指令;无独立目标,以响应外部请求为核心,
    示例: 语音助手(Siri执行用户指令)

2 智能体的构成与运行原理

2.1 任务环境定义

2.1.1 PEAS 模型

PEAS 是描述智能体任务环境的核心框架,四个字母分别对应:

  • Performance(性能度量):衡量任务完成好坏的标准,比如旅行助手的 “预订成功率”“用户满意度”“行程规划合理性”
  • Environment(环境):智能体所处的外部世界,比如旅行助手要面对的航班系统、酒店平台、天气数据、用户需求变化
  • Actuators(执行器):智能体用来改变环境的工具,比如调用预订接口、发送行程通知、修改订单信息
  • Sensors(传感器):智能体用来感知环境的方式,比如读取用户输入、查询 API 数据、接收预订平台的反馈

示例: 智能旅行助手的 PEAS 描述

维度 描述
Performance(性能度量) 在预算和时间内,最大化用户满意度与行程合理性
Environment(环境) 航旅预定网站、地图服务、天气预报API等网络服务
Actuators(执行器) 调用API的函数、向用户界面生成和显示格式化文本
Sensors(传感器) 解析API返回的数据(如JSON、HTML)、读取用户输入的自然语言

2.2 智能体的运行机制

明确智能体依托 PEAS 模型适配差异化任务环境、适配各类环境特性后,想要落地自主交互、完成目标决策,就需要一套标准化、可闭环的底层运行流程,这套支撑智能体自主运转、联动环境交互的核心底层运行机制,就是智能体循环(Agent Loop)

智能体循环:就是智能体和外界持续交互、一步步推进任务的核心运行闭环,全程不断重复运转,直到完成目标。
智能体与环境交互的基本循环

  1. 感知阶段
    作为循环起始,依靠各类感知渠道收集环境信息,接收用户指令、环境变动、上一轮行动带来的反馈数据,掌握当下整体现状。
  2. 思考阶段
    智能体核心决策环节,由大模型完成内部推理
    • 规划:结合现有信息与自身记忆,梳理任务方向,把复杂大目标拆分成简单可执行的小任务,调整行动方案
    • 工具选择:依照制定好的计划,匹配最合适的执行工具,确定调用方式与相关参数
  3. 行动阶段
    依据思考得出的决策,通过执行器执行具体操作,调用对应工具作用于外部环境,主动改变环境现有状态。

第二轮循环
行动改变环境后,环境自动生成全新状态与观测结果,再次传回智能体进入新一轮感知,形成感知 — 思考 — 行动 完整循环。
智能体依靠反复运行这套循环,持续调整策略、逐步推进流程,最终平稳完成既定任务目标,才结束该智能体循环。

2.3 智能体的感知与行动

为了让 LLM 能稳定、可控地驱动这套 “感知 - 思考 - 行动” 闭环,我们需要一套明确的交互协议来规范它与外部环境的信息交换。
这套协议的核心,是对智能体每一步输出进行结构化定义,让 LLM 的推理过程和行动指令变得可被机器解析,也让环境反馈能被 LLM 理解。它主要由三部分构成,共同支撑起循环的运转:

  • Thought(思考):智能体的决策过程快照,用自然语言清晰阐述当前情境分析、上一步反馈复盘、问题分解与下一步规划,相当于把 “脑内思考过程” 外化呈现。
  • Action(行动):基于思考得出的具体操作指令,通常以标准化函数调用格式表示,比如调用天气查询、搜索引擎等工具,是对外部环境的可执行指令。
# 一个正在规划旅行的智能体可能会生成如下格式化的输出
Thought: 用户想知道北京的天气。我需要调用天气查询工具。
Action: get_weather("北京")		# 外部解析器会捕捉到该指令,并调用get_weather函数
  • Observation(观察):环境对行动的反馈结果,会被感知系统从原始机器数据(如 JSON)处理成简洁自然语言文本,作为下一轮循环的输入。
get_weather:  {
  "city": "北京",
  "weather": "晴",
  "temperature": 25,
  "wind": "微风",
  "unit": "摄氏度"
}	# get_weather的输出内容

Observation: 北京当前天气为晴,气温25摄氏度,微风。		# 感知系统处理后的内容

通过这个由 Thought、Action、Observation 构成的严谨循环,LLM 智能体得以将内部的语言推理能力,与外部环境的真实信息和工具操作能力有效地结合起来。

2.4 智能体核心功能

AI 智能体是可感知外界、自主行动并达成目标的智能系统,具备六大核心能力:

  1. 感知功能
    • 环境感知:借助摄像头、麦克风、雷达及各类传感装置,全方位捕捉外部环境动态变化,实时获取场景、距离、状态等各类实景信息。
    • 信息提取与理解:对采集到的海量原始数据进行清洗整合,剔除无效冗余信息,深度解析数据内涵,精准读懂场景信息与用户下达的实际指令。
  2. 决策功能
    • 基于规则的决策:严格遵循人工预先编写的逻辑条例与业务流程,依照固定模式快速做出对应判断,输出规范统一的处理结果。
    • 基于学习的决策:深度挖掘海量行业数据与用户行为数据,自主总结场景运行规律与用户行为偏好,脱离死板规则实现智能化自主决断。
    • 基于优化的决策:结合场景实际需求运用智能优化算法,多维度对比各类可行执行方案,权衡时间、成本、效率选出综合最优决策。
  3. 行动功能
    • 物理行动:精准联动工业机械臂、无人机、自动驾驶设备等实体硬件,下达操控指令,完成搬运、巡检、行驶、组装等各类实体作业。
    • 信息交互行动:依托网络接口与各类应用系统建立连接,开展线上消息传递、指令下发、结果反馈,完成数字化业务对接与日常对话沟通。
  4. 学习功能
    • 监督学习:利用已做好分类标注的标准数据集开展模型训练,精准掌握事物特征,熟练完成图像识别、内容判别、趋势预测等定向任务。
    • 无监督学习:无需依靠人工标注样本,自主探索海量原始数据内部联系,自动完成数据聚类划分,挖掘潜藏在数据中的隐藏规律与特征。
    • 强化学习:持续与真实环境开展交互试探,依据环境给出的奖励与惩罚反馈不断复盘调整行为,循序渐进优化策略,提升综合任务完成能力。
  5. 交互功能
    • 人机交互:兼容语音、文字、图形界面等多种沟通形式,贴合人类交流习惯顺畅对话,快速响应日常咨询、事务办理、办公协助等各类需求。
    • 智能体间交互:同系统内多个智能体可自由互通信息、共享资源数据,合理划分工作任务、协调运行节奏,协同攻克单一智能体无法完成的复杂任务。
  6. 自适应功能
    • 环境自适应:面对环境局势、外界条件、运行状态发生突发变动时,无需人工重新设定,自动调整运行逻辑与执行方案,快速适配全新运行场景。
    • 用户自适应:长期记录并分析用户使用习惯、消费倾向与功能偏好,动态更新服务模式与推荐内容,持续优化输出结果,适配不同用户个性化使用需求。

3 动手体验, 制作一个智能体

目标:构建一个能处理分步任务的智能旅行助手。需要解决的用户任务定义为:“你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。” 要完成这个任务,智能体必须展现出清晰的逻辑规划能力。它需要先调用天气查询工具,并将获得的观察结果作为下一步的依据。在下一轮循环中,它再调用景点推荐工具,从而得出最终建议。

3.1 准备工作

想要在 Python 程序调用网络接口(通过wttr.in查询天气)与大模型服务,可借助三款常用工具库:requests用于发送网络请求、访问通用网络 API;tavily-python是 AI 搜索专用客户端,可调取实时全网搜索数据;openai为官方 SDK,专门对接 GPT 系列大模型。使用前需执行对应命令完成库的安装配置。环境配置

  • 需要配置
  1. 获取大模型的API_KEY
  2. 获取tavily的API
# python 版本 > 3.10
# 创建虚拟环境
# 1. 进入项目目录
cd "hello-agents"
# 2. 创建虚拟环境
python -m venv venv
# 3. 激活虚拟环境
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate

# 安装依赖包
pip install requests tavily-python openai

3.1.1 LLM的提示词

想要顺利调用真实大语言模型搭建智能体,核心在于提示工程。通过定制专属指令模板,明确设定大模型的身份角色、可用工具,以及思考与行动的标准输出格式,将这套完整规则作为**系统提示词(system_prompt)**传入大模型,以此规范智能体整体运行逻辑。

# 系统提示词
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[最终答案] 格式结束

# 正确示例
Thought: 用户需要北京天气,先调用天气工具
Action: get_weather(city="北京")

Thought: 已拿到天气,调用景点推荐工具
Action: get_attraction(city="北京",weather="晴")

Thought: 信息齐全,整理答案结束对话
Action: Finish[北京今日晴天,适合前往故宫游玩...]

请开始吧!
"""

3.1.2 工具1: 查询真实天气

wttr.in 是一个免费的天气 API 服务,支持全球城市查询。
通过 wttr.in 来创建一个查询真是天气的工具
wttr.in返回结果: json格式
wttr.in返回结果: 网页格式
查询天气

# 工具1: 查询真实天气
import requests
def get_weather(city: str) -> str:
    """
    通过调用 wttr.in API 查询真实的天气信息
    """
    # wttr.in 是一个免费的天气 API 服务,支持全球城市查询
    # API端点, 我们请求JSON格式的数据
    url = f"https://wttr.in/{city}?format=j1"
    # print("get_weather city: ", city)
    try:
        # 发起网络请求
        response = requests.get(url)
        print(f"get_weather response: {response}")
        # 检查响应码: 200(成功)
        response.raise_for_status()
        # 解析返回的JSON数据 | 把 API 返回的 JSON 格式数据,转换成 Python 里的字典(dict)对象
        data = response.json()
        # print(f"get_weather data: {data}")
        # 提取当前天气状况
        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}"
    # get_weather 中的data数据
# {
#     'current_condition':          # 当前实时天气(重点)
#         [
#             {
#                 'FeelsLikeC': '27',                # 体感温度(摄氏度)
#                 'FeelsLikeF': '81',                # 体感温度(华氏度)
#                 'cloudcover': '0',                 # 云量覆盖率(百分比)
#                 'humidity': '35',                   # 空气湿度(百分比)
#                 'observation_time': '11:11 AM',    # 气象数据观测时间
#                 'precipInches': '0.0',             # 降雨量(英寸)
#                 'precipMM': '0.0',                 # 降雨量(毫米)
#                 'pressure': '1009',                # 大气压强(百帕)
#                 'pressureInches': '30',            # 大气压强(英寸汞柱)
#                 'temp_C': '28',                    # 实时气温(摄氏度)
#                 'temp_F': '83',                    # 实时气温(华氏度)
#                 'uvIndex': '0',                    # 紫外线指数
#                 'visibility': '10',                # 能见度(公里)
#                 'visibilityMiles': '6',            # 能见度(英里)
#                 'weatherCode': '116',              # 天气状况数字编码
#                 'weatherDesc': [{'value': 'Partly Cloudy '}],  # 天气状况英文描述
#                 'weatherIconUrl': [{'value': 'https://cdn.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png'}],  # 天气图标链接
#                 'winddir16Point': 'SSW',           # 风向16方位缩写
#                 'winddirDegree': '198',            # 风向角度
#                 'windspeedKmph': '18',             # 风速(千米/小时)
#                 'windspeedMiles': '11'             # 风速(英里/小时)
#             }
#         ],
#     'nearest_area': [{...}],         # 城市地区信息
#     'request': [{...}],             # 请求信息
#     'weather': [{...},{...},{...}]        # 未来3天天气预报
#
# }

3.1.3 工具2:搜索并推荐旅游景点

定义一个依据Tavily 通过提供的城市和天气状况, 在互联网上搜索合适的景点:

# 工具2: 搜索并推荐旅游景点
import os
from tavily import TavilyClient
def get_attraction(city: str, weather: str) -> str:
    """ 根据城市和天气, 使用Tavily Search API搜索并返回优化后的景点推荐 """
    # 1. 从环境变量中读取API秘钥
    api_key = os.environ.get("TAVILY_API_KEY")	# 要配置自己的环境变量
    if not api_key:
        return "错误: 未配置TAVILY_API_KEY环境变量。"

    # 2. 初始化Tavily客户端
    tavily = TavilyClient(api_key=api_key)

    # 3. 构造一个精确的查询
    query = f"'f{city}' 在'{weather}'天气下值得去的旅游景点推荐及理由"

    try:
        # 4. 调用API, include_answer=True会返回一个综合整理后的回答
        # search_depth: 搜索深度, basic=轻量模式, 速度快,适合普通场景 | advanced = 搜索更深入但耗时更长
        response = tavily.search(query=query, search_depth="basic", include_answer=True)

        # 5. Tavily返回结果非常干净, 可直接使用
        # response['answer'] 是一个基于所有搜索结果的总结性回答.
        if response.get("answer"):
            return response["answer"]

        # 如果没有综合性回答, 这格式化原始结果
        formatted_results = []
        for result in response.get("results", []):
            formatted_results.append(f"- {result['title']}: {result['content']}")

        if not formatted_results:
            return "抱歉, 没有找到相关的旅游景点推荐。"

        return "根据搜索, 为你找到以下信息: \n" + "\n".join(formatted_results)
    except Exception as e:
        return f"错误: 执行Tavily搜索时出现问题 - {e}"

# 将所有工具函数放入一个字典, 方便后续调用
available_tools = {
    "get_weather": get_weather,
    "get_attraction": get_attraction,
}

3.2 接入大语言模型

当前,许多 LLM 服务提供商(包括 OpenAI、Azure、DeepSeek以及众多开源模型服务框架如 Ollama、vLLM 等)都遵循了与 OpenAI API 相似的接口规范。这种标准化为开发者带来了极大的便利。智能体的自主决策能力来源于 LLM。我们将实现一个通用的客户端 OpenAICompatibleClient,它可以连接到任何兼容 OpenAI 接口规范的 LLM 服务。

from openai import OpenAI

class OpenAICompatibleClient:
    """
    一个用于调用任何兼容OpenAI接口的LLM服务的客户端。
    """
    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:
        """调用LLM API来生成回应。"""
        print("正在调用大语言模型...")
        try:
            messages = [
                {'role': 'system', 'content': system_prompt},	# system_message
                {'role': 'user', 'content': prompt}				# human_message
            ]
            response = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                stream=False		# 不用流式输出, 一次展示所有结果
            )
            answer = response.choices[0].message.content
            print("大语言模型响应成功。")
            return answer
        except Exception as e:
            print(f"调用LLM API时发生错误: {e}")
            return "错误:调用语言模型服务时出错。"

  • LLM调用的返回结构说明

# response = self.client.chat.completions.create(
#                 model=self.model,
#                 messages=messages,
#                 stream=False
#             )
# response: ChatCompletion(
#     id='chatcmpl-c8592ddb-c16c-9f40-9e5d-838ac572a5e8',  # 本次对话请求唯一标识ID
#     choices=[  # 模型返回的回答结果列表,多条候选回复
#         Choice(
#             finish_reason='stop',  # 结束原因:正常完整生成完毕
#             index=0,  # 当前这条回复在候选列表里的索引序号
#             logprobs=None,  # 词语概率对数信息,此处未开启返回
#             message=ChatCompletionMessage(  # 模型输出的消息主体对象
#                 content='Thought: 用户需要查询北京天气并推荐景点,首先需要获取实时天气信息作为前提条件\n\nAction: get_weather(city="北京")',  # 模型思考+工具调用指令正文
#                 refusal=None,  # 拒绝回复内容,无拒绝则为空
#                 role='assistant',  # 消息角色:assistant助手角色
#                 annotations=None,  # 附加标注信息,暂无
#                 audio=None,  # 语音音频相关数据,暂无
#                 function_call=None,  # 传统函数调用字段,未使用
#                 tool_calls=None,  # 工具调用结构化字段,未启用
#                 reasoning_content='用户请求我查询北京的天气,然后根据天气推荐旅游景点。我需要按照以下步骤进行:\n\n1. 首先调用get_weather工具查询北京天气\n2. 然后根据天气结果调用get_attraction工具获取推荐景点\n3. 最后整理信息结束对话\n\n让我开始第一步,调用天气查询工具。'  # 模型内部深度思考过程文本
#             ),
#         )
#     ],
#     created=1782055651,  # 接口响应生成时间戳
#     model='qwen3.5-flash',  # 本次调用使用的大模型名称
#     object='chat.completion',  # 接口返回数据类型标识
#     moderation=None,  # 内容审核相关结果,暂无
#     service_tier=None,  # 服务调用档位,暂无配置
#     system_fingerprint=None,  # 模型版本指纹标识
#     usage=CompletionUsage(  # 本次对话消耗token统计对象
#         completion_tokens=97,  # 模型生成回复所用token数量
#         prompt_tokens=313,  # 输入提示词所用token数量
#         total_tokens=410,  # 本次请求总共消耗token数量
#         completion_tokens_details=CompletionTokensDetails(  # 生成端token细分统计
#             accepted_prediction_tokens=None,  # 预测采纳token,无数据
#             audio_tokens=None,  # 音频类token,无数据
#             reasoning_tokens=63,  # 模型思考内容占用token数
#             rejected_prediction_tokens=None  # 废弃预测token,无数据
#         ),
#         prompt_tokens_details=PromptTokensDetails(  # 输入端token细分统计
#             audio_tokens=None,  # 输入音频token,无数据
#             cached_tokens=None,  # 缓存命中token数量,无数据
#             text_tokens=313  # 纯文本输入占用token数
#         )
#     )
# )

3.3 执行主循环

将模拟agent的内部决策过程, 整合所有组件, 通过格式化后的 Prompt 驱动 LLM进行决策

import re

# --- 1. 配置LLM客户端 ---
# 请根据您使用的服务,将这里替换成对应的凭证和地址
# API_KEY = "YOUR_API_KEY"
# BASE_URL = "YOUR_BASE_URL"
# MODEL_ID = "YOUR_MODEL_ID"
API_KEY = os.environ.get("DASHSCOPE_API_KEY")
BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1"
MODEL_ID = "qwen3.5-flash"			# 模型名称
# print(f"API_KEY: {API_KEY}")			# 查询是否充环境变量中多去到API_KEY,
#  若是新增加的环境变量, 关闭所有的Pycharm项目后重新启动, 即可加载初API_KEY

llm = OpenAICompatibleClient(
    model=MODEL_ID,
    api_key=API_KEY,
    base_url=BASE_URL
)

# --- 2. 初始化 ---
user_prompt = "你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。"
prompt_history = [f"用户请求: {user_prompt}"]		# 消息列表

print(f"用户输入: {user_prompt}\n" + "="*40)

# --- 3. 运行主循环 ---
for i in range(5): # 设置最大循环次数
    print(f"--- 循环 {i+1} ---\n")
    
    # 3.1. 构建Prompt
    full_prompt = "\n".join(prompt_history)
    
    # 3.2. 调用LLM进行思考
    llm_output = llm.generate(full_prompt, system_prompt=AGENT_SYSTEM_PROMPT)
    # 模型可能会输出多余的Thought-Action,需要截断
    # 强制约束大模型一次只输出一次思考 + 一次行动,截断多余多轮思考,保证智能体按顺序串行执行工具。
    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 对")
    print(f"模型输出:\n{llm_output}\n")
    prompt_history.append(llm_output)
    
    # 3.3. 解析并执行行动
    action_match = re.search(r"Action: (.*)", llm_output, re.DOTALL)
    if not action_match:
        observation = "错误: 未能解析到 Action 字段。请确保你的回复严格遵循 'Thought: ... Action: ...' 的格式。"
        observation_str = f"Observation: {observation}"
        print(f"{observation_str}\n" + "="*40)
        prompt_history.append(observation_str)
        continue
    action_str = action_match.group(1).strip()

    if action_str.startswith("Finish"):
        final_answer = re.match(r"Finish\[(.*)\]", action_str).group(1)
        print(f"任务完成,最终答案: {final_answer}")
        break
    
    tool_name = re.search(r"(\w+)\(", action_str).group(1)
    args_str = re.search(r"\((.*)\)", action_str).group(1)
    kwargs = dict(re.findall(r'(\w+)="([^"]*)"', args_str))

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

    # 3.4. 记录观察结果
    observation_str = f"Observation: {observation}"
    print(f"{observation_str}\n" + "="*40)
    prompt_history.append(observation_str)

代码解释

# 正则整体作用:从大模型输出文本里,精准截取【单轮完整思考(Thought)+动作(Action)】片段
# 规则:匹配从 Thought: 开始,到下一轮标记出现前为止的内容,实现单轮分割
match = re.search(
    r'(Thought:.*?Action:.*?)'          # 主体匹配区域
    r'(?=\n\s*(?:Thought:|Action:|Observation:)|\Z)',  # 后置边界断言(停止条件)
    llm_output,
    re.DOTALL                            # 单行模式开关:让 . 能匹配换行符
)

# 1. 主体捕获组 (Thought:.*?Action:.*?)
    # Thought::精准匹配思考语句开头固定标识
    # .*?:非贪婪匹配,尽可能少匹配字符,避免跨轮内容粘连
    # Action::匹配动作调用开头固定标识
    # 整体含义:抓取 从思考开头 → 动作结尾 的一整轮思维 + 调用内容
# 2. 后置零宽断言 (?=\n\s*(?:Thought:|Action:|Observation:)|\Z)
    # (?=...):正向先行断言
    # 特点:只判定后面是什么内容,不占用、不捕获、不吞掉字符,只当作截断边界
    # 内部拆解:
    # \n:匹配换行符,区分不同轮次
    # \s*:匹配任意数量空格 / 缩进,兼容排版空格
    # (?:Thought:|Action:|Observation:)
        # (?:):非捕获分组,只用来多选匹配,不单独存结果
        # 含义:遇到下一轮(Thought:|Action:|Observation)中任意一种开头标记就停止截取
    # |\Z:或者匹配文本最末尾,适配最后一轮没有下一条内容的场景
# 3. 修饰符 re.DOTALL
    # 正常 . 不能匹配换行
    # 加上此参数:. 可以跨行匹配,解决思考 / 动作分行书写的场景

# # 正则:匹配以 Action: 开头的整行/整段指令内容
action_match = re.search(r"Action: (.*)", llm_output, re.DOTALL)

示例: 
llm_output: 'Thought: 用户需要查询北京天气并推荐景点,首先需要获取实时天气信息作为前提条件\n\nAction: get_weather(city="北京")'
action_match: Action: get_weather(city="北京")
action_match.group(1): 'get_weather(city="北京")'
# Action:
    # 精准匹配固定前缀文本 Action:,必须严格一致
# 空格
    # 匹配冒号后面紧跟的空格
# (.*)
    # () 捕获分组,用来取出后面所有内容
    # . 匹配任意字符
    # * 匹配零个或多个任意字符
    # 作用:抓取Action:后面全部剩余内容
# re.DOTALL
    # 让.可以匹配换行符,支持Action:内容跨行书写
    # action_str = get_attraction(city="北京", weather="晴")
    tool_name = re.search(r"(\w+)\(", action_str).group(1)  # tool_name: get_attraction
    # (\w+)\(  : \w+ 字母数字下划线,匹配函数名;\( 转义左括号
    args_str = re.search(r"\((.*)\)", action_str).group(1)  # args_str: city="北京", weather="晴"
    # \( 左括号,\) 右括号,.* 括号内所有内容
    kwargs = dict(re.findall(r'(\w+)="([^"]*)"', args_str)) # kwargs: {'city': '北京', 'weather': '晴'}
    # (\w+):参数名 | =:等于号 | ":双引号 | [^"]*:除双引号外所有字符,精准截取引号内值,不越界
		
		# 执行对应工具函数,并传入解析好的关键字参数,拿到执行结果赋值给观测值
		bservation = available_tools[tool_name](**kwargs)
		# (** kwargs) 把解析得到的参数字典解包传参
		# kwargs = {"city":"北京", "weather":"晴"}
		# 等价于:
		# get_weather(city="北京", weather="晴")

3.4 运行案例分析

以下输出完整地展示了一个成功的智能体执行流程。通过对这个三轮循环的分析,我们可以清晰地看到智能体解决问题的核心能力。
这个简单的旅行助手案例,集中演示了基于Thought-Action-Observation范式的智能体所具备的四项基本能力:任务分解、工具调用、上下文理解和结果合成。正是通过这个循环的不断迭代,智能体才得以将一个模糊的用户意图,转化为一系列具体、可执行的步骤,并最终达成目标。

用户输入: 你好, 请帮我查询一下今天北京的天气, 然后根据天气推荐一个合适的旅游景点。
========================================
--- 循环 1 ---

正在调用大语言模型...
大语言模型响应成功.
模型输出:
Thought: 用户需要查询北京今天的天气,并据此推荐旅游景点。我首先需要获取北京的实时天气信息。
Action: get_weather(city="北京")

Observation: 北京当前天气: Clear , 气温22摄氏度
========================================
--- 循环 2 ---

正在调用大语言模型...
大语言模型响应成功.
模型输出:
Thought: 已获取到北京的天气信息(晴天,22摄氏度),现在需要根据这个天气信息推荐适合的旅游景点。
Action: get_attraction(city="北京",weather="晴")

Observation: On sunny days in Beijing, visit the Forbidden City, the Great Wall at Badaling, and the Temple of Heaven for great views and historical significance.
========================================
--- 循环 3 ---

正在调用大语言模型...
大语言模型响应成功.
模型输出:
Thought: 已获取天气信息并调用景点推荐工具,现在整合信息生成最终答案。
Action: Finish[今日北京晴朗,气温适宜22℃。推荐前往:1.故宫(历史建筑与开阔庭院适合晴天游览);2.八达岭长城(视野清晰利于欣赏壮丽景色);3.天坛(园林景观在晴天时更显葱郁)]

任务完成: 最终答案: 今日北京晴朗,气温适宜22℃。推荐前往:1.故宫(历史建筑与开阔庭院适合晴天游览);2.八达岭长城(视野清晰利于欣赏壮丽景色);3.天坛(园林景观在晴天时更显葱郁)

prompt_history最终结果

========================消息列表==================================
对话历史轮数: 6

===== 第1轮 =====
用户请求: 你好, 请帮我查询一下今天北京的天气, 然后根据天气推荐一个合适的旅游景点。

===== 第2轮 =====
Thought: 用户需要查询北京今天的天气,并据此推荐旅游景点。我首先需要获取北京的实时天气信息。
Action: get_weather(city="北京")

===== 第3轮 =====
Observation: 北京当前天气: Clear , 气温22摄氏度

===== 第4轮 =====
Thought: 已获取到北京的天气信息(晴天,22摄氏度),现在需要根据这个天气信息推荐适合的旅游景点。
Action: get_attraction(city="北京",weather="晴")

===== 第5轮 =====
Observation: On sunny days in Beijing, visit the Forbidden City, the Great Wall at Badaling, and the Temple of Heaven for great views and historical significance.

===== 第6轮 =====
Thought: 已获取天气信息并调用景点推荐工具,现在整合信息生成最终答案。
Action: Finish[今日北京晴朗,气温适宜22℃。推荐前往:1.故宫(历史建筑与开阔庭院适合晴天游览);2.八达岭长城(视野清晰利于欣赏壮丽景色);3.天坛(园林景观在晴天时更显葱郁)]
========================消息列表==================================

4 智能体应用的协作模式

随着智能体应用愈发普及,人类更多转为使用者与协作参与者。依据智能体自主性与任务定位,协作模式分为两类:一是充当实用工具,深度融入日常工作流程辅助办公;二是成为独立协作主体,和其他智能体相互配合,共同攻克各类复杂任务。

4.1 作为开发者工具的智能体

开发者工具模式下智能体深度融入开发流程,定位为辅助工具而非替代人力,自动承接重复繁琐工作,让开发者聚焦核心创意研发,有效提升开发效率与项目质量。当下主流 AI 编程工具各有特色:

  • GitHub Copilot 嵌入主流编辑器,主打实时代码补全,兼具对话编程能力;
  • Claude Code 依托终端运行,可通读项目代码库,支持全流程开发与自动化部署场景;
  • Trae 体量轻便响应迅速,擅长代码智能生成与重构,适配快速迭代开发;
  • Cursor 原生 AI 代码编辑器,深度理解全局项目上下文,深耕代码调试与整体重构。

整体行业趋势清晰可见,AI 全面渗透软件开发全流程,以人机协同新模式,持续革新传统开发方式。

4.2 作为自主协作者的智能体

自主协作者模式,区别于工具式辅助,人类仅下达高层整体目标,无需全程分步指导。智能体可独立完成规划、推理、执行与复盘,人机关系从命令-执行转变为目标-委托,智能体主动向着任务目标自主推进。

目前诞生众多成熟智能体开发框架,例如:CrewAI、AutoGen、MetaGPT、LangGraph 等,优秀框架主流架构分为三类:

  1. 单智能体自主循环
    依托单一智能体搭建"思考-规划-执行-反思"闭环,依靠自我迭代完成开放式复杂任务,是早期自主智能体主流形式。
  2. 多智能体团队协作
    模拟人类团队分工配合完成任务,既可以设定不同角色对话协同,也能搭建标准化工作流程组建虚拟团队,同时支持自由灵活的智能体交互形式。
    例:
    • 组织化工作流:以 MetaGPT、CrewAI 为代表,搭建分工清晰的虚拟团队体系。为每个智能体划定专属职责与标准作业流程,依托层级统筹、顺序推进的方式协同配合,可高效产出完整项目代码、专业研究报告等高质量复杂成果。
    • 灵活交互模式:以 AutoGen、AgentScope 为代表,支持自由多变的对话交互形式,开发者可自主搭建搭建智能体之间多元复杂的通信协作网络,适配多样化协作场景。
  3. 高级控制流架构
    诸如 LangGraph 等框架,以状态图形式搭建底层运行逻辑,灵活实现流程循环、分支跳转、任务回溯与人机介入,大幅提升智能体运行稳定性与流程可控性。

各类架构不断完善,推动自主协作智能体落地实用,能够高效处理各类真实场景复杂任务。


4.3 Workflow 和 Agent 的差异

简单理解: Workflow 是让 AI 按部就班地执行指令,而 Agent 则是赋予 AI 自由度去自主达成目标。
 Workflow 和 Agent 的差异

  • **WorkFlow(工作流)**属于静态自动化范式,提前固定好全部执行步骤与判断条件,流程顺序、分支规则均预先写死,仅能机械按既定流程执行,灵活性较差, 稳定性强,每个输入都可以得到固定的输出。

    • 例:企业新员工入职审批工作流
      整套流程、审核门槛、流转节点全部提前录入系统,判定规则固定,流程如下:
      1. 人事部门提交完整新员工入职资料,发起入职审批流程,流程正式触发;
      2. 系统判定员工定岗薪资:若月度薪资≤8000元,仅直属部门负责人单人审核即可;
      3. 若月度薪资>8000元,执行多级流转:先由部门负责人审核岗位匹配度,审核通过后自动流转至人力资源总监复核薪资职级,复核无误后,最终交由公司总经理终审;
      4. 任意节点审核驳回,流程直接退回人事部修改资料,重新发起审批;
      5. 全部审批节点通过后,系统自动办理工号开立、办公设备登记、考勤账户开通,同步发送入职通知邮件给员工本人。
  • Agent则是以目标为导向的自主系统,依靠大模型充当决策核心,无需固定流程模板。可自主拆分任务、按需调用工具,结合实时信息动态推理判断,依据不同场景灵活调整执行方案,摆脱死板规则限制,自适应完成多样化任务。

    • 例:上一章节写的智能旅行助手
      用户指令:“你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。” 它的处理过程充分展现了其自主性
      1. 规划与工具调用: Agent 首先会把任务拆解为两个步骤:① 查询天气;② 基于天气推荐景点。随即,它会自主选择并调用“天气查询 API”,并将“北京”作为参数传入。

      2. 推理与决策: 假设 API 返回结果为“晴朗,微风”。Agent 的 LLM 大脑会基于这个信息进行推理:“晴天适合户外活动”。接着,它会根据这个判断,在它的知识库或通过搜索引擎这个工具中,筛选出北京的户外景点,如故宫、颐和园、天坛公园等。

      3. 生成结果: 最后,Agent 会综合信息,给出一个完整的、人性化的回答:“今天北京天气晴朗,微风,非常适合户外游玩。为您推荐前往【颐和园】,您可以在昆明湖上泛舟,欣赏美丽的皇家园林景色。”


参考内容

github的hello-agents

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐