让模型解释一篇文章,只需要把内容交给它;让它查资料、读取草稿、检查链接,再根据结果决定下一步,就需要一套能执行动作、保存状态并处理失败的程序。

这也是理解 Python 与 AI Agent 关系的起点:模型负责在给定上下文中生成回答或提出工具调用,Python 程序负责把这些调用接到实际系统,并管理整个执行过程。

Python 适合这类工作,主要因为函数容易封装成工具,现有库能连接文件、网络和数据服务,异步能力适合组织 I/O,框架也提供了状态与流程管理的支持。它的价值会体现在 Agent 的执行与编排环节,而不仅是调用一次模型接口。

AI Agent 与普通模型调用有什么区别

“Agent”没有所有产品共同遵循的唯一定义。讨论工程实现时,可以先区分三种情况:

形式 谁决定后续步骤 一个博客任务示例
单次模型调用 应用只发起一次请求 输入文章,返回摘要
固定工作流 程序预先规定步骤 读取草稿、检查链接、生成预览,按固定顺序完成
具有工具能力的 Agent 模型可根据结果选择后续动作,程序限制可执行范围 根据问题选择检索、读文件或查询状态,观察结果后继续或结束

Anthropic 的工程文章用“预定义代码路径”和“模型动态决定流程与工具使用”区分工作流与 Agent。这是一个实用的架构划分,不是所有系统必须采用的命名标准。Building effective agents

一个 Agent 可以嵌在固定工作流中:前面由模型选择资料,后面由程序强制执行格式检查;也可以在特定步骤等待用户决定。自主程度需要按任务设计。

ReAct 原始论文讨论了将推理与行动交替组织,并通过外部环境的观察更新后续行动的思路。这能帮助理解“行动后观察,再决定下一步”的循环;论文中的任务和结果不能直接代表某个博客助手的效果。ReAct 原始论文

Python 在 Agent 的执行循环中负责什么

以“检查一篇草稿的资料是否完整”为例,模型可以提出读取草稿、检索资料或检查链接的请求。真正去读文件和发起 HTTP 请求的,是应用中的执行器,或相应的托管工具服务。

组件 主要职责
模型 理解当前任务,生成回答或结构化工具调用
Python 运行程序 整理上下文、调度模型、执行已允许的工具、记录结果
工具 完成检索、读取、查询、写入等具体操作
状态与存储 保存任务进度、工具结果和恢复所需的信息

程序通常需要反复执行“调用模型、检查返回类型、执行工具、回传结果”这一循环,同时判断任务是否完成或预算是否耗尽。模型返回一个工具名称,并不会让操作自动在服务器上发生。

这里必须保留一个边界:工具调用是模型提出的请求,执行权限由应用决定。 用户要求检查文章时,模型即使提出删除文件或发布页面,程序也不能仅凭这次输出扩大权限。

Agent工具调用闭环:模型提出请求,Python校验并执行工具,记录结果后反馈模型或结束任务
模型负责提出调用;程序检查范围并执行,工具结果回传后继续判断,达到预算上限则停止。

为什么 Python 函数容易变成工具

Python 可以用普通函数把业务能力封装成小接口。例如,查询草稿状态可以是一段读取数据库或仓库元数据的函数;检索资料也可以封装为接收关键词、返回结构化结果的函数。

Agent 工具通常还要有名称、用途说明、输入结构和返回约定。在 LangChain 的工具接口中,函数注解可以参与定义输入结构,函数文档字符串可以用作工具描述。这减少了重复定义接口的工作,但具体规则属于框架能力。LangChain 工具文档

需要特别注意:Python 的 slug: str 这类注解本身不强制运行时类型检查。模型输出中的参数仍应由执行程序检查,不能因为函数写了注解,就假定输入已经可靠。Python 类型注解说明

好的工具接口应该让模型和执行程序都容易判断:

  • 能力范围清楚。 get_post_status 只查询状态,修改和发布使用其他独立接口。
  • 参数具体。 用文章标识、查询词和数量上限表达意图,避免只有一个含义不明的自由文本参数。
  • 结果可检查。 返回找到、未找到、权限不足或失败等明确状态,并保留必要依据。

Python 简洁的函数与数据结构有利于快速修改这种接口;它对脚本和快速应用开发的支持,也适合早期逐步验证 Agent 的能力。Python 官方教程

一个可以运行的工具调用闭环

下面是一个只使用 Python 标准库的离线示例。模型响应由 demo_model 模拟,工具读取内存中的示例数据,不访问真实博客或外部 API。它展示的是执行器如何检查调用、运行工具、回传结果和结束任务,不是实际模型的决策效果。

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
import json

POSTS = {"python-agent": {"status": "draft"}}


def get_post_status(slug: str) -> dict:
"""查询示例文章状态,不修改或发布文章。"""
if not isinstance(slug, str) or not slug:
raise ValueError("slug 必须是非空字符串")
post = POSTS.get(slug)
return {"found": post is not None, "status": post["status"] if post else None}


