AI 教程 · 2026年8月7日 - AI 智能体自动化工作流实战

AI 智能体自动化工作流实战:构建你的第一个 AI Agent

2026 年,AI 智能体(AI Agent)已经从概念验证走向了主流生产环境。本文带你从零开始,构建一个真正能用的 AI Agent 工作流。


背景

什么是 AI Agent?

AI Agent(智能体)是一个能够自主感知环境、做出决策并采取行动的人工智能系统。与传统的聊天机器人不同,AI Agent 不仅能够”说话”,还能”做事”——调用 API、搜索网页、读写文件、执行代码,甚至管理工作流中的多个子任务。

为什么 Agent 很重要?

2026 年被称为”Agentic AI 元年”。各大模型厂商纷纷推出了原生支持工具调用(Function Calling)和 Agent 框架的 API。AI Agent 不再只是实验室里的玩具,而是成为了企业自动化、个人生产力提升的核心工具。

关键趋势:

  • 大语言模型(LLM)从”对话引擎”升级为”推理引擎”和”行动引擎”
  • 工具调用(Function Calling)成为模型标配能力
  • 多智能体协作系统开始落地
  • 记忆管理和上下文窗口优化成为核心挑战

第一步:理解 AI Agent 的核心概念

一个标准的 AI Agent 由四个核心组件构成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌─────────────────────────────────────────┐
│ AI Agent │
│ ┌─────────┐ ┌─────────┐ │
│ │ LLM │ │ Tools │ │
│ │ (大脑) │ │ (工具) │ │
│ └────┬────┘ └────┬────┘ │
│ │ │ │
│ ┌────▼────────────▼────┐ │
│ │ Memory (记忆) │ │
│ └──────────────────────┘ │
│ ┌──────────────────────┐ │
│ │ Planning (规划) │ │
│ └──────────────────────┘ │
└─────────────────────────────────────────┘

常见模式

模式 说明 适用场景
ReAct 推理(Reasoning)+ 行动(Acting)交替循环 复杂推理任务
Function Calling 模型主动选择调用预定义函数 API 调用、工具集成
Tool Use 模型使用外部工具扩展能力 搜索、计算、代码执行
Plan-then-Execute 先制定计划,再逐步执行 多步骤工作流

Agent 循环:Perceive → Think → Act → Observe

这是 Agent 最基本的工作循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
收到用户输入


┌──────────┐
│ Perceive │ ← 感知输入 & 上下文
│ (感知) │
└────┬─────┘


┌──────────┐
│ Think │ ← LLM 推理 & 决策
│ (思考) │
└────┬─────┘


┌──────────┐
│ Act │ ← 执行动作(调用工具/回复)
│ (行动) │
└────┬─────┘


┌──────────┐
│ Observe │ ← 观察结果 & 反馈
│ (观察) │
└────┬─────┘

└──→ 循环直到任务完成

第二步:环境准备

系统要求

  • Python 3.10+
  • 一个 OpenAI / Anthropic / 或其他 LLM 提供商的 API Key
  • pip 包管理器

安装依赖

1
2
3
4
5
6
7
# 创建虚拟环境(推荐)
python3 -m venv agent_env
source agent_env/bin/activate # Linux/Mac
# 或 agent_env\Scripts\activate # Windows

# 安装核心依赖
pip install openai anthropic httpx python-dotenv

配置 API Key

创建 .env 文件:

1
2
3
# .env
OPENAI_API_KEY=sk-your-openai-api-key-here
ANTHROPIC_API_KEY=sk-ant-your-anthropic-api-key-here

项目结构

1
2
3
4
5
6
7
8
9
my_first_agent/
├── .env # 环境变量
├── main.py # 主入口
├── agent/
│ ├── __init__.py
│ ├── core.py # Agent 核心逻辑
│ ├── tools.py # 工具定义
│ └── memory.py # 记忆管理
└── requirements.txt # 依赖清单

第三步:构建你的第一个 Agent

让我们从最简单的 Agent 开始——一个能搜索网页并回答问题的智能体。

步骤 1:定义工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# agent/tools.py
import requests
import json
from typing import Any

