1. 项目概述AI智能体入门指南最近几年AI领域最让人兴奋的进展之一就是“智能体”概念的兴起。你可能已经用过ChatGPT这样的聊天机器人它们能回答问题、写邮件、生成代码这已经很厉害了。但智能体更进一步它不再是简单地“一问一答”而是能够自主规划、使用工具、执行复杂任务甚至持续学习的AI实体。想象一下你只需要告诉它“帮我分析一下上个月的销售数据找出问题并写一份报告”它就能自己去数据库拉取数据、用Python做分析、生成图表最后整理成一份PPT发给你。这就是智能体的潜力。微软在GitHub上开源的“AI Agents for Beginners”项目就是一个绝佳的起点。这个项目不是又一个高深莫测、满是数学公式的研究论文仓库而是一个面向开发者和初学者的、手把手的实践教程。它的核心目标非常明确用最直观的方式带你从零开始亲手构建和运行一个能真正“干活”的AI智能体。无论你是对AI充满好奇的学生还是希望将AI能力集成到产品中的开发者这个项目都提供了一个结构清晰、代码可运行的“游乐场”。这个项目解决的痛点非常实际市面上关于智能体的概念讨论很多但具体“怎么做”的、能跑起来的例子却很少。很多教程要么过于理论化要么环境配置复杂到让人望而却步。“AI Agents for Beginners”则反其道而行它假设你只有基础的Python知识然后一步步引导你搭建环境、理解核心概念、编写代码最终让你看到自己的智能体是如何思考、规划和执行任务的。它就像一本带有详细实验步骤的教科书让你在动手的过程中真正理解智能体背后的运作机制比如智能体是如何被“提示”驱动的如何与外部工具API、数据库交互以及如何管理自己的“记忆”以进行多轮复杂对话。2. 智能体的核心架构与工作原理拆解在开始敲代码之前我们必须先搞清楚智能体到底是什么以及它是如何“思考”和“行动”的。如果把传统的聊天AI比作一个知识渊博但手脚被绑住的顾问那么智能体就是一个被赋予了“手脚”和“记事本”的自主员工。2.1 智能体与传统AI模型的本质区别传统的AI模型比如用于文本生成的GPT系列其工作模式是“刺激-反应”。你输入一段提示模型基于其训练数据预测并生成最可能的下一个词序列作为回复。它没有持久的目标没有对自身状态的认知也不会主动调用外部资源。它的“世界”仅限于你提供的输入文本。而智能体则构建了一个感知-思考-行动的循环。这个循环是智能体架构的核心感知接收来自用户或环境的输入比如用户的指令“查看北京明天天气”。思考基于输入、自身的目标和记忆进行推理和规划“用户想知道天气我需要调用天气API。要调用API我需要知道城市‘北京’和日期‘明天’。我拥有调用天气API的工具。”。行动根据思考结果执行一个动作。这个动作可以是生成一段文本回复但更多时候是调用一个工具比如执行一段代码get_weather(“北京”, “tomorrow”)。观察获取行动的结果API返回了“北京明天晴15-25°C”。然后智能体会将这个结果作为新的“感知”进入下一个循环直到任务完成最终回复用户“北京明天晴天气温15到25摄氏度。”。这个循环的关键在于“工具使用”。工具是智能体延伸自身能力的手臂。一个只会聊天的模型能力受限于其训练数据。而一个会使用工具的智能体其能力边界是无限的——它可以通过工具访问实时信息搜索引擎、股票API、操作外部系统发送邮件、控制智能家居、进行复杂计算运行代码、查询数据库。2.2 智能体系统的关键组件一个完整的智能体系统通常包含以下几个核心组件理解它们对后续的编程至关重要大脑LLM - 大语言模型这是智能体的“思考”中枢。它负责理解用户意图、进行逻辑推理、制定计划、决定下一步该调用哪个工具。项目中通常会使用像GPT-4、Claude或开源的Llama系列模型作为大脑。LLM并不直接“知道”如何调用工具它通过我们提供的“提示”来学习。工具Tools这是智能体的“手脚”。一个工具本质上是一个函数它有明确的名称、描述和输入参数。例如get_current_time()一个无参数工具返回当前时间。search_web(query: str)一个需要搜索词作为参数的工具返回搜索结果。calculate_bmi(weight_kg: float, height_m: float)计算身体质量指数。 智能体的大脑LLM会根据工具的描述来决定在何时、使用何种参数来调用它们。提示工程Prompt Engineering这是指挥智能体大脑的“指令手册”。我们需要在给LLM的提示中清晰地定义系统角色你是谁“你是一个乐于助人的AI助手。”能力描述你能做什么“你可以通过调用工具来获取实时信息或进行计算。”工具列表详细描述每个工具是干什么的、怎么用。行动格式要求LLM以特定的结构化格式通常是JSON来输出它的“思考”和“行动”决定以便程序能够解析。 一个设计良好的提示是智能体正确工作的前提。项目中的大部分代码其实都是在构建和优化这个提示。记忆Memory为了让智能体能处理多轮对话和复杂任务它需要记忆。记忆分为几种短期记忆/对话历史记住当前会话中用户和AI说过的所有话。这是最基本的。长期记忆可能是一个向量数据库存储智能体学到的关于用户或世界的持久化信息例如“用户张三喜欢喝黑咖啡”。摘要记忆在长对话后将历史对话总结成一段摘要既保留了关键信息又避免了提示过长。 记忆管理是构建实用智能体的挑战之一因为LLM有上下文长度限制不能无限制地记住所有对话。执行引擎Agent Executor这是驱动整个“感知-思考-行动”循环的“调度器”。它的工作是接收用户输入将其与记忆组合成完整的提示发送给LLM解析LLM的回复判断是直接回答还是调用工具如果调用工具则找到对应的函数并执行将工具执行结果和新的用户输入再次组合送入下一个循环直到LLM输出最终答案。微软的“AI Agents for Beginners”项目正是通过具体的代码示例向你展示如何将这些组件像搭积木一样组合起来构建出不同能力的智能体。注意智能体不是魔法。它的所有“智能”都源于LLM的推理能力和你为其精心设计的工具与提示。它可能会“胡言乱语”幻觉可能会错误地选择工具。因此构建健壮的智能体需要大量的测试、提示迭代和错误处理机制。3. 环境搭建与核心工具链实战理论说得再多不如动手跑一行代码。微软的这个项目非常贴心地降低了入门门槛。我们不需要从零开始搭建所有轮子而是站在像LangChain或Semantic Kernel这样的优秀框架的肩膀上。这些框架已经将智能体的核心组件大脑、工具、记忆、执行循环封装好了我们只需要进行“配置”和“组装”。3.1 开发环境与框架选型对于初学者我强烈建议按照项目的指引从最简化的环境开始。第一步准备Python环境。我个人的习惯是使用conda或venv创建独立的虚拟环境避免包版本冲突。这是保证项目可复现的第一步。# 使用 conda conda create -n ai-agents python3.10 conda activate ai-agents # 或使用 venv python -m venv ai-agents-env # Windows ai-agents-env\Scripts\activate # macOS/Linux source ai-agents-env/bin/activate第二步选择智能体框架。项目可能会介绍多个框架对于纯新手我建议先从LangChain开始。原因如下生态成熟LangChain社区极大教程、示例和第三方工具集成最多遇到问题容易找到解决方案。抽象层次适中它既提供了高级的、快速上手的“Agent”接口也允许你深入到底层定制每一个环节。“AI Agents for Beginners”项目本身很可能就以LangChain为主要示例。安装核心包pip install langchain langchain-openai这里langchain是核心框架langchain-openai是用于连接OpenAI API的适配器。如果你打算使用开源模型如通过Ollama本地运行Llama3则需要安装对应的包如langchain-community和ollama。第三步获取大模型API密钥。你需要一个“大脑”。最方便的是使用云服务如OpenAI的GPT或Anthropic的Claude。去对应平台注册账号获取API Key。请务必妥善保管此密钥不要上传到公开的代码仓库通常的做法是将其设置为环境变量。# 在终端中设置临时 export OPENAI_API_KEY你的-sk-xxx密钥 # 或在代码中通过python-dotenv加载3.2 构建你的第一个工具并让智能体使用它现在让我们抛开复杂的理论直接创建一个最简单的智能体它只有一个功能查天气。我们会亲手定义一个“天气查询工具”然后看智能体如何学会使用它。1. 定义工具函数工具就是一个普通的Python函数但我们需要用装饰器或类来告诉LangChain这是一个工具。# weather_agent.py from langchain.agents import tool import requests # 使用 tool 装饰器定义一个工具。描述至关重要LLM靠它来理解工具用途。 tool def get_weather(city: str) - str: 根据城市名称查询当前天气情况。 Args: city: 城市名例如 北京、New York。 Returns: 字符串格式的天气信息。 # 注意这里为了示例我们模拟一个API调用。 # 在实际应用中你应该替换为真实的天气API如OpenWeatherMap。 # 真实API通常需要密钥并且返回JSON我们需要解析。 print(f[工具调用] 正在查询{city}的天气...) # 打印日志方便观察 # 模拟API返回 weather_data { 北京: 北京当前天气晴温度22°C微风。, 上海: 上海当前天气多云温度25°C东南风3级。, New York: New York current weather: Partly cloudy, 18°C. } return weather_data.get(city, f抱歉未找到{city}的天气信息。) # 让我们测试一下工具本身是否工作 if __name__ __main__: print(get_weather.invoke(北京))运行这个脚本你应该能看到输出[工具调用] 正在查询北京的天气...和北京当前天气晴温度22°C微风。。这说明工具函数本身没问题。2. 创建智能体并赋予它工具接下来我们将这个工具、一个LLM大脑和一套执行逻辑组装成智能体。# 续上 weather_agent.py from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # 1. 初始化LLM大脑 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0, openai_api_key你的API_KEY) # temperature0 使输出更确定适合执行任务。 # 2. 准备工具列表 tools [get_weather] # 3. 获取一个预设的提示模板。ReAct是一个经典的智能体推理框架。 prompt hub.pull(hwchase17/react) # 4. 创建智能体 agent create_react_agent(llm, tools, prompt) # 5. 创建执行器它负责运行循环 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) # verboseTrue 会打印出详细的思考过程对调试至关重要 # handle_parsing_errorsTrue 能处理LLM输出格式错误的情况避免程序崩溃。 # 6. 运行智能体 print( 智能体对话开始 ) try: result agent_executor.invoke({input: 北京和上海的天气怎么样}) print(\n 最终回答 ) print(result[output]) except Exception as e: print(f执行出错: {e})3. 运行并观察“思考过程”当你运行上面的完整代码时如果verboseTrue你会在控制台看到类似下面的输出这是智能体“内心独白”的展现 智能体对话开始 进入新的AgentExecutor链... 我需要同时知道北京和上海的天气。我可以分别查询这两个城市。 动作: get_weather 动作输入: {city: 北京} [工具调用] 正在查询北京的天气... 观察: 北京当前天气晴温度22°C微风。 我现在需要查询上海的天气。 动作: get_weather 动作输入: {city: 上海} [工具调用] 正在查询上海的天气... 观察: 上海当前天气多云温度25°C东南风3级。 我现在有了两个城市的信息可以总结回答了。 动作: 最终答案 动作输入: 北京当前天气晴朗气温22摄氏度微风。上海当前多云气温25摄氏度东南风3级。 链结束。 最终回答 北京当前天气晴朗气温22摄氏度微风。上海当前多云气温25摄氏度东南风3级。看智能体并没有被“北京和上海的天气怎么样”这个复合问题难倒。它自主地将问题拆解成两个子任务“查询北京天气”和“查询上海天气”然后依次调用了两次get_weather工具最后将结果汇总给出了一个完整的回答。这就是智能体规划能力和工具使用能力的直观体现。实操心得第一次运行成功会带来巨大的成就感。关键点在于1)工具描述要清晰tool下的文档字符串是给LLM看的务必准确描述功能、参数和返回值。2)打开verbose模式这是理解智能体工作逻辑、调试错误的最重要手段。3)处理好错误handle_parsing_errorsTrue能避免因LLM输出格式意外而导致的程序中断在实际开发中你需要更完善的错误处理机制。4. 从单一工具到多工具协作构建功能复合型智能体只会查天气的智能体只是个开始。真正的价值在于让智能体能够根据复杂任务自主选择并组合多个工具。这就好比给你的员工配备了整个工具箱而不仅仅是一把锤子。4.1 设计一个多工具智能体计算与信息查询让我们升级智能体赋予它更多能力。假设我们要构建一个“个人健康与信息助手”它需要能计算BMI身体质量指数。能查询单词释义模拟词典功能。当然还能查天气。我们将创建三个工具并观察智能体如何决策。# multi_tool_agent.py from langchain.agents import tool, create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from langchain import hub import math # 工具1: 计算BMI tool def calculate_bmi(weight_kg: float, height_m: float) - str: 计算身体质量指数。需要提供体重公斤和身高米。 bmi weight_kg / (height_m ** 2) category 偏瘦 if bmi 18.5 else 正常 if bmi 24 else 偏胖 if bmi 28 else 肥胖 return f您的BMI指数为{bmi:.1f}属于{category}范围。 # 工具2: 查询单词释义模拟 tool def lookup_word(word: str) - str: 查询英文单词的中文释义。 dictionary { algorithm: 算法解决问题的一系列步骤或规则。, agent: 智能体能感知环境并自主行动的实体。, neural network: 神经网络受人脑启发的一种机器学习模型。 } meaning dictionary.get(word.lower()) return meaning if meaning else f未找到单词 {word} 的释义。 # 工具3: 查询天气复用之前的稍作修改 tool def get_weather(city: str) - str: 根据城市名称查询当前天气情况。 weather_data {Beijing: 晴朗15°C, London: 多云10°C, Tokyo: 小雨18°C} info weather_data.get(city) return f{city}的天气是{info} if info else f抱歉暂无{city}的天气信息。 # 主程序 def main(): llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) tools [calculate_bmi, lookup_word, get_weather] prompt hub.pull(hwchase17/react) agent create_react_agent(llm, tools, prompt) executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) # 测试用例1复合任务 print(测试1: 复合任务) result1 executor.invoke({input: 我体重70公斤身高1.75米我的BMI是多少另外‘algorithm’这个词是什么意思}) print(f回答: {result1[output]}\n) # 测试用例2需要推理的任务 print(测试2: 需要推理的任务) result2 executor.invoke({input: 如果我在伦敦应该穿什么衣服}) print(f回答: {result2[output]}\n) # 测试用例3模糊任务 print(测试3: 模糊任务) result3 executor.invoke({input: 告诉我关于神经网络和东京的一些信息。}) print(f回答: {result3[output]}) if __name__ __main__: main()运行这个程序你会看到智能体精彩的决策过程对于测试1它会识别出两个独立子任务依次调用calculate_bmi和lookup_word工具。对于测试2这是一个隐含任务。用户没直接说“查天气”但智能体基于常识推理出“决定穿什么需要知道天气”从而主动调用get_weather工具获取伦敦天气再生成穿衣建议。对于测试3任务更模糊。智能体需要理解“关于神经网络的信息”可能指向单词释义“关于东京的信息”可能指向天气或百科本例中只有天气工具。它会尝试调用lookup_word(“neural network”)和get_weather(“Tokyo”)。4.2 工具描述与智能体决策的微妙关系智能体选择哪个工具完全依赖于LLM对工具描述和用户问题的匹配理解。这里有几个关键经验描述要具体且独特如果两个工具描述相似智能体可能会混淆。例如一个“搜索网络”工具和一个“搜索内部文档”工具如果描述都写“搜索信息”智能体就难以抉择。应该写成“使用谷歌搜索公开网络信息”和“在公司知识库中搜索相关文档”。参数描述要清晰在工具函数的docstring里务必用Args:部分明确每个参数的名字和含义。LLM会参考这个来生成正确的调用格式。让智能体敢于说“不知道”有时用户的问题超出工具能力范围。一个好的设计是提供一个“兜底工具”比如final_answer让智能体在无法使用其他工具时能直接给出“我目前无法处理这个请求”的回答而不是强行调用错误工具。注意事项多工具智能体的调试会更复杂。如果智能体总是选错工具首先检查verbose日志看LLM的“思考”步骤。问题往往出在1) 工具描述不准确2) 用户提示不够清晰3) LLM的temperature设置过高导致决策不稳定。可以尝试优化提示词例如在系统消息中更强调“请仔细阅读工具描述后再做决定”。5. 为智能体注入记忆实现连贯多轮对话没有记忆的智能体每次对话都是“初见”。你无法进行这样的对话 用户“我叫小明。” AI“你好小明” 用户“我刚刚叫什么名字” AI茫然无知为了让智能体真正有用我们必须赋予它记忆能力。LangChain提供了多种记忆机制最简单也最常用的是ConversationBufferMemory。5.1 实现带有对话记忆的智能体我们将改造之前的健康助手让它能记住对话历史。# agent_with_memory.py from langchain.agents import tool, create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from langchain import hub from langchain.memory import ConversationBufferMemory # 定义工具同上略 tool def calculate_bmi(weight_kg: float, height_m: float) - str: # ... 实现同上 pass tool def get_weather(city: str) - str: # ... 实现同上 pass def main(): llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) tools [calculate_bmi, get_weather] # **关键变化1创建记忆组件** memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # memory_key 是存储在提示词中历史记录的变量名。 # return_messagesTrue 会以消息列表格式存储更适合与ChatModel配合。 # **关键变化2使用支持记忆的提示模板** # react 模板默认不支持记忆我们需要一个包含记忆变量的模板或者自定义。 # 这里我们使用LangChain Hub上一个支持对话的模板假设存在或自定义。 # 为了简化我们可以直接使用一个简单的包含chat_history和input变量的提示。 from langchain.prompts import PromptTemplate prompt_template PromptTemplate.from_template( 你是一个友好的健康与生活助手。你可以使用工具来获取信息或进行计算。 如果你不知道答案就说不知道不要编造。 之前的对话历史 {chat_history} 人类的新问题{input} 你应该思考需要做什么如果需要就使用工具。 {agent_scratchpad} # 这个变量是留给执行器填充工具调用和观察结果的 ) # 创建智能体使用自定义提示 agent create_react_agent(llm, tools, prompt_template) # **关键变化3创建执行器时传入memory** executor AgentExecutor( agentagent, toolstools, memorymemory, # 将记忆组件挂载到执行器 verboseTrue, handle_parsing_errorsTrue ) # 进行多轮对话 queries [ 我叫Alex。, 我的体重是80公斤身高1.8米我的BMI健康吗, 对了我所在城市北京的天气如何, 根据我的BMI和天气我今天适合去户外跑步吗 ] for query in queries: print(f\n[用户]: {query}) result executor.invoke({input: query}) print(f[助手]: {result[output]}) # 记忆已经自动被executor更新 # 查看记忆内容 print(\n 当前对话记忆 ) print(memory.buffer) if __name__ __main__: main()运行这段代码你会发现智能体在第二轮对话中已经知道用户在说“我的体重...”而无需再次询问姓名虽然此例中姓名未用于计算但记忆已存在。在第四轮对话中智能体需要综合之前对话中计算出的BMI结果和查询到的北京天气来回答“是否适合跑步”。这就需要记忆组件将前几轮的上下文包括工具调用的结果传递到当前的提示中LLM才能做出连贯的推理。5.2 记忆的挑战与高级策略简单的ConversationBufferMemory会把所有历史对话都塞进提示里这有两个问题上下文长度限制LLM有token数限制例如GPT-3.5-turbo是16K。长对话会耗尽限制导致无法继续。信息冗余十轮前的闲聊对当前问题可能毫无帮助反而干扰模型。因此在实际项目中我们需要更智能的记忆管理ConversationSummaryMemory不是存储所有原始对话而是定期或每次将历史对话总结成一段摘要。新的提示中包含的是摘要而非全文大大节省token。缺点是可能丢失细节。ConversationSummaryBufferMemory结合上述两者保留最近N条原始对话更早的则用摘要代替。这是一种权衡。向量存储记忆将对话中的关键信息如用户偏好、事实转换成向量存入像Chroma、Pinecone这样的向量数据库。当需要相关信息时通过语义搜索召回。这适用于需要长期、跨会话记忆的场景。实操心得记忆是智能体开发中的“深水区”。起步时用ConversationBufferMemory完全足够。当对话变长出现问题时再考虑引入摘要或向量存储。一个黄金法则是在提示中明确告诉LLM如何使用记忆。例如在提示词中加入“请参考之前的对话历史来理解当前问题但只关注与当前问题相关的部分。”6. 智能体开发中的常见“坑”与实战调试技巧即使按照教程一步步来你也一定会遇到智能体“犯傻”的时候它可能调用错误的工具、传入错误的参数、或者陷入死循环。别担心这是学习过程的必经之路。以下是我在开发中总结的几个最常见问题及其解决方法。6.1 问题一智能体不调用工具直接胡编乱造答案现象你问“北京天气如何”它直接编造一段天气回复而不是调用get_weather工具。根因分析工具描述不清LLM没有理解这个工具是干什么的或者认为自己的知识足以回答。提示词指令不强没有在系统提示中强制要求它“必须使用工具”。LLM温度temperature过高temperature参数控制输出的随机性。设为0确定性最高更适合执行任务设为更高值如0.7则创意更多但可能不遵守指令。解决方案强化提示词在系统提示中明确指令。system_message 你是一个必须使用工具来回答问题的助手。你拥有以下工具 {tools} 对于任何问题你必须先思考是否需要使用工具。如果问题涉及实时信息、计算或你知识库之外的内容你必须使用工具。 你的回答必须基于工具返回的事实绝对不允许编造信息。 请严格按照以下格式输出 思考... 动作工具名称 动作输入工具输入参数 检查temperature确保创建LLM时设置了temperature0。优化工具描述在工具描述中强调其必要性如“必须使用此工具获取实时天气不允许猜测”。6.2 问题二工具调用参数格式错误现象在verbose日志中你看到智能体决定调用calculate_bmi但动作输入是“weight: 70, height: 1.75”而你的函数期待的是两个浮点数参数导致调用失败。根因分析LLM没有严格按照JSON格式输出参数或者参数名不匹配。解决方案使用更强大的解析器LangChain的create_react_agent默认使用JSON格式解析。确保你的提示模板明确要求JSON。你也可以使用AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION这类代理类型它对结构化输出支持更好。在工具描述中明确参数格式tool def calculate_bmi(weight_kg: float, height_m: float) - str: 计算身体质量指数。 **参数必须是一个包含‘weight_kg’和‘height_m’两个键的JSON对象。** 例如{{weight_kg: 70, height_m: 1.75}} 增加错误处理与重试在AgentExecutor中设置max_iterations最大循环次数和early_stopping_method提前停止方法避免因单个错误卡死。也可以编写自定义的输出解析器来处理格式错误。6.3 问题三智能体陷入无限循环或重复调用现象智能体不停地调用同一个工具或者在不同工具间来回切换无法给出最终答案。根因分析工具返回结果不明确工具返回的信息可能没有明确回答LLM的疑问导致它认为任务未完成继续调用。缺乏终止条件LLM不知道何时应该停止“思考-行动”循环输出最终答案。解决方案优化工具输出确保工具返回的信息清晰、完整、直接。例如天气工具不要只返回“15°C”而应返回“北京当前气温15°C晴朗微风。查询成功。”在提示中明确结束指令在提示模板中加入“当你拥有足够的信息来直接、完整地回答用户的问题时你必须使用Final Answer:作为开头来输出最终答案并停止使用工具。”设置硬性限制AgentExecutor(max_iterations10, max_execution_time30)。这是一个安全网防止失控。6.4 通用调试技巧Verbose是你的最佳朋友始终开启verboseTrue。仔细阅读LLM的“思考”步骤你能精准定位是理解错了问题还是选错了工具或是参数格式不对。从简单到复杂先让智能体用好一个工具再逐步添加。每加一个新工具都进行充分测试。编写单元测试为你的每个工具函数编写独立的单元测试确保它们本身工作正常。然后为智能体编写集成测试模拟用户输入检查输出是否符合预期。使用Playground进行提示迭代在OpenAI Playground或类似界面中手动构建包含系统提示、工具描述和用户问题的完整提示观察LLM的原始输出。这能帮你快速调整提示词而无需每次运行整个Python脚本。日志记录除了LangChain的verbose在你的工具函数内部也加入日志打印如print(f“[Tool {name}] called with args: {args}”)这能让你更清楚地看到执行流。构建可靠的智能体是一个迭代过程编码 - 测试 - 观察错误 - 调整提示/工具 - 再测试。耐心和细致的观察是成功的关键。当你看到智能体流畅地理解复杂指令、自动调用正确的工具链并给出完美答案时那种感觉是无与伦比的。