第3章 写Agent之前,这些Python够用了
第2章装好了环境,这一章快速过一遍Python——不是从头教,是挑Agent开发里真正常用到的部分。如果你Python已经熟了,可以扫一遍直接跳到第4章。如果有些生疏,跟着过一遍,后面写Agent代码的时候不会卡在基础语法上。
3.1 Agent的工作台
3.1.1 用得最多的三种数据
写Agent的时候,你会频繁跟三种数据结构打交道。
列表:Agent拿到一堆工具返回的结果,用列表装着最方便。
python
# Agent调用了三个搜索工具,结果放在一起
search_results = [
"北京今天晴,20-28℃",
"北京明天多云,18-25℃",
"北京后天有雨,15-22℃"
]
# Agent需要从中挑出"有雨"的那条
rain_days = [r for r in search_results if "雨" in r]
print(rain_days) # ['北京后天有雨,15-22℃']字典:Agent跟外部API打交道,JSON来回全是字典。
python
# 工具返回的天气数据(JSON转成的字典)
weather = {
"city": "北京",
"temperature": 25,
"humidity": 60,
"forecast": ["晴", "多云", "有雨"]
}
# Agent提取需要的信息
if weather["temperature"] > 30:
print(f"{weather['city']}今天很热")
else:
print(f"{weather['city']}今天温度还行")集合:Agent需要"去重"的时候用。比如一个Agent问了三个不同的人同一个问题,得到了一些重复的回答,用集合快速去重。
python
# 三个Agent返回的推荐方案,有重复
plan_a = {"改签", "退款", "补偿"}
plan_b = {"改签", "升级舱位", "补偿"}
plan_c = {"退款", "补偿", "优惠券"}
# 合并所有方案,自动去重
all_plans = plan_a | plan_b | plan_c
print(all_plans) # {'改签', '退款', '补偿', '升级舱位', '优惠券'}3.1.2 推导式:少写for循环的秘密
Agent代码里经常需要"把A处理成B",用推导式一行搞定。
python
# 不用推导式:三行
tools = ["search", "calculator", "weather"]
upper_tools = []
for t in tools:
upper_tools.append(t.upper())
# 用推导式:一行
upper_tools = [t.upper() for t in tools]字典推导式更常用——Agent经常需要把一种格式的字典转成另一种:
python
# API返回的工具配置
tool_configs = {
"search": {"enabled": True, "timeout": 10},
"calculator": {"enabled": False, "timeout": 5},
"weather": {"enabled": True, "timeout": 8}
}
# 只要启用的工具
active_tools = {k: v for k, v in tool_configs.items() if v["enabled"]}
# {'search': {'enabled': True, 'timeout': 10}, 'weather': {'enabled': True, 'timeout': 8}}3.2 写Agent代码的好帮手
3.2.1 lambda:临时小函数
Agent开发中经常需要传一个小函数作为参数,但专门写个 def 又太重了。这时候用 lambda。
python
# 场景:Agent拿到了一批工具的评分,需要按分数排序
tools = [
{"name": "search", "score": 4.5},
{"name": "calculator", "score": 3.2},
{"name": "weather", "score": 4.8}
]
# lambda 一行搞定按score排序
tools.sort(key=lambda t: t["score"], reverse=True)
print([t["name"] for t in tools]) # ['weather', 'search', 'calculator']3.2.2 map 和 filter:批量处理利器
这两个函数在LangChain的源码里出现频率很高,值得了解一下。
python
# Agent拿到了一堆用户消息,需要全部转成小写再处理
messages = ["Hello World", "HOW ARE YOU", "Fine Thank You"]
lowered = list(map(str.lower, messages))
# ['hello world', 'how are you', 'fine thank you']
# 过滤掉空消息
raw = ["你好", "", "帮我查天气", "", "谢谢"]
valid = list(filter(None, raw))
# ['你好', '帮我查天气', '谢谢']3.2.3 解包:让参数传递更灵活
Agent框架里经常看到 *args 和 **kwargs,其实就是"我不管你给我多少个参数,我都能处理"。
python
# 场景:Agent的工具调用函数,不知道每次会传几个参数
def call_tool(tool_name, *args, **kwargs):
"""通用工具调用函数"""
print(f"调用工具: {tool_name}")
print(f"位置参数: {args}")
print(f"关键字参数: {kwargs}")
# 不同工具传不同的参数
call_tool("search", "北京天气")
# 调用工具: search
# 位置参数: ('北京天气',)
# 关键字参数: {}
call_tool("weather", city="北京", date="明天")
# 调用工具: weather
# 位置参数: ()
# 关键字参数: {'city': '北京', 'date': '明天'}3.3 让代码更优雅
3.3.1 装饰器:给函数加个"壳"
Agent开发中最常见的装饰器场景:记录每个工具调用的耗时。
python
import time
def log_time(func):
"""记录函数执行时间的装饰器"""
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
cost = time.time() - start
print(f"工具 {func.__name__} 执行耗时: {cost:.2f}秒")
return result
return wrapper
@log_time
def search_weather(city):
time.sleep(1.2) # 模拟API调用
return f"{city}今天晴"
@log_time
def search_news(topic):
time.sleep(0.8)
return f"关于{topic}的最新消息..."
# 两个函数自动带上了计时功能
print(search_weather("北京"))
# 工具 search_weather 执行耗时: 1.20秒
# 北京今天晴3.3.2 上下文管理器:自动"进门"和"出门"
Agent需要连数据库、开文件、调API——这些操作都有"打开"和"关闭"两步。上下文管理器帮你自动关,不用手动 close()。
python
# 不用上下文管理器:容易忘关
f = open("agent_log.txt", "w")
f.write("Agent started\n")
# ... 写了一堆代码,中间可能报错
f.close() # 如果中间报错了,这行根本执行不到
# 用上下文管理器:自动关,绝不出错
with open("agent_log.txt", "w") as f:
f.write("Agent started\n")
# 不管中间报不报错,退出 with 块自动关闭你自己写Agent工具时也会用到:
python
from contextlib import contextmanager
@contextmanager
def tool_session(tool_name):
"""模拟工具调用的会话管理"""
print(f"[{tool_name}] 初始化连接...")
yield # 这里执行工具的具体逻辑
print(f"[{tool_name}] 关闭连接,释放资源")
# 使用
with tool_session("weather_api"):
print("正在查询天气...")
# 输出:
# [weather_api] 初始化连接...
# 正在查询天气...
# [weather_api] 关闭连接,释放资源3.4 让Agent同时做多件事
Agent经常需要"同时"调好几个工具——比如查天气的同时查新闻、查股价。如果串行执行,用户得等很久。
3.4.1 什么时候用 asyncio
asyncio 适合"IO密集型"任务——大部分时间在等网络返回,Python可以趁等待的时间去干别的事。
python
import asyncio
async def call_api(tool_name, delay):
"""模拟调用外部API"""
print(f"开始调用 {tool_name}...")
await asyncio.sleep(delay) # 模拟网络等待
print(f"{tool_name} 返回结果")
return f"{tool_name} 的结果"
async def main():
# 同时发起三个工具调用
results = await asyncio.gather(
call_api("天气查询", 1),
call_api("新闻搜索", 0.8),
call_api("股价查询", 0.5)
)
print(f"全部完成: {results}")
asyncio.run(main())
# 输出:三个调用几乎同时开始,总耗时≈1秒而不是1+0.8+0.5=2.3秒3.4.2 什么时候不用
如果你的工具调用本身就是"串行"的(第二步依赖第一步的结果),那老老实实写同步代码就好。asyncio 不是魔法,它只在"等待IO时可以切走"这个场景有用。
python
# 这种场景不需要 asyncio
# 因为第二步依赖第一步的结果
result_1 = search_location("北京")
result_2 = search_weather(result_1["location_id"]) # 依赖result_13.5 Agent的眼睛和耳朵
3.5.1 文件读写:Agent记日志、读配置
Agent运行时会记日志、读配置文件、保存结果——文件操作是基本功。
python
import time
from pathlib import Path
# 写日志(追加模式)
log_file = Path("agent.log")
with open(log_file, "a") as f:
f.write(f"[{time.strftime('%H:%M:%S')}] 用户提问:今天天气怎么样\n")
# 读配置文件
import json
with open("agent_config.json", "r") as f:
config = json.load(f)
print(config["model"]) # 比如 "gpt-4"3.5.2 网络请求:Agent调用外部API
Agent最核心的能力就是调用外部API。requests 库基本上每个Agent项目都会用到。
python
import requests
def search_weather(city):
"""调用天气API"""
try:
response = requests.get(
"https://api.weather.com/v1/current",
params={"city": city},
timeout=5 # 5秒超时,别让Agent傻等
)
response.raise_for_status() # 状态码不是200就抛异常
return response.json()
except requests.Timeout:
return {"error": "天气服务超时,请稍后重试"}
except requests.RequestException as e:
return {"error": f"请求失败: {str(e)}"}几个写Agent时容易踩的坑:
- 永远加 timeout——不然Agent可能卡死在一个慢API上
- 永远处理异常——外部API随时可能挂,你的Agent不能跟着挂
- API Key 放
.env文件,别硬编码——这个第2章讲过了
3.6 本章小结
这一章我们快速过了一遍Agent开发中最常用的Python知识:
- 数据结构:列表装结果、字典传数据、集合去重——Agent的日常工作台
- 函数式编程:lambda、map、filter、解包——让Agent代码更简洁
- 装饰器与上下文管理器:给工具加日志、自动管理资源——让代码更优雅
- asyncio并发:Agent同时调多个工具时,别让用户傻等
- 文件与网络:Agent读配置、记日志、调API的基本功
这些不是你还没学的Python基础——是你写Agent时真正常用到的部分。剩下的语法,遇到了查一下就行。
✅ 知识点检查
学完这一章,试试回答这几个问题:
- [ ] 列表、字典、集合各适合什么场景?Agent代码里为什么用推导式比for循环更多?
- [ ]
lambda在什么情况下比写一个def更合适? - [ ] 装饰器和上下文管理器的本质区别是什么?
- [ ]
asyncio什么时候能加速你的Agent?什么时候加速不了? - [ ] 写Agent调外部API时,有哪三个容易踩的坑?
📚 延伸阅读
- Python官方文档:https://docs.python.org/3/
- Real Python教程:https://realpython.com/ — 有大量Python进阶文章
- 本书配套源码:关注公众号「图解AI系列」免费领取
🎯 下一章预告
第4章,我们正式进入AI Agent的世界——
"Agent不是魔法,它只是个聪明点的程序。看完这一章,你就知道它到底是个什么东西。"