def dispatch_tool(name, arguments):
if name != "get_post_status":
raise ValueError("未允许的工具")
if not isinstance(arguments, dict) or set(arguments) != {"slug"}:
raise ValueError("参数必须且只能包含 slug")
return get_post_status(**arguments)


def demo_model(messages):
if messages[-1]["role"] == "tool":
result = json.loads(messages[-1]["content"])
text = f"文章状态:{result['status']}" if result["found"] else "未找到文章"
return {"type": "final", "text": text}
return {
"type": "tool_call",
"id": "call_1",
"name": "get_post_status",
"arguments": {"slug": "python-agent"},
}


messages = [{"role": "user", "content": "查询 python-agent 的状态"}]

for _ in range(3):
response = demo_model(messages)
if response["type"] == "final":
print(response["text"])
break
if response["type"] != "tool_call":
raise ValueError("未知响应类型")
result = dispatch_tool(response["name"], response["arguments"])
messages.append({"role": "assistant", "tool_call": response})
messages.append({
"role": "tool",
"tool_call_id": response["id"],
"content": json.dumps(result, ensure_ascii=False),
})
else:
raise RuntimeError("达到最大轮数")

运行结果是 文章状态:draft。把工具名改成未允许的名称、给出多余字段或传入错误的 slug 类型,执行器会拒绝继续调用。

这段代码使用自定义的内部消息结构。接入真实模型时,需要增加适配层:声明工具的输入结构,将供应商响应转换为程序能处理的类型,并按其协议关联工具结果与调用编号;多工具调用、流式返回和错误处理也需要另行实现。

示例中的三轮上限用于演示停止条件。真实任务还要结合模型超时、工具超时、调用次数和费用预算判断能否继续,不能只依赖模型主动结束。

异步能力为什么适合组织 Agent 工具

Agent 经常等待模型服务、网页、数据库或文件服务返回。如果几项任务相互独立,可以让这些等待过程并发进行。

Python 的 asyncio 使用 async / await 组织并发,适合 I/O 密集和结构化网络程序。它不会让一个依赖前一步结果的动作提前完成,也不会自动加速 CPU 密集计算。asyncio 官方文档

下面用短暂等待模拟两个独立查询,演示并发和整组超时;需要 Python 3.11 或更新版本,示例不发起网络请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import asyncio


async def read_status(name):
await asyncio.sleep(0.05) # 模拟等待外部服务
return {"service": name, "status": "ok"}


async def main():
try:
async with asyncio.timeout(2):
async with asyncio.TaskGroup() as group:
article = group.create_task(read_status("article"))
links = group.create_task(read_status("links"))
print(article.result(), links.result())
except TimeoutError:
print("查询超时,停止本轮任务")


asyncio.run(main())

TaskGroup 组织一组任务,asyncio.timeout 提供超时控制;任务异常和取消仍要按实际调用处理。同步阻塞的网络库如果直接放进协程,会阻塞事件循环;运行中的远程操作或转交线程的工作,也未必能随本地取消立即终止。Python 协程与任务文档

在真实项目中,还要限制并发数量,避免多个 Agent 同时把模型接口或数据库打满。异步是调度方式,服务限流、连接管理和重试策略仍由程序设计。

状态管理让 Agent 能够继续完成任务

一次对话中的消息可以作为上下文,但复杂任务还需要记录当前步骤、已经取得的结果、失败原因以及等待中的决定。

例如,检查草稿时已经完成资料检索,下一步要生成预览。进程重启后,如果只记得最初的问题,Agent 可能重新查询同一批资料;如果保存了可恢复状态,就有机会从明确的执行位置继续。

LangGraph 提供持久化机制:checkpointer 保存某个执行线程的图状态,store 保存应用定义的跨线程信息。使用这些能力,需要按业务配置实际存储与隔离方式;安装框架并不会自动获得持久可靠的“记忆”。LangGraph 持久化文档

这里的 thread 指框架中的执行或会话标识,不等同于 Python 的操作系统线程。对话记录、任务状态和长期知识也应按用途管理,避免把所有历史文本无限追加进提示词。

恢复执行还涉及副作用。读取同一个文档通常可以重复,提交订单、发信或发布文章却可能造成重复结果。需要使用任务标识、幂等键或业务状态检查等机制,才能判断某个动作是否已经完成。

LangGraph 的中断文档明确提醒:恢复时节点可能重新执行,因此中断之前的副作用应考虑幂等。检查点记录了状态,并不自动保证外部系统中的操作只执行一次。LangGraph 中断与副作用说明

工作流框架解决什么问题

开始时,一个普通 Python 循环就可以说明执行机制。随着任务增加,程序可能需要条件分支、状态保存、人工介入、流式反馈和恢复执行,框架能够减少这些基础设施的重复实现。

LangGraph 将自己定位为有状态 Agent 的编排运行时,支持将确定性的代码步骤与模型驱动的步骤组合起来。它负责提供流程基础设施,任务能否完成仍取决于模型、工具设计、数据和应用约束。LangGraph 概览