# 工具函数:网页搜索
def web_search(query: str, max_results: int = 3) -> list[dict]:
"""
使用搜索引擎查询信息。

参数:
query: 搜索关键词
max_results: 最大返回结果数

返回:
搜索结果列表,每项包含 title, url, snippet
"""
# 这里使用一个简单的示例 API,实际使用时替换为你的搜索 API
url = f"https://api.duckduckgo.com/?q={query}&format=json"
try:
response = requests.get(url, timeout=10)
data = response.json()
results = []
for item in data.get("results", [])[:max_results]:
results.append({
"title": item.get("Title", ""),
"url": item.get("FirstURL", ""),
"snippet": item.get("Abstract", "")
})
return results
except Exception as e:
return [{"error": f"搜索失败: {str(e)}"}]

# 工具函数:计算器
def calculator(expression: str) -> float | str:
"""
计算数学表达式。

参数:
expression: 数学表达式字符串,如 "2 + 3 * 4"

返回:
计算结果
"""
try:
# 安全计算:仅允许基本的数学运算
allowed = set("0123456789+-*/()., ")
if not all(c in allowed for c in expression):
return "错误:表达式包含不允许的字符"
result = eval(expression, {"__builtins__": {}}, {})
return result
except Exception as e:
return f"计算错误: {str(e)}"

# 工具注册表
TOOL_REGISTRY = {
"web_search": {
"function": web_search,
"description": "搜索互联网获取最新信息",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词"
},
"max_results": {
"type": "integer",
"description": "最大返回结果数(默认 3)",
"default": 3
}
},
"required": ["query"]
}
},
"calculator": {
"function": calculator,
"description": "计算数学表达式",
"parameters": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "数学表达式"
}
},
"required": ["expression"]
}
}
}

步骤 2:实现 Agent 核心循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# agent/core.py
import json
import os
from openai import OpenAI
from dotenv import load_dotenv
from .tools import TOOL_REGISTRY

load_dotenv()

class SimpleAgent:
"""一个简单的 AI Agent 实现"""

def __init__(self, model: str = "gpt-4o"):
self.client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
self.model = model
self.messages = [] # 对话历史
self.tools = self._build_tools_schema()

def _build_tools_schema(self) -> list[dict]:
"""将工具注册表转换为 OpenAI 工具调用格式"""
tools = []
for name, meta in TOOL_REGISTRY.items():
tools.append({
"type": "function",
"function": {
"name": name,
"description": meta["description"],
"parameters": meta["parameters"]
}
})
return tools

def _execute_tool(self, name: str, arguments: dict) -> str:
"""执行工具调用"""
if name not in TOOL_REGISTRY:
return f"错误:未知工具 '{name}'"
try:
result = TOOL_REGISTRY[name]["function"](**arguments)
return json.dumps(result, ensure_ascii=False)
except Exception as e:
return f"工具执行错误: {str(e)}"

def run(self, user_input: str, max_iterations: int = 5) -> str:
"""
运行 Agent,处理用户输入。

Perceive → Think → Act → Observe 循环
"""
self.messages.append({"role": "user", "content": user_input})

for iteration in range(max_iterations):
print(f"\n[迭代 {iteration + 1}/{max_iterations}]")

# 1. Perceive + Think: 发送给 LLM
response = self.client.chat.completions.create(
model=self.model,
messages=self.messages,
tools=self.tools,
tool_choice="auto"
)

message = response.choices[0].message

# 检查是否需要工具调用
if message.tool_calls:
# 2. Act: 执行工具
self.messages.append(message)
for tool_call in message.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
print(f" → 调用工具: {func_name}({func_args})")

# 3. Observe: 观察结果
result = self._execute_tool(func_name, func_args)
print(f" ← 结果: {result[:100]}...")

self.messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
else:
# 不需要工具调用,直接返回模型回答
final_answer = message.content
self.messages.append({"role": "assistant", "content": final_answer})
return final_answer

# 达到最大迭代次数,返回当前结果
return "Agent 已达到最大迭代次数,请尝试简化问题。"

def reset(self):
"""重置对话历史"""
self.messages = []

