2026 AI Agent 入门实战:不用 LangChain,用 Python 手写一个会调用工具的最小智能体
AI Agent,也就是 AI 智能体,是目前人工智能应用开发中的热门方向。
普通聊天程序只能回答问题,而 Agent 更强调“执行任务”。例如:
- 查看当前时间
- 列出文件夹中的文件
- 统计不同类型文件的数量
- 根据用户要求选择合适的工具
- 获取工具执行结果并返回答案
很多 Agent 教程一开始就使用 LangChain、LangGraph 等框架,初学者容易被大量概念和依赖劝退。
本文先不调用大模型,也不使用第三方框架,只用 Python 标准库手写一个最小 Agent 雏形,理解智能体最基本的运行流程。
一、Agent 的基本工作流程
一个简单的 Agent 可以拆成以下几个部分:
接收用户任务
↓
判断用户想做什么
↓
选择合适的工具
↓
执行工具
↓
读取执行结果
↓
把结果返回给用户
例如,用户输入:
帮我统计文件类型
Agent 判断这是一个文件统计任务,于是选择:
count_file_types
工具执行完成后,Agent 再把统计结果返回给用户。
本文实现三个工具:
- 查看当前时间。
- 查看工作目录中的文件。
- 统计不同类型文件的数量。
二、完整代码
新建一个 Python 文件:
mini_agent.py
复制下面的完整代码:
"""一个只使用 Python 标准库实现的最小 Agent 雏形。"""
import argparse
from collections import Counter
from datetime import datetime
from pathlib import Path
class MiniAgent:
"""根据用户输入选择并执行本地工具。"""
def __init__(self, workspace):
self.workspace = workspace.resolve()
if not self.workspace.is_dir():
raise ValueError("工作目录不存在或者不是文件夹。")
self.tools = {
"current_time": self.current_time,
"list_files": self.list_files,
"count_file_types": self.count_file_types,
}
def current_time(self):
"""返回当前本地时间。"""
return datetime.now().strftime(
"当前时间:%Y-%m-%d %H:%M:%S"
)
def list_files(self):
"""列出工作目录第一层的文件。"""
files = sorted(
[
item.name
for item in self.workspace.iterdir()
if item.is_file()
],
key=str.lower,
)
if not files:
return "当前目录中没有文件。"
# 防止目录中文件过多,只显示前20个
visible_files = files[:20]
result = ["当前目录中的文件:"]
for number, file_name in enumerate(
visible_files,
start=1,
):
result.append(
str(number) + ". " + file_name
)
if len(files) > 20:
result.append(
"还有 "
+ str(len(files) - 20)
+ " 个文件没有显示。"
)
return "\n".join(result)
def count_file_types(self):
"""统计工作目录第一层中不同类型文件的数量。"""
counter = Counter()
for item in self.workspace.iterdir():
if not item.is_file():
continue
file_type = item.suffix.lower()
if not file_type:
file_type = "无扩展名"
counter[file_type] += 1
if not counter:
return "当前目录中没有可以统计的文件。"
sorted_results = sorted(
counter.items(),
key=lambda item: (-item[1], item[0]),
)
result = ["文件类型统计结果:"]
for file_type, count in sorted_results:
result.append(
file_type + ":" + str(count) + " 个"
)
return "\n".join(result)
def decide(self, user_input):
"""根据关键词选择工具。"""
text = user_input.strip().lower()
if any(
keyword in text
for keyword in ["时间", "几点", "日期"]
):
return "current_time"
if (
"统计" in text
and any(
keyword in text
for keyword in ["文件", "类型", "扩展名"]
)
):
return "count_file_types"
if any(
keyword in text
for keyword in ["查看文件", "列出文件", "有哪些文件"]
):
return "list_files"
return None
def run(self, user_input):
"""完成一次任务判断和工具调用。"""
tool_name = self.decide(user_input)
if tool_name is None:
return (
"暂时无法识别这个任务。\n"
"你可以尝试输入:\n"
"1. 现在几点?\n"
"2. 查看文件\n"
"3. 统计文件类型"
)
tool = self.tools[tool_name]
try:
tool_result = tool()
except OSError as error:
return "工具执行失败:" + str(error)
return (
"执行工具:" + tool_name + "\n"
+ tool_result
)
def main():
parser = argparse.ArgumentParser(
description="运行一个最小 Python Agent"
)
parser.add_argument(
"workspace",
nargs="?",
default=".",
help="允许 Agent 读取的工作目录",
)
args = parser.parse_args()
try:
agent = MiniAgent(
Path(args.workspace)
)
except ValueError as error:
print("启动失败:" + str(error))
return 1
print("最小 Python Agent 已启动。")
print("工作目录:" + str(agent.workspace))
print("输入 exit 可以退出程序。")
while True:
user_input = input("\n请输入任务:").strip()
if user_input.lower() in {
"exit",
"quit",
"退出",
}:
print("Agent 已退出。")
break
if not user_input:
print("请输入具体任务。")
continue
print(agent.run(user_input))
return 0
if __name__ == "__main__":
raise SystemExit(main())
三、运行 Agent
在 mini_agent.py 所在目录打开 PowerShell,执行:
python mini_agent.py
程序启动后会显示:
最小 Python Agent 已启动。
工作目录:当前目录的完整路径
输入 exit 可以退出程序。
输入:
现在几点?
Agent 会选择时间工具:
执行工具:current_time
当前时间:2026-09-16 10:30:00
实际时间以电脑运行时显示的结果为准。
四、让 Agent 查看文件
输入:
查看文件
Agent 会执行:
list_files
运行结果类似:
执行工具:list_files
当前目录中的文件:
1. mini_agent.py
2. 工作计划.docx
3. 产品资料.pdf
4. 数据.csv
为了避免一次输出太多内容,程序最多显示前20个文件。
五、让 Agent 统计文件类型
输入:
帮我统计文件类型
运行结果类似:
执行工具:count_file_types
文件类型统计结果:
.pdf:3 个
.txt:2 个
.csv:1 个
.docx:1 个
无扩展名:1 个
程序会把大写和小写扩展名合并。
例如:
图片.PNG
截图.png
都会被统计为:
.png
六、指定需要处理的文件夹
默认情况下,Agent 读取程序当前所在的文件夹。
如果想处理其他目录,可以在启动时填写文件夹路径:
python mini_agent.py "D:\工作资料"
路径中包含空格时,需要使用英文双引号。
例如:
python mini_agent.py "D:\2026 年项目资料"
Agent 只读取指定目录第一层的文件,不会修改、移动或者删除文件。
处理重要资料前,建议先使用测试文件夹运行。
七、为什么它可以算作 Agent 雏形?
这个程序已经包含了 Agent 的几个基础组成部分。
1. 接收任务
user_input = input("请输入任务:")
用户可以使用自然语言描述自己的需求。
2. 任务判断
tool_name = self.decide(user_input)
decide() 根据用户输入判断需要使用哪个工具。
3. 工具注册
self.tools = {
"current_time": self.current_time,
"list_files": self.list_files,
"count_file_types": self.count_file_types,
}
工具名称和实际的 Python 函数保存在字典中。
后续增加新工具时,只需要编写对应函数,再把它注册到字典中。
4. 工具调用
tool = self.tools[tool_name]
tool_result = tool()
Agent 根据任务判断结果调用对应工具。
5. 返回执行结果
return (
"执行工具:" + tool_name + "\n"
+ tool_result
)
工具完成任务后,Agent 将结果整理并返回给用户。
八、它和真正的大模型 Agent 有什么区别?
本文程序使用关键词判断任务:
if "时间" in text:
return "current_time"
优点是:
- 代码简单
- 不需要联网
- 不需要申请 API Key
- 不会产生模型调用费用
- 运行结果容易理解和检查
缺点也很明显:
- 只能理解提前设置好的关键词
- 无法处理复杂表达
- 不会自动拆分多步骤任务
- 不具备上下文记忆
- 不会根据结果继续规划
真正的大模型 Agent 通常会让模型负责理解任务和选择工具。
例如用户输入:
先看看这个文件夹有哪些文件,
再统计一下哪种文件最多。
大模型可能将任务拆成两步:
第一步:调用 list_files
第二步:调用 count_file_types
这也是本文程序后续可以继续升级的方向。
九、如何增加一个新工具?
例如,我们想增加“统计文件总数”工具。
首先编写函数:
def count_all_files(self):
count = sum(
1
for item in self.workspace.iterdir()
if item.is_file()
)
return "文件总数:" + str(count)
然后注册工具:
self.tools = {
"current_time": self.current_time,
"list_files": self.list_files,
"count_file_types": self.count_file_types,
"count_all_files": self.count_all_files,
}
最后在 decide() 中增加判断:
if "文件总数" in text:
return "count_all_files"
这样 Agent 就获得了一项新的能力。
十、常见问题
输入任务后提示无法识别
当前版本依靠关键词判断任务。
可以尝试输入:
现在几点?
查看文件
统计文件类型
提示工作目录不存在
检查文件夹路径是否正确:
python mini_agent.py "D:\工作资料"
不要把具体文件当成工作目录。
文件统计数量不正确
本文只统计指定文件夹第一层的文件,不统计子文件夹中的内容。
另外,脚本文件 mini_agent.py 本身也位于工作目录时,它会被统计为一个 .py 文件。
中文路径能不能使用?
可以。
建议使用完整路径并添加英文双引号:
python mini_agent.py "D:\中文资料目录"
十一、总结
本文没有直接使用复杂框架,而是通过 Python 标准库实现了一个最小 Agent 雏形。
它具备以下能力:
- 接收用户任务
- 判断任务类型
- 选择工具
- 执行工具
- 返回执行结果
- 限制文件访问范围
这个版本还没有接入真正的大模型,但已经展示了 Agent 最核心的结构。
理解这套流程后,下一步可以把关键词判断替换为大模型,再加入:
- 多轮对话
- 自动任务拆分
- 记忆功能
- 大模型 API
- 本地 Ollama 模型
- 多工具连续调用
相比一开始就使用复杂框架,先手写一个最小版本,更容易理解 Agent 到底是怎样工作的。
本文代码由 AI 辅助编写。运行时请先使用测试文件夹,不要直接处理重要资料。
更多推荐




所有评论(0)