尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从零构建AI智能体:基于LangChain与Spring AI的工程实践指南

从零构建AI智能体:基于LangChain与Spring AI的工程实践指南 在实际技术项目中AI 智能体AI Agent已经从概念走向了工程实践。它不再仅仅是聊天机器人而是能够感知环境、规划决策、执行工具调用并持续学习的自主程序。对于开发者而言理解如何从零搭建一个具备基础能力的智能体是进入这一领域的关键一步。本文将以一个可运行的“AI 小镇”模拟项目为切入点带你理解智能体的核心组件、工作流程并动手实现一个简单的智能体系统。无论你是想探索智能体开发还是希望将 AI 能力集成到现有业务中本文提供的从环境搭建、框架选择到代码实现和问题排查的完整路径都将为你提供一个坚实的起点。我们将围绕一个开源模拟项目拆解智能体的感知、决策、行动与学习循环。你会了解到如何选择合适的框架如 LangChain、Spring AI如何设计智能体的记忆与工具调用机制以及如何处理开发中常见的“幻觉”Hallucination、工具调用失败等问题。最终你将获得一个可以本地运行、观察其行为的智能体原型并掌握将其扩展为更复杂应用如自动化测试、合规检测的基本方法。1. 理解 AI 智能体的核心架构与工作循环在开始编码之前必须厘清智能体Agent与普通调用大模型 API 的程序有何本质区别。简单来说一个普通程序是“你问模型答”而智能体是“你给目标它自己想办法完成”。这背后的核心是一个经典的“感知-思考-行动”循环在工程上通常体现为几个关键组件。1.1 智能体与简单提示工程的区别很多人接触 AI 应用是从写提示词Prompt开始的例如让模型总结一段文本。这属于“零样本”或“少样本”提示模型根据当前输入直接生成输出没有状态记忆也没有外部工具调用能力。智能体则在此基础上增加了几个维度状态与记忆Memory智能体能记住之前的对话历史、执行过的操作及其结果从而在后续决策中保持上下文连贯性。这通常通过向量数据库、普通数据库或简单的会话缓存来实现。工具调用Tool Calling智能体可以理解用户指令并决定调用哪个外部工具如计算器、搜索引擎、数据库查询、API来获取信息或执行操作。这是智能体扩展能力边界的关键。规划与决策Planning对于复杂任务智能体需要将其分解为多个子步骤并决定执行顺序。这通常由大模型本身的推理能力或外部的规划器Planner模块完成。学习与反思Learning/Reflection高级智能体能够从历史行动的结果中学习评估行动的有效性并在未来遇到类似情况时调整策略。以一个“查询天气并建议穿衣”的任务为例简单提示用户输入“北京今天天气如何我该穿什么”模型基于训练数据生成一个笼统的回答。智能体1. 感知到用户问题2. 思考后决定先调用“天气查询工具”获取北京实时温度、湿度3. 根据工具返回的具体数据结合“穿衣知识库”进行推理4. 生成包含具体温度和建议的回复。如果用户追问“明天呢”它能记住刚才查询的是北京并继续调用工具。1.2 典型智能体框架的组件映射目前主流的智能体开发框架如 LangChain、LlamaIndex、Spring AI都将上述抽象概念封装成了可编程的组件。了解这些组件有助于你选择适合的工具。组件功能描述在 LangChain 中的对应在 Spring AI 中的对应Agent智能体核心协调其他组件工作。AgentExecutorAgent接口及其实现LLM大语言模型提供推理和生成能力。ChatOpenAI,ChatAnthropic等ChatClient(OpenAI, Azure, Ollama)Tools可供智能体调用的外部函数或API。Tool注解修饰的函数或BaseTool子类Tool接口实现类Memory存储和检索对话历史、工具调用结果。ConversationBufferMemory,VectorStoreRetrieverMemoryChatMemory接口实现Prompt Template定义引导智能体行为的系统提示词。ChatPromptTemplatePromptTemplateOutput Parser解析模型输出将其转换为结构化数据如工具调用指令。JsonOutputParser,StructuredOutputParser通常内置于 Agent 实现中开源项目“AI 小镇”如mewamew/my_ai_town这类模拟社会实验通常是多个智能体在共享环境中交互的复杂系统。它放大了单个智能体的架构每个居民是一个智能体小镇环境是共享状态居民间的对话是工具调用信息交换长期目标如成为艺术家是规划任务。研究这类项目能帮你理解多智能体协作和更复杂的记忆、规划机制。2. 环境准备与开发框架选型在动手实现之前需要搭建一个稳定的开发环境并选择适合你技术栈的框架。本节将提供两种主流路线的准备方案。2.1 基础开发环境配置无论选择哪种框架以下环境是通用的Python 环境推荐使用 Python 3.10 或 3.11。使用conda或venv创建独立的虚拟环境是最佳实践。# 使用 conda 创建环境 conda create -n ai-agent python3.11 conda activate ai-agent # 或使用 venv python -m venv venv # Windows .\venv\Scripts\activate # Linux/Mac source venv/bin/activate大模型访问权限你需要一个能够访问的大语言模型 API。对于学习和原型开发有以下选择OpenAI GPT 系列稳定工具调用能力强但需付费。开源本地模型如通过Ollama运行Llama 3、Qwen或DeepSeek等模型。免费但对本地硬件有要求。国内大模型 API如智谱、月之暗面、百度文心等需注册获取 API Key。将 API Key 设置为环境变量避免硬编码在代码中# Linux/Mac export OPENAI_API_KEYyour-api-key-here # Windows (PowerShell) $env:OPENAI_API_KEYyour-api-key-here2.2 框架选型LangChain vs Spring AI根据你的主要开发语言和项目背景可以选择不同的技术栈。Python 路线LangChainLangChain 是当前生态最丰富的智能体开发框架社区活跃教程和示例众多。它非常适合快速原型验证和学术研究。# 安装核心库及OpenAI集成 pip install langchain langchain-openai # 如果需要使用更多社区工具或记忆存储 pip install langchain-community langchain-chroma注意LangChain 模块拆分较细建议根据项目需要逐步安装避免依赖冲突。Java 路线Spring AI如果你所在团队主要技术栈是 Java或者项目需要集成到现有的 Spring Boot 微服务中Spring AI 是官方支持的良好选择。它提供了统一的ChatClientAPI 来对接不同模型并内置了智能体、向量库等模块。 在pom.xml中添加依赖dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version0.8.1/version !-- 请使用最新稳定版 -- /dependency然后在application.yml中配置spring: ai: openai: api-key: ${OPENAI_API_KEY} chat: options: model: gpt-4o-mini选型建议快速学习、验证想法、数据科学背景优先选择LangChain (Python)。企业级应用、需要集成现有 Java 后端、强调工程规范优先选择Spring AI (Java)。其他Dify、Coze等平台属于低代码/无代码智能体搭建平台适合非开发者快速构建应用但定制性和底层控制力较弱。Cursor等 AI 编程助手是开发工具而非智能体开发框架。本文后续示例将以LangChain (Python)为主因为其受众更广概念演示更直观。Spring AI 的思路基本一致只是 API 不同。3. 从零构建一个基础智能体天气查询助手我们将构建一个能够理解用户意图、调用天气查询工具并给出建议的智能体。这个例子涵盖了智能体最核心的要素。3.1 项目结构与依赖创建一个新的项目目录结构如下weather_agent/ ├── tools/ │ └── weather_tools.py # 工具定义 ├── agents/ │ └── weather_agent.py # 智能体定义与执行 ├── main.py # 主程序入口 └── requirements.txtrequirements.txt内容langchain0.1.0 langchain-openai0.0.5 requests2.31.0 python-dotenv1.0.03.2 第一步定义工具Tools工具是智能体能力的延伸。这里我们定义一个模拟的天气查询工具。在实际项目中你可以替换为真实的天气 API。tools/weather_tools.py:from langchain.tools import tool import requests tool def get_current_weather(location: str) - str: 根据城市名获取当前的天气信息。 Args: location: 城市名称例如“北京”、“上海”。 Returns: 一个描述天气的字符串。 # 注意这是一个模拟函数。真实情况应调用如和风天气、OpenWeatherMap等API。 # 这里为了演示返回固定格式的模拟数据。 print(f[工具调用] 正在查询 {location} 的天气...) # 模拟API调用延迟 import time time.sleep(0.5) # 模拟不同城市的返回 weather_data { 北京: 晴朗温度 25°C微风湿度 40%。, 上海: 多云温度 28°C东南风2级湿度 65%。, 广州: 阵雨温度 30°C南风3级湿度 80%。, } return weather_data.get(location, f未找到 {location} 的天气信息。目前模拟数据仅支持{list(weather_data.keys())}) # 可以定义更多工具如穿衣建议工具、湿度查询工具等。 # tool # def get_clothing_advice(temperature: int, conditions: str) - str: # ...关键点使用tool装饰器将普通函数声明为 LangChain 可识别的工具。函数的文档字符串非常重要大模型会阅读它来理解工具的用途和参数。描述必须清晰准确。工具应返回字符串或可序列化的数据以便智能体理解。3.3 第二步构建智能体Agent我们将使用 LangChain 的create_react_agent来构建一个智能体。ReAct 是一个经典的智能体推理框架Reason Act。agents/weather_agent.py:import os from langchain import hub from langchain.agents import create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from tools.weather_tools import get_current_weather def build_weather_agent(): 构建并返回一个天气查询智能体的执行器。 # 1. 初始化大模型 # 确保环境变量 OPENAI_API_KEY 已设置 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 如果使用本地模型例如通过 Ollama # from langchain_community.llms import Ollama # llm Ollama(modelllama3) # 2. 定义智能体可用的工具列表 tools [get_current_weather] # 3. 从 LangChain Hub 拉取一个预设的 ReAct 提示词模板 # 这个模板会指导模型按照“思考 - 行动 - 观察”的循环工作 prompt hub.pull(hwchase17/react) # 4. 创建智能体 agent create_react_agent(llm, tools, prompt) # 5. 创建智能体执行器它负责运行循环处理工具调用 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 开启详细日志便于调试 handle_parsing_errorsTrue, # 优雅处理模型输出解析错误 max_iterations5, # 限制最大循环次数防止死循环 early_stopping_methodgenerate # 当模型认为任务完成时停止 ) return agent_executor if __name__ __main__: # 本地测试 agent_executor build_weather_agent() result agent_executor.invoke({input: 北京和上海的天气怎么样}) print(\n--- 最终回答 ---) print(result[output])代码解释ChatOpenAI: 封装了与 OpenAI API 的交互。temperature0使输出更确定适合工具调用。create_react_agent: 将模型、工具和提示词模板组合成一个智能体对象。AgentExecutor: 这是智能体的“发动机”。它运行 ReAct 循环将用户输入和上下文传给模型 - 模型返回思考结果和工具调用请求 - 执行器调用工具 - 将工具结果作为“观察”再次传给模型 - 直到模型生成最终答案。verboseTrue这是学习阶段最重要的参数它会打印出智能体内部的思考链Chain of Thought让你看清它是如何决策的。3.4 第三步运行与验证创建主程序入口main.pyfrom dotenv import load_dotenv from agents.weather_agent import build_weather_agent # 加载 .env 文件中的环境变量如果你把 API KEY 放在 .env 文件里 load_dotenv() def main(): print(初始化天气查询智能体...) agent build_weather_agent() while True: try: user_input input(\n请输入您的问题 (或输入 quit 退出): ) if user_input.lower() in [quit, exit, q]: print(再见) break if not user_input.strip(): continue print(f\n用户: {user_input}) print(- * 50) result agent.invoke({input: user_input}) print(- * 50) print(f智能体: {result[output]}) except KeyboardInterrupt: print(\n程序被中断。) break except Exception as e: print(f\n发生错误: {e}) if __name__ __main__: main()运行程序python main.py输入“北京今天天气如何”观察控制台输出。你应该能看到类似以下的详细日志verboseTrue的效果 进入新的 AgentExecutor 链... 思考用户想知道北京的天气我需要使用天气查询工具。 行动get_current_weather 行动输入{location: 北京} [工具调用] 正在查询 北京的天气... 观察晴朗温度 25°C微风湿度 40%。 思考我已经获取了北京的天气信息可以直接回答用户。 最终答案北京今天的天气是晴朗温度 25°C微风湿度 40%。 链结束。这表明智能体成功完成了“思考-行动-观察-再思考-回答”的完整循环。4. 核心机制详解与高级配置一个可用的基础智能体已经搭建完成但要使其健壮、可靠需要深入理解其内部机制并进行配置。4.1 智能体的“思考”过程ReAct 提示词剖析LangChain Hub 上的hwchase17/react提示词模板是智能体行为的“宪法”。其核心结构如下简化你是一个有帮助的助手可以使用以下工具 {tools} 使用以下格式回答 问题用户输入的问题 思考你需要一步步思考。如果需要使用工具就在这里决定用哪个工具。 行动要调用的工具名必须是 [{tool_names}] 中的一个。 行动输入工具的输入必须是有效的 JSON 格式。 观察工具返回的结果 ... (这个“思考/行动/行动输入/观察”循环可以重复多次) 思考我现在知道了最终答案。 最终答案对用户问题的最终回答。这个模板强制模型以结构化格式输出方便AgentExecutor解析。{tools}和{tool_names}会在运行时被替换为你定义的工具列表和名称。4.2 记忆Memory的集成上面的例子是“无状态”的每次对话都是独立的。为了让智能体记住上下文需要集成记忆组件。 修改agents/weather_agent.py中的build_weather_agent函数from langchain.memory import ConversationBufferMemory def build_weather_agent_with_memory(): llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) tools [get_current_weather] prompt hub.pull(hwchase17/react) # 1. 创建记忆对象 memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 2. 修改提示词模板加入记忆变量 # ReAct 提示词本身不直接支持历史我们可以自定义或使用其他支持记忆的Agent类型如conversational-react-description # 这里为了演示我们改用另一种方式 from langchain.agents import initialize_agent, AgentType agent_executor initialize_agent( tools, llm, agentAgentType.CONVERSATIONAL_REACT_DESCRIPTION, # 专为对话设计的Agent类型 verboseTrue, memorymemory, # 传入记忆 max_iterations3, handle_parsing_errorsTrue, ) return agent_executor现在当你连续问“北京天气怎么样”和“那我该穿什么”时智能体会记得之前的对话地点是北京从而在后续回答中保持连贯。4.3 处理“AI 幻觉”与工具调用失败“AI 幻觉”Hallucination指模型生成不准确或虚构信息。在智能体场景中幻觉可能导致它调用不存在的工具或传入错误参数。常见问题1模型不调用工具直接编造答案现象用户问“北京温度多少”模型直接回答“北京气温大约20度”而没有调用get_current_weather工具。原因提示词指令不够强或者模型在训练数据中“见过”类似问题倾向于直接生成。解决强化工具描述在工具的文档字符串中明确写出“你必须使用此工具来获取准确的天气信息不要凭空猜测”。调整提示词在系统提示词中强调“对于任何涉及天气的问题你必须使用get_current_weather工具”。使用更强的模型GPT-4 在工具调用遵循指令上通常优于 GPT-3.5。常见问题2工具调用参数格式错误现象日志显示Action Input: 北京一个字符串但工具期望{location: 北京}一个JSON对象。原因模型没有严格按照 JSON 格式输出。解决确保提示词模板中明确要求“必须是有效的 JSON 格式”。使用handle_parsing_errorsTrue让执行器在解析失败时尝试修复或提示模型重试。使用支持“结构化输出”Structured Output的模型或使用JsonOutputParser对模型输出进行后处理。常见问题3智能体陷入死循环现象智能体反复调用同一个工具无法得出最终答案。原因工具返回的结果可能无法让模型满意或者模型逻辑陷入循环。解决设置max_iterations如5次强制限制循环次数。优化工具返回的信息使其更清晰、更具结论性。检查提示词中“最终答案”的触发条件是否明确。5. 生产环境考量与最佳实践将智能体从演示原型推向生产环境需要关注稳定性、安全性和可维护性。5.1 配置管理切勿将 API Key 等敏感信息硬编码在代码中。使用环境变量或专业的配置管理工具如python-dotenv Spring Cloud Config。# .env 文件 OPENAI_API_KEYsk-... OPENAI_BASE_URLhttps://api.openai.com/v1 # 如果使用代理 WEATHER_API_KEYyour-real-weather-key# 在代码中读取 import os api_key os.getenv(OPENAI_API_KEY) if not api_key: raise ValueError(请在 .env 文件中设置 OPENAI_API_KEY)5.2 日志与监控生产环境必须关闭verboseTrue但需要将智能体的决策日志记录到文件或日志系统中以便排查问题。import logging logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) # 可以自定义回调函数来记录关键事件 from langchain.callbacks import StdOutCallbackHandler from langchain.callbacks.base import BaseCallbackHandler class CustomCallbackHandler(BaseCallbackHandler): def on_agent_action(self, action, **kwargs): logger.info(f智能体行动: {action.log}) # 在创建 AgentExecutor 时传入 agent_executor AgentExecutor(..., callbacks[CustomCallbackHandler()])5.3 安全与合规这是企业级应用的重中之重。工具权限控制不是所有工具都对所有用户开放。需要建立用户-工具权限映射在执行前进行校验。输入输出过滤与审核对用户输入和模型输出进行内容安全过滤防止生成有害、偏见或敏感信息。数据隐私确保用户对话数据、通过工具查询的业务数据符合隐私法规如 GDPR。考虑对数据进行脱敏或使用本地化模型。速率限制与熔断对调用大模型 API 和内部工具的频率进行限制防止滥用或意外高负载拖垮系统。5.4 性能优化缓存对频繁且结果不变的查询如某些天气信息、知识库问答实施缓存减少不必要的模型调用和工具调用降低成本与延迟。异步调用如果智能体需要并行调用多个独立工具使用异步模式如 LangChain 的ainvoke可以显著提升响应速度。模型选型在精度和成本间权衡。简单的工具路由任务可以使用更小、更快的模型如gpt-3.5-turbo复杂的规划推理则可能需要gpt-4。6. 扩展方向从单智能体到复杂应用掌握了基础智能体搭建后你可以向以下几个方向深入探索1. 多智能体系统如 AI 小镇研究mewamew/my_ai_town这类项目学习如何让多个智能体共享环境、通过消息传递进行协作与竞争。关键点在于设计智能体间的通信协议和共享状态管理。2. 智能体工作流Workflow对于需要严格步骤的任务如数据处理流水线可以将多个智能体或工具按固定顺序组织成工作流。Coze 扣子、Dify等平台的可视化工作流设计器就是此概念的体现。在代码中你可以用LangChain Expression Language (LCEL)或普通编程逻辑来编排。3. 智能体与专业领域结合AI 编程助手类似Cursor、GitHub Copilot智能体可以理解代码上下文调用代码解析、搜索、生成、测试等工具。智能体测试让智能体模拟用户操作 UI或根据 API 文档自动生成并执行测试用例。合规自动化检测如输入材料中提到的“企业级 AI 智能体安全合规自动化检测系统”智能体可以调用代码扫描、配置检查、漏洞库查询等工具自动化完成安全审计的一部分工作。4. 处理复杂工具与长上下文当工具数量众多或文档复杂时需要为智能体配备“工具检索”能力即先根据用户问题从工具库中筛选出最相关的几个再让模型决定调用哪一个。这通常结合向量数据库Vector Store和检索增强生成RAG技术来实现。构建 AI 智能体的旅程始于一个简单的工具调用循环但通往一个能可靠处理复杂任务、安全合规、易于维护的生产系统还需要在架构设计、异常处理、监控运维上投入大量工程努力。建议从本文的小例子出发逐个攻克记忆、规划、多智能体协作等进阶课题并始终将测试和验证作为开发流程的核心环节。
返回列表