步骤 3:主入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# main.py
from agent.core import SimpleAgent

def main():
agent = SimpleAgent()

print("=" * 60)
print(" AI Agent 演示 - 输入 'exit' 退出")
print("=" * 60)

while True:
user_input = input("\n👤 你: ").strip()
if user_input.lower() in ("exit", "quit", "q"):
print("再见!")
break

print("\n🤖 Agent 思考中...")
result = agent.run(user_input)
print(f"\n🤖 Agent: {result}")

if __name__ == "__main__":
main()

运行效果示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ python main.py
============================================================
AI Agent 演示 - 输入 'exit' 退出
============================================================

👤 你: 2026年诺贝尔物理学奖颁给了谁?

🤖 Agent 思考中...

[迭代 1/5]
→ 调用工具: web_search({'query': '2026 Nobel Prize Physics winner'})
← 结果: [{"title": "2026 Nobel Prize in Physics", ...}]...

🤖 Agent: 2026年诺贝尔物理学奖授予了...(详细回答)

第四步:添加工具(Tools)

工具是 Agent 与外部世界交互的桥梁。下面详细介绍如何定义和注册自定义工具。

工具定义规范

每个工具需要三个要素:

  1. 函数实现——实际的 Python 函数
  2. 元数据描述——给 LLM 看的说明
  3. 参数 Schema——描述参数结构

更多工具示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# agent/tools.py(扩展)

# 工具:文件读取器
def read_file_content(filepath: str, max_length: int = 2000) -> str:
"""
读取本地文件内容。

参数:
filepath: 文件路径
max_length: 最大读取字符数

返回:
文件内容
"""
try:
with open(filepath, "r", encoding="utf-8") as f:
content = f.read(max_length)
return content
except Exception as e:
return f"读取文件失败: {str(e)}"

# 工具:获取当前时间
def get_current_time() -> dict:
"""
获取当前日期和时间。

返回:
包含日期、时间、星期几的字典
"""
from datetime import datetime
now = datetime.now()
weekdays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
return {
"date": now.strftime("%Y-%m-%d"),
"time": now.strftime("%H:%M:%S"),
"weekday": weekdays[now.weekday()]
}

# 工具:URL 内容抓取
def fetch_webpage(url: str) -> str:
"""
获取网页的文本内容。

参数:
url: 网页 URL

返回:
网页文本内容
"""
try:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
response = requests.get(url, headers=headers, timeout=15)
response.raise_for_status()
# 简单提取文本(实际项目中可用 BeautifulSoup)
text = response.text[:3000]
return text
except Exception as e:
return f"抓取失败: {str(e)}"

注册工具

将新工具添加到 TOOL_REGISTRY

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 在 TOOL_REGISTRY 中添加新条目
TOOL_REGISTRY["read_file"] = {
"function": read_file_content,
"description": "读取本地文件的内容",
"parameters": {
"type": "object",
"properties": {
"filepath": {
"type": "string",
"description": "文件路径"
},
"max_length": {
"type": "integer",
"description": "最大读取字符数",
"default": 2000
}
},
"required": ["filepath"]
}
}

TOOL_REGISTRY["get_current_time"] = {
"function": get_current_time,
"description": "获取当前日期和时间",
"parameters": {
"type": "object",
"properties": {}
}
}

TOOL_REGISTRY["fetch_webpage"] = {
"function": fetch_webpage,
"description": "获取指定 URL 的网页文本内容",
"parameters": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "网页 URL"
}
},
"required": ["url"]
}
}

工具设计最佳实践

实践 说明
清晰的描述 用中文写清楚工具的功能和适用场景
参数校验 在函数内部做输入校验,防止注入攻击
超时处理 网络请求设置合理的超时时间
错误返回 用结构化错误信息而非抛异常
幂等性 同样的输入应产生同样的输出(如果可以)

第五步:添加记忆(Memory)

记忆是 Agent 持续对话和长期学习的关键。我们实现两个层次的记忆管理。

短期记忆:对话历史管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# agent/memory.py
import json
import os
from datetime import datetime
from typing import Optional

