从零实现一个 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 虚拟环境。mkdirai-agent-clicdai-agent-cli python3-mvenv venvsourcevenv/bin/activate# Linux/macOS# venv\Scripts\activate # Windows2.2 安装依赖我们需要安装以下核心库langchainLangChain 框架核心langchain-openaiOpenAI 模型接口openaiOpenAI Python 客户端python-dotenv管理环境变量pipinstalllangchain langchain-openai openai python-dotenv2.3 配置 API Key在项目根目录创建.env文件填入你的 OpenAI API Key或其他兼容的 LLM API KeyOPENAI_API_KEYsk-your-api-key-here # 如果你使用其他模型可以配置 # OPENAI_API_BASEhttps://api.xxx.com/v1 # LLM_MODELgpt-4o-mini3. 核心概念Agent 的工作原理在开始编码之前理解 Agent 的核心循环至关重要。一个典型的 ReActReasoning ActingAgent 遵循以下步骤思考ThoughtAgent 接收用户输入和当前状态决定下一步该做什么。行动ActionAgent 选择一个工具并传入参数来执行。观察ObservationAgent 接收工具执行后的结果。循环Agent 根据观察结果继续思考直到它认为任务完成然后给出最终答案Final Answer。这个循环由 LLM 的推理能力驱动。我们通过给 LLM 一个包含可用工具描述和调用格式的 Prompt让它学会“思考-行动-观察”的模式。4. 第一步定义 Agent 的工具工具是 Agent 与外部世界交互的接口。每个工具都需要有清晰的名称、描述和参数定义这样 LLM 才能正确地选择和使用它。4.1 创建工具模块在项目根目录创建tools.py文件。# tools.pyfromlangchain.toolsimporttoolimportsubprocessimportosimportjsontooldefrun_shell_command(command:str)-str: 执行一个 shell 命令并返回输出结果。 适用于运行脚本、编译代码、查看文件等。 try:resultsubprocess.run(command,shellTrue,capture_outputTrue,textTrue,timeout30)outputresult.stdoutifresult.stderr:outputf\n[STDERR]\n{result.stderr}ifresult.returncode!0:outputf\n[Exit code:{result.returncode}]returnoutputexceptsubprocess.TimeoutExpired:return错误命令执行超时30秒exceptExceptionase:returnf错误执行命令时发生异常 -{str(e)}tooldefread_file(file_path:str)-str: 读取指定文件的全部内容。文件路径应为绝对路径或相对于当前工作目录的路径。 try:withopen(file_path,r,encodingutf-8)asf:contentf.read()returncontentexceptFileNotFoundError:returnf错误文件 {file_path} 未找到exceptExceptionase:returnf错误读取文件时发生异常 -{str(e)}tooldefwrite_file(file_path:str,content:str)-str: 将内容写入指定文件。如果文件不存在则创建如果存在则覆盖。 try:withopen(file_path,w,encodingutf-8)asf:f.write(content)returnf成功内容已写入 {file_path}exceptExceptionase:returnf错误写入文件时发生异常 -{str(e)}tooldeflist_directory(path:str.)-str: 列出指定目录下的文件和文件夹。 try:itemsos.listdir(path)result[]foriteminitems:full_pathos.path.join(path,item)ifos.path.isdir(full_path):result.append(f[DIR]{item})else:sizeos.path.getsize(full_path)result.append(f[FILE]{item}({size}bytes))return\n.join(result)ifresultelse目录为空exceptFileNotFoundError:returnf错误目录 {path} 未找到exceptExceptionase:returnf错误列出目录时发生异常 -{str(e)}关键点使用tool装饰器将函数标记为 LangChain 工具。函数的文档字符串docstring就是工具的描述LLM 会用它来决定何时调用此工具。参数的类型注解和名称也很重要LLM 会据此生成正确的参数。5. 第二步构建 Agent 核心现在我们来创建 Agent 的核心逻辑。创建agent.py文件。# agent.pyimportosfromdotenvimportload_dotenvfromlangchain_openaiimportChatOpenAIfromlangchain.agentsimportcreate_react_agent,AgentExecutorfromlangchain.promptsimportPromptTemplatefromtoolsimportrun_shell_command,read_file,write_file,list_directory# 加载环境变量load_dotenv()defcreate_agent(verbose:boolTrue): 创建并返回一个 AI Agent 执行器。 # 1. 初始化 LLMllmChatOpenAI(modelos.getenv(LLM_MODEL,gpt-4o-mini),temperature0,api_keyos.getenv(OPENAI_API_KEY),base_urlos.getenv(OPENAI_API_BASE),)# 2. 定义工具列表tools[run_shell_command,read_file,write_file,list_directory,]# 3. 创建 ReAct Agent# 使用一个清晰的 Prompt 模板来指导 Agent 的行为promptPromptTemplate.from_template(你是一个强大的 AI 助手可以通过思考和调用工具来帮助用户完成各种任务。 你拥有以下工具 {tools} 工具名称{tool_names} 请严格按照以下格式进行思考和行动 Thought: 描述你当前的想法和计划。 Action: 你要调用的工具名称必须是 [{tool_names}] 中的一个。 Action Input: 传递给工具的输入参数必须是一个有效的 JSON 对象。 Observation: 工具返回的结果。 ...重复 Thought/Action/Observation 循环 Thought: 我现在可以给出最终答案了。 Final Answer: 对用户问题的最终回答。 用户的问题是{input} 你的工作区是当前目录你可以自由地创建、读取和修改文件。 {agent_scratchpad} )# 4. 创建 Agentagentcreate_react_agent(llmllm,toolstools,promptprompt,)# 5. 创建 Agent 执行器agent_executorAgentExecutor(agentagent,toolstools,verboseverbose,# 打印思考过程handle_parsing_errorsTrue,# 处理 LLM 输出解析错误max_iterations15,# 防止无限循环)returnagent_executor代码解析create_react_agentLangChain 内置的 ReAct Agent 创建函数它自动处理了 Prompt 的组装和输出解析。AgentExecutor负责驱动 Agent 的思考-行动循环直到得到最终答案或达到最大迭代次数。verboseTrue在终端打印 Agent 的思考过程对调试和理解 Agent 行为非常有帮助。handle_parsing_errors当 LLM 输出格式不正确时自动重试提高鲁棒性。6. 第三步创建 CLI 交互界面现在我们把 Agent 封装成一个交互式命令行应用。创建cli.py文件。# cli.pyimportsysimportreadline# 提供命令行历史记录和编辑功能fromagentimportcreate_agentdefmain():print(*60)print( AI Agent CLI - 你的智能命令行助手)print( 输入你的问题Agent 将思考并调用工具来帮助你。)print( 输入 exit 或 quit 退出。)print(*60)# 创建 Agentprint(\n正在初始化 Agent...)agent_executorcreate_agent(verboseTrue)print(Agent 已就绪\n)whileTrue:try:# 获取用户输入user_inputinput(\n 你: ).strip()ifuser_input.lower()in[exit,quit,q]:print( 再见)breakifnotuser_input:continue# 调用 Agentprint(\n Agent 正在思考...\n)responseagent_executor.invoke({input:user_input})# 输出最终答案print(f\n Agent:{response[output]})exceptKeyboardInterrupt:print(\n\n 检测到中断再见)breakexceptExceptionase:print(f\n❌ 发生错误:{str(e)})if__name____main__:main()7. 运行与测试7.1 启动 CLI在终端运行python cli.py7.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库pipinstallduckduckgo-search在tools.py中添加fromlangchain.toolsimporttoolfromduckduckgo_searchimportDDGStooldefweb_search(query:str)-str: 使用 DuckDuckGo 搜索互联网。当你需要获取最新信息或查找资料时使用。 try:withDDGS()asddgs:resultslist(ddgs.text(query,max_results5))ifnotresults:return未找到相关结果formatted[]fori,rinenumerate(results,1):formatted.append(f{i}.{r[title]}\n{r[href]}\n{r[body]})return\n\n.join(formatted)exceptExceptionase:returnf搜索失败:{str(e)}然后在agent.py的tools列表中加入这个新工具。8.2 添加代码执行沙箱为了安全地执行用户代码可以使用 Docker 容器。这里提供一个简单的本地 Python 执行工具注意安全风险tooldefrun_python_code(code:str)-str: 执行一段 Python 代码并返回输出。适用于快速验证算法或数据处理。 注意此工具会直接执行代码请确保代码来源可信。 try:importioimportsysfromcontextlibimportredirect_stdout,redirect_stderr f_stdoutio.StringIO()f_stderrio.StringIO()withredirect_stdout(f_stdout),redirect_stderr(f_stderr):exec(code,{__builtins__:__builtins__})outputf_stdout.getvalue()iff_stderr.getvalue():outputf\n[STDERR]\n{f_stderr.getvalue()}returnoutputifoutputelse代码执行成功无输出。exceptExceptionase:returnf代码执行错误:{str(e)}8.3 添加记忆能力默认情况下Agent 每次调用都是独立的。要让它记住对话历史可以添加记忆组件# agent.py 修改fromlangchain.memoryimportConversationBufferMemoryfromlangchain.agentsimportcreate_react_agent,AgentExecutordefcreate_agent_with_memory(verbose:boolTrue):# ... 初始化 llm 和 tools ...memoryConversationBufferMemory(memory_keychat_history,return_messagesTrue)agent_executorAgentExecutor(agentagent,toolstools,verboseverbose,handle_parsing_errorsTrue,max_iterations15,memorymemory,# 添加记忆)returnagent_executor9. 完整项目结构ai-agent-cli/ ├── .env # 环境变量API Key 等 ├── .gitignore # Git 忽略文件 ├── cli.py # 命令行交互入口 ├── agent.py # Agent 核心逻辑 ├── tools.py # 工具定义 └── requirements.txt # 依赖列表requirements.txt内容langchain0.3.0 langchain-openai0.2.0 openai1.0.0 python-dotenv1.0.0 duckduckgo-search6.0.0 # 可选用于 Web 搜索10. 总结与下一步恭喜你已经从零实现了一个功能完整的 AI Agent CLI。这个 Agent 能够理解自然语言指令自主规划并调用工具执行命令、读写文件、搜索网络通过思考-行动循环完成复杂任务在终端中提供交互式体验下一步你可以探索的方向支持更多 LLM通过 LangChain 的模型抽象可以轻松切换为 Claude、Gemini 或本地模型如 Ollama。添加更多工具数据库查询、API 调用、Git 操作等。改进用户体验添加流式输出、进度条、彩色输出等。安全沙箱使用 Docker 或子进程隔离来安全执行代码。持久化记忆将对话历史保存到文件或数据库。多 Agent 协作创建多个专业 Agent如代码 Agent、搜索 Agent协同工作。这个 CLI 框架为你提供了一个坚实的基础你可以根据自己的需求不断扩展和优化它。现在打开终端开始构建你的 AI Agent 吧
