从零实现一个 AI Agent CLI:完整教程
1. 引言
AI Agent(智能体)是当前 AI 应用开发中最热门的范式之一。一个 AI Agent 能够理解用户的目标,自主规划步骤,调用工具(如搜索引擎、计算器、文件系统)来完成任务,而不仅仅是生成一段文本。
CLI(命令行界面)是 Agent 最自然的载体之一。通过终端,Agent 可以轻松地执行系统命令、读写文件、调用 API,甚至管理整个开发流程。
本文将带你从零开始,使用 Python 和 LangChain 框架,一步步构建一个功能完整的 AI Agent CLI。你将学到:
- Agent 的核心概念与运行原理
- 如何定义 Agent 可以使用的工具
- 如何构建 Agent 的思考与行动循环
- 如何将 Agent 封装成一个可交互的命令行应用
- 如何扩展 Agent 的能力
2. 环境准备与项目初始化
2.1 创建项目
首先,创建一个新的项目目录并初始化 Python 虚拟环境。
mkdir ai-agent-cli
cd ai-agent-cli
python3 -m venv venv
source venv/bin/activate # Linux/macOS
# venv\Scripts\activate # Windows
2.2 安装依赖
我们需要安装以下核心库:
langchain:LangChain 框架核心langchain-openai:OpenAI 模型接口openai:OpenAI Python 客户端python-dotenv:管理环境变量
pip install langchain langchain-openai openai python-dotenv
2.3 配置 API Key
在项目根目录创建 .env 文件,填入你的 OpenAI API Key(或其他兼容的 LLM API Key):
OPENAI_API_KEY=sk-your-api-key-here
# 如果你使用其他模型,可以配置
# OPENAI_API_BASE=https://api.xxx.com/v1
# LLM_MODEL=gpt-4o-mini
3. 核心概念:Agent 的工作原理
在开始编码之前,理解 Agent 的核心循环至关重要。一个典型的 ReAct(Reasoning + Acting)Agent 遵循以下步骤:
- 思考(Thought):Agent 接收用户输入和当前状态,决定下一步该做什么。
- 行动(Action):Agent 选择一个工具并传入参数来执行。
- 观察(Observation):Agent 接收工具执行后的结果。
- 循环:Agent 根据观察结果继续思考,直到它认为任务完成,然后给出最终答案(Final Answer)。
这个循环由 LLM 的推理能力驱动。我们通过给 LLM 一个包含可用工具描述和调用格式的 Prompt,让它学会“思考-行动-观察”的模式。
4. 第一步:定义 Agent 的工具
工具是 Agent 与外部世界交互的接口。每个工具都需要有清晰的名称、描述和参数定义,这样 LLM 才能正确地选择和使用它。
4.1 创建工具模块
在项目根目录创建 tools.py 文件。
# tools.py
from langchain.tools import tool
import subprocess
import os
import json
@tool
def run_shell_command(command: str) -> str:
"""
执行一个 shell 命令并返回输出结果。
适用于运行脚本、编译代码、查看文件等。
"""
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30
)
output = result.stdout
if result.stderr:
output += f"\n[STDERR]\n{result.stderr}"
if result.returncode != 0:
output += f"\n[Exit code: {result.returncode}]"
return output
except subprocess.TimeoutExpired:
return "错误:命令执行超时(30秒)"
except Exception as e:
return f"错误:执行命令时发生异常 - {str(e)}"
@tool
def read_file(file_path: str) -> str:
"""
读取指定文件的全部内容。文件路径应为绝对路径或相对于当前工作目录的路径。
"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
return content
except FileNotFoundError:
return f"错误:文件 '{file_path}' 未找到"
except Exception as e:
return f"错误:读取文件时发生异常 - {str(e)}"
@tool
def write_file(file_path: str, content: str) -> str:
"""
将内容写入指定文件。如果文件不存在则创建,如果存在则覆盖。
"""
try:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
return f"成功:内容已写入 '{file_path}'"
except Exception as e:
return f"错误:写入文件时发生异常 - {str(e)}"
@tool
def list_directory(path: str = ".") -> str:
"""
列出指定目录下的文件和文件夹。
"""
try:
items = os.listdir(path)
result = []
for item in items:
full_path = os.path.join(path, item)
if os.path.isdir(full_path):
result.append(f"[DIR] {item}")
else:
size = os.path.getsize(full_path)
result.append(f"[FILE] {item} ({size} bytes)")
return "\n".join(result) if result else "目录为空"
except FileNotFoundError:
return f"错误:目录 '{path}' 未找到"
except Exception as e:
return f"错误:列出目录时发生异常 - {str(e)}"
关键点:
- 使用
@tool装饰器将函数标记为 LangChain 工具。 - 函数的文档字符串(docstring)就是工具的描述,LLM 会用它来决定何时调用此工具。
- 参数的类型注解和名称也很重要,LLM 会据此生成正确的参数。
5. 第二步:构建 Agent 核心
现在我们来创建 Agent 的核心逻辑。创建 agent.py 文件。
# agent.py
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain.prompts import PromptTemplate
from tools import run_shell_command, read_file, write_file, list_directory
# 加载环境变量
load_dotenv()
def create_agent(verbose: bool = True):
"""
创建并返回一个 AI Agent 执行器。
"""
# 1. 初始化 LLM
llm = ChatOpenAI(
model=os.getenv("LLM_MODEL", "gpt-4o-mini"),
temperature=0,
api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_API_BASE"),
)
# 2. 定义工具列表
tools = [
run_shell_command,
read_file,
write_file,
list_directory,
]
# 3. 创建 ReAct Agent
# 使用一个清晰的 Prompt 模板来指导 Agent 的行为
prompt = PromptTemplate.from_template(
"""你是一个强大的 AI 助手,可以通过思考和调用工具来帮助用户完成各种任务。
你拥有以下工具:
{tools}
工具名称:{tool_names}
请严格按照以下格式进行思考和行动:
Thought: 描述你当前的想法和计划。
Action: 你要调用的工具名称,必须是 [{tool_names}] 中的一个。
Action Input: 传递给工具的输入参数,必须是一个有效的 JSON 对象。
Observation: 工具返回的结果。
...(重复 Thought/Action/Observation 循环)
Thought: 我现在可以给出最终答案了。
Final Answer: 对用户问题的最终回答。
用户的问题是:{input}
你的工作区是当前目录,你可以自由地创建、读取和修改文件。
{agent_scratchpad}
"""
)
# 4. 创建 Agent
agent = create_react_agent(
llm=llm,
tools=tools,
prompt=prompt,
)
# 5. 创建 Agent 执行器
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=verbose, # 打印思考过程
handle_parsing_errors=True, # 处理 LLM 输出解析错误
max_iterations=15, # 防止无限循环
)
return agent_executor
代码解析:
create_react_agent:LangChain 内置的 ReAct Agent 创建函数,它自动处理了 Prompt 的组装和输出解析。AgentExecutor:负责驱动 Agent 的思考-行动循环,直到得到最终答案或达到最大迭代次数。verbose=True:在终端打印 Agent 的思考过程,对调试和理解 Agent 行为非常有帮助。handle_parsing_errors:当 LLM 输出格式不正确时,自动重试,提高鲁棒性。
6. 第三步:创建 CLI 交互界面
现在我们把 Agent 封装成一个交互式命令行应用。创建 cli.py 文件。
# cli.py
import sys
import readline # 提供命令行历史记录和编辑功能
from agent import create_agent
def main():
print("=" * 60)
print(" AI Agent CLI - 你的智能命令行助手")
print(" 输入你的问题,Agent 将思考并调用工具来帮助你。")
print(" 输入 'exit' 或 'quit' 退出。")
print("=" * 60)
# 创建 Agent
print("\n正在初始化 Agent...")
agent_executor = create_agent(verbose=True)
print("Agent 已就绪!\n")
while True:
try:
# 获取用户输入
user_input = input("\n👤 你: ").strip()
if user_input.lower() in ['exit', 'quit', 'q']:
print("👋 再见!")
break
if not user_input:
continue
# 调用 Agent
print("\n🤖 Agent 正在思考...\n")
response = agent_executor.invoke({"input": user_input})
# 输出最终答案
print(f"\n🤖 Agent: {response['output']}")
except KeyboardInterrupt:
print("\n\n👋 检测到中断,再见!")
break
except Exception as e:
print(f"\n❌ 发生错误: {str(e)}")
if __name__ == "__main__":
main()
7. 运行与测试
7.1 启动 CLI
在终端运行:
python cli.py
7.2 测试示例
启动后,你可以尝试以下命令来测试 Agent 的能力:
示例 1:文件操作
👤 你: 帮我创建一个名为 hello.py 的文件,内容是一个打印 "Hello, AI Agent!" 的 Python 脚本
示例 2:执行命令
👤 你: 运行刚才创建的 hello.py 文件
示例 3:组合任务
👤 你: 查看当前目录下有哪些文件,然后读取 hello.py 的内容
示例 4:复杂任务
👤 你: 创建一个名为 project 的目录,在里面创建一个 README.md 文件,写入项目简介,然后列出 project 目录的内容
8. 进阶:扩展 Agent 的能力
8.1 添加 Web 搜索工具
安装 duckduckgo-search 库:
pip install duckduckgo-search
在 tools.py 中添加:
from langchain.tools import tool
from duckduckgo_search import DDGS
@tool
def web_search(query: str) -> str:
"""
使用 DuckDuckGo 搜索互联网。当你需要获取最新信息或查找资料时使用。
"""
try:
with DDGS() as ddgs:
results = list(ddgs.text(query, max_results=5))
if not results:
return "未找到相关结果"
formatted = []
for i, r in enumerate(results, 1):
formatted.append(f"{i}. {r['title']}\n {r['href']}\n {r['body']}")
return "\n\n".join(formatted)
except Exception as e:
return f"搜索失败: {str(e)}"
然后在 agent.py 的 tools 列表中加入这个新工具。
8.2 添加代码执行沙箱
为了安全地执行用户代码,可以使用 Docker 容器。这里提供一个简单的本地 Python 执行工具(注意安全风险):
@tool
def run_python_code(code: str) -> str:
"""
执行一段 Python 代码并返回输出。适用于快速验证算法或数据处理。
注意:此工具会直接执行代码,请确保代码来源可信。
"""
try:
import io
import sys
from contextlib import redirect_stdout, redirect_stderr
f_stdout = io.StringIO()
f_stderr = io.StringIO()
with redirect_stdout(f_stdout), redirect_stderr(f_stderr):
exec(code, {"__builtins__": __builtins__})
output = f_stdout.getvalue()
if f_stderr.getvalue():
output += f"\n[STDERR]\n{f_stderr.getvalue()}"
return output if output else "代码执行成功,无输出。"
except Exception as e:
return f"代码执行错误: {str(e)}"
8.3 添加记忆能力
默认情况下,Agent 每次调用都是独立的。要让它记住对话历史,可以添加记忆组件:
# agent.py 修改
from langchain.memory import ConversationBufferMemory
from langchain.agents import create_react_agent, AgentExecutor
def create_agent_with_memory(verbose: bool = True):
# ... 初始化 llm 和 tools ...
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=verbose,
handle_parsing_errors=True,
max_iterations=15,
memory=memory, # 添加记忆
)
return agent_executor
9. 完整项目结构
ai-agent-cli/
├── .env # 环境变量(API Key 等)
├── .gitignore # Git 忽略文件
├── cli.py # 命令行交互入口
├── agent.py # Agent 核心逻辑
├── tools.py # 工具定义
└── requirements.txt # 依赖列表
requirements.txt 内容:
langchain>=0.3.0
langchain-openai>=0.2.0
openai>=1.0.0
python-dotenv>=1.0.0
duckduckgo-search>=6.0.0 # 可选,用于 Web 搜索
10. 总结与下一步
恭喜!你已经从零实现了一个功能完整的 AI Agent CLI。这个 Agent 能够:
- 理解自然语言指令
- 自主规划并调用工具(执行命令、读写文件、搜索网络)
- 通过思考-行动循环完成复杂任务
- 在终端中提供交互式体验
下一步你可以探索的方向:
- 支持更多 LLM:通过 LangChain 的模型抽象,可以轻松切换为 Claude、Gemini 或本地模型(如 Ollama)。
- 添加更多工具:数据库查询、API 调用、Git 操作等。
- 改进用户体验:添加流式输出、进度条、彩色输出等。
- 安全沙箱:使用 Docker 或子进程隔离来安全执行代码。
- 持久化记忆:将对话历史保存到文件或数据库。
- 多 Agent 协作:创建多个专业 Agent(如代码 Agent、搜索 Agent)协同工作。
这个 CLI 框架为你提供了一个坚实的基础,你可以根据自己的需求不断扩展和优化它。现在,打开终端,开始构建你的 AI Agent 吧!
更多推荐



所有评论(0)