class ConversationMemory:
"""管理对话历史(短期记忆)"""

def __init__(self, max_context_length: int = 4096):
self.messages = []
self.max_context_length = max_context_length # 最大 token 数(近似)
self.current_length = 0

def add_message(self, role: str, content: str):
"""添加消息到对话历史"""
message = {
"role": role,
"content": content,
"timestamp": datetime.now().isoformat()
}
self.messages.append(message)
self.current_length += len(content)
self._prune_context()

def get_context(self) -> list[dict]:
"""获取当前上下文(用于 LLM 调用)"""
return [
{"role": msg["role"], "content": msg["content"]}
for msg in self.messages
]

def _prune_context(self):
"""当上下文超过限制时,裁剪最早的消息"""
while self.current_length > self.max_context_length and len(self.messages) > 1:
removed = self.messages.pop(0)
self.current_length -= len(removed["content"])

def clear(self):
"""清空对话历史"""
self.messages = []
self.current_length = 0

长期记忆:持久化存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# agent/memory.py(续)

class PersistentMemory:
"""持久化记忆(长期记忆)—— 保存到本地文件"""

def __init__(self, storage_path: str = "./agent_memory.json"):
self.storage_path = storage_path
self.memories = self._load()

def _load(self) -> dict:
"""从文件加载记忆"""
if os.path.exists(self.storage_path):
try:
with open(self.storage_path, "r", encoding="utf-8") as f:
return json.load(f)
except (json.JSONDecodeError, IOError):
return {"sessions": [], "knowledge": {}}
return {"sessions": [], "knowledge": {}}

def _save(self):
"""保存记忆到文件"""
with open(self.storage_path, "w", encoding="utf-8") as f:
json.dump(self.memories, f, ensure_ascii=False, indent=2)

def save_session(self, session_id: str, messages: list[dict]):
"""保存一次对话会话"""
session = {
"id": session_id,
"timestamp": datetime.now().isoformat(),
"message_count": len(messages),
"messages": messages[-10:] # 只保存最后 10 条
}
self.memories["sessions"].append(session)
# 最多保留 50 个会话
if len(self.memories["sessions"]) > 50:
self.memories["sessions"] = self.memories["sessions"][-50:]
self._save()

def store_knowledge(self, key: str, value: str):
"""存储知识片段"""
self.memories["knowledge"][key] = {
"value": value,
"updated_at": datetime.now().isoformat()
}
self._save()

def recall(self, key: str) -> Optional[str]:
"""回忆知识片段"""
if key in self.memories["knowledge"]:
return self.memories["knowledge"][key]["value"]
return None

def search_knowledge(self, keyword: str) -> list[dict]:
"""搜索知识库"""
results = []
for key, entry in self.memories["knowledge"].items():
if keyword.lower() in key.lower() or \
keyword.lower() in entry["value"].lower():
results.append({"key": key, "value": entry["value"]})
return results

将记忆集成到 Agent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 在 SimpleAgent 中添加记忆支持