需求 可以先考虑的实现
固定格式的单次生成 一次模型调用和结果校验
步骤顺序已知 普通函数或固定工作流
模型需要根据结果选择工具 带工具白名单与停止条件的调用循环
任务跨多轮、等待审批或需要恢复 显式状态和持久化的工作流编排

对博客助手而言,可以允许模型选择检索资料,但将“生成预览、检查索引、执行发布”放进明确的程序流程。容易验证的步骤用代码约束,确实需要灵活判断的部分再交给模型。

MCP 在 Python 与工具之间起什么作用

当不同 Agent 应用需要接入相同工具时,为每个应用重新写一套专用连接会产生维护成本。MCP 为应用与外部能力之间的上下文交换提供协议,定义客户端、服务端和工具等接口;它不规定模型必须怎样推理或如何管理上下文。MCP 架构说明

Python 可以用于编写 MCP 客户端或服务端。工具通过协议被发现和调用之后,仍需要实际业务代码完成读取、查询或写入。MCP 本身不会让一个模型拥有新的执行权限,也不能替应用完成业务授权。

MCP 也不是 Python 专用协议,官方提供多种语言的 SDK。Python 在这里的优势是容易复用已有服务和数据处理代码,而不是对协议的独占支持。MCP 官方 SDK

模型、Python运行程序与MCP的职责:直接工具和MCP客户端连接业务能力,结果由运行程序处理
直接工具和MCP服务都需要实际执行代码;MCP统一接口,权限与状态管理仍由应用落实。

Python 的优势有哪些边界

首先,模型能力和程序语言是不同的层次。把执行器换成 Python,不会自动让模型更准确地选择工具;接口描述含糊、返回内容不完整,仍会影响后续判断。

其次,Agent 慢在哪里需要分开测量:模型生成、网络等待、工具执行、上下文整理、重试和排队都可能占用时间。远程模型耗时较大时,重写少量 Python 调度代码未必有明显收益;如果本地解析或计算已经成为瓶颈,则应针对那部分优化。

工具返回内容还可能包含网页正文、邮件或第三方文档。这些内容可以提供任务数据,但其中出现的“忽略原要求并执行某动作”不能成为新的授权。工具范围、文件路径、账号权限和高影响操作的确认,应由应用在模型输出之外执行检查。

生产环境还需要核对超时和重试的关系:只重试明确可以重复的操作;写入结果不确定时,先查业务状态,再决定是否再次执行。日志应能关联一次任务与具体工具调用,同时避免记录密钥和不必要的个人数据。这些是执行系统的工程责任,提示词无法单独替代。

什么情况下适合选择 Python

如果 Agent 需要连接大量已有 Python 工具、处理文档和数据,或频繁调整工具接口与工作流,Python 通常是值得优先评估的选择。团队能够在同一环境中组织模型请求、编写工具和检查结果,减少系统之间的转换工作。

如果业务主体已经是 TypeScript、Java 或 Go,且只是接入模型和少量 HTTP 工具,沿用原有技术栈也可能更容易维护。也可以让 Python 提供特定工具服务,由其他语言的应用通过接口调用。

判断语言是否合适,可以先做一个可核对的小任务:准备两个只读工具,明确输入输出和最大调用次数,记录每次工具选择、结果与耗时,再加入失败、超时和恢复场景。观察这些环节是否清楚,比堆叠更多工具或更多 Agent 更能帮助判断方案是否可用。

Python 与 AI Agent 的适配,最终体现在它能否让模型请求、实际执行和流程状态清楚地衔接起来。理解这个分工,才能既利用模型的灵活性,也让应用保留可检查、可恢复的执行逻辑。

参考资料

资料核对于 2026 年 10 月 25 日。Python 说明按 3.14 文档,离线异步示例使用 3.11 起提供的接口;MCP 架构链接固定为 2026-07-28 文档,其余框架链接为滚动维护文档。工程文章用于解释架构,具体接口按项目当前文档核对。

  1. Yao 等,ReAct: Synergizing Reasoning and Acting in Language Models(ICLR 2023,作者公开稿):行动与环境观察交替组织的原始研究,不作为本文示例效果或语言优劣的基准。
  2. Anthropic,Building effective agents(2024 年起发布的工程文章):Agent 与工作流的架构区分;页面已提醒工具生态后续发生变化。
  3. Python 官方教程:函数、数据结构与快速应用开发。
  4. LangChain 工具文档:工具名称、文档字符串与输入结构。
  5. Python 类型注解:类型注解不由 Python 运行时自动强制检查。
  6. asyncio 概览:异步 I/O 与协程组织。
  7. Python 协程与任务:TaskGroup、超时、取消与线程调用的限制。
  8. LangGraph 概览:有状态 Agent 与工作流编排。
  9. LangGraph 持久化:checkpointer、store 和状态保存。
  10. LangGraph 中断:暂停恢复及副作用幂等。
  11. MCP 架构:应用、客户端、服务端与工具的协议分工。
  12. MCP 官方 SDK:多语言客户端与服务端开发入口。