class SimpleAgentWithMemory(SimpleAgent):
"""带记忆的 AI Agent"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.conversation_memory = ConversationMemory()
self.persistent_memory = PersistentMemory()
self.session_id = datetime.now().strftime("%Y%m%d_%H%M%S")

def run(self, user_input: str, max_iterations: int = 5) -> str:
# 使用 conversation_memory 替代 self.messages
self.conversation_memory.add_message("user", user_input)

for iteration in range(max_iterations):
response = self.client.chat.completions.create(
model=self.model,
messages=self.conversation_memory.get_context(),
tools=self.tools,
tool_choice="auto"
)

message = response.choices[0].message

if message.tool_calls:
self.conversation_memory.add_message("assistant",
json.dumps([{"name": tc.function.name, "args": tc.function.arguments}
for tc in message.tool_calls]))
for tool_call in message.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
result = self._execute_tool(func_name, func_args)
self.conversation_memory.add_message("tool", result)
else:
final_answer = message.content
self.conversation_memory.add_message("assistant", final_answer)
# 保存会话
self.persistent_memory.save_session(
self.session_id,
self.conversation_memory.messages
)
return final_answer

return "Agent 已达到最大迭代次数。"

第六步:构建工作流

真正的 AI Agent 需要处理复杂的多步骤工作流。下面我们构建一个支持条件分支、错误处理和重试机制的工作流引擎。

工作流引擎

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# agent/workflow.py
import time
import json
from typing import Callable, Any
from enum import Enum

class WorkflowStatus(Enum):
PENDING = "pending"
RUNNING = "running"
SUCCESS = "success"
FAILED = "failed"
SKIPPED = "skipped"

class WorkflowStep:
"""工作流中的一个步骤"""

def __init__(self, name: str, action: Callable,
depends_on: list[str] = None,
max_retries: int = 3,
timeout: int = 30):
self.name = name
self.action = action
self.depends_on = depends_on or []
self.max_retries = max_retries
self.timeout = timeout
self.status = WorkflowStatus.PENDING
self.result = None
self.error = None
self.retry_count = 0

class WorkflowEngine:
"""多步骤工作流引擎,支持条件分支和错误处理"""

def __init__(self, agent: Any):
self.agent = agent
self.steps: dict[str, WorkflowStep] = {}
self.context: dict = {} # 工作流上下文,用于步骤间共享数据

def add_step(self, step: WorkflowStep):
"""添加一个工作流步骤"""
self.steps[step.name] = step

def add_conditional_step(self, name: str,
condition: Callable[[dict], bool],
if_true: WorkflowStep,
if_false: WorkflowStep = None):
"""添加条件分支步骤"""
def conditional_action(ctx):
if condition(ctx):
return if_true.action(ctx)
elif if_false:
return if_false.action(ctx)
return {"skipped": True, "reason": "Condition not met"}

step = WorkflowStep(
name=name,
action=conditional_action,
depends_on=if_true.depends_on
)
self.steps[name] = step

def run(self, initial_input: str) -> dict:
"""执行工作流"""
results = {}
self.context["user_input"] = initial_input

# 拓扑排序:按依赖关系排序步骤
sorted_steps = self._topological_sort()

for step_name in sorted_steps:
step = self.steps[step_name]

# 检查依赖是否已满足
if not self._check_dependencies(step):
step.status = WorkflowStatus.SKIPPED
results[step_name] = {"status": "skipped", "reason": "依赖未满足"}
continue

step.status = WorkflowStatus.RUNNING
print(f"\n▶ 执行步骤: {step.name}")

# 带重试的执行
for attempt in range(step.max_retries + 1):
try:
start_time = time.time()
result = step.action(self.context)
elapsed = time.time() - start_time

step.status = WorkflowStatus.SUCCESS
step.result = result
results[step_name] = {
"status": "success",
"result": result,
"elapsed_seconds": round(elapsed, 2)
}
self.context[step_name] = result
print(f" ✓ 完成 ({elapsed:.1f}s)")
break

except Exception as e:
step.retry_count = attempt + 1
if attempt < step.max_retries:
wait = 2 ** attempt # 指数退避
print(f" ✗ 失败: {e}{wait}s 后重试 ({attempt + 1}/{step.max_retries})")
time.sleep(wait)
else:
step.status = WorkflowStatus.FAILED
step.error = str(e)
results[step_name] = {
"status": "failed",
"error": str(e)
}
print(f" ✗ 最终失败: {e}")

return results

def _check_dependencies(self, step: WorkflowStep) -> bool:
"""检查步骤的依赖是否全部成功"""
for dep_name in step.depends_on:
if dep_name not in self.steps:
return False
if self.steps[dep_name].status != WorkflowStatus.SUCCESS:
return False
return True

def _topological_sort(self) -> list[str]:
"""简单的拓扑排序"""
visited = set()
sorted_list = []

def dfs(node):
if node in visited:
return
visited.add(node)
step = self.steps.get(node)
if step:
for dep in step.depends_on:
if dep in self.steps:
dfs(dep)
sorted_list.append(node)

for name in self.steps:
dfs(name)

return sorted_list

实战:自动化信息收集工作流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# examples/info_gathering_workflow.py
from agent.core import SimpleAgentWithMemory
from agent.workflow import WorkflowEngine, WorkflowStep
from agent.tools import TOOL_REGISTRY

def main():
agent = SimpleAgentWithMemory()
engine = WorkflowEngine(agent)

# 步骤 1:搜索收集信息
def search_info(ctx):
topic = ctx.get("user_input", "")
result = agent.run(f"请搜索关于 '{topic}' 的最新信息")
return result

# 步骤 2:总结信息
def summarize(ctx):
raw_info = ctx.get("search_info", "")
result = agent.run(f"请总结以下信息,提取关键点:\n{raw_info}")
return result

# 步骤 3:生成报告
def generate_report(ctx):
summary = ctx.get("summarize", "")
result = agent.run(f"请根据以下总结,生成一份结构化的中文报告:\n{summary}")
return result

# 步骤 4:保存报告(条件分支)
def save_report(ctx):
report = ctx.get("generate_report", "")
with open(f"report_{int(time.time())}.md", "w", encoding="utf-8") as f:
f.write(report)
return {"saved": True, "path": f"report_{int(time.time())}.md"}

# 注册步骤
engine.add_step(WorkflowStep("search_info", search_info))
engine.add_step(WorkflowStep("summarize", summarize, depends_on=["search_info"]))
engine.add_step(WorkflowStep("generate_report", generate_report, depends_on=["summarize"]))
engine.add_step(WorkflowStep("save_report", save_report, depends_on=["generate_report"]))

# 运行工作流
topic = input("请输入要调研的主题:")
print(f"\n开始执行信息收集工作流...")
print("=" * 50)

results = engine.run(topic)

print("\n" + "=" * 50)
print("工作流执行报告")
print("=" * 50)
for step_name, result in results.items():
status_icon = "✅" if result["status"] == "success" else "❌" if result["status"] == "failed" else "⏭️"
print(f"{status_icon} {step_name}: {result['status']}")
if "elapsed_seconds" in result:
print(f" 耗时: {result['elapsed_seconds']}s")

错误处理与重试策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 高级重试策略:指数退避 + 抖动
def retry_with_backoff(func, max_retries=3, base_delay=1.0):
"""
带指数退避和随机抖动的重试机制。

等待时间 = base_delay * (2 ** attempt) + random(0, 1)
"""
import random

for attempt in range(max_retries + 1):
try:
return func()
except Exception as e:
if attempt == max_retries:
raise e
delay = base_delay * (2 ** attempt) + random.random()
print(f" 重试 {attempt + 1}/{max_retries},等待 {delay:.1f}s...")
time.sleep(delay)

return None

# 使用示例
def safe_web_search(query):
"""带重试的安全搜索"""
def do_search():
return TOOL_REGISTRY["web_search"]["function"](query)

try:
result = retry_with_backoff(do_search, max_retries=3)
return result
except Exception as e:
return {"error": f"搜索最终失败: {str(e)}"}

总结

我们构建了什么

通过本文,我们从一个概念出发,逐步构建了一个完整的 AI Agent 系统:

组件 功能
Agent 核心 实现了 Perceive → Think → Act → Observe 循环
工具系统 可扩展的工具注册表,支持搜索、计算、文件操作等
记忆系统 短期(对话管理)+ 长期(持久化存储)双重记忆
工作流引擎 多步骤编排、条件分支、自动重试与错误处理

完整代码获取

本文所有代码均可在 GitHub 上获取:

1
https://github.com/your-org/ai-agent-tutorial

进一步学习资源

伦理考量

AI Agent 的自主性带来了巨大的潜力,但也伴随着责任:

  1. 安全边界:始终对 Agent 的工具调用设置权限和速率限制
  2. 透明度:Agent 的操作应可审计、可追溯
  3. 人工监督:关键决策应保留人工确认环节
  4. 数据隐私:Agent 处理的数据应遵循最小化原则
  5. 可靠性:Agent 的输出应附带置信度评估

记住:AI Agent 是工具,不是决策者。最终的判断权和责任始终在人类手中。


本文发布于 2026年8月7日。AI 技术日新月异,请结合最新文档和最佳实践使用本文内容。