
1. 项目概述为什么我们需要亲手构建一个AI Agent最近几个月AI领域最火的概念除了大模型本身恐怕就是“AI Agent”了。你可能在各种技术文章、产品发布会甚至投资报告里频繁看到这个词。但说实话很多讨论都停留在概念层面听起来很酷——一个能自主理解、规划并执行复杂任务的智能体——可真要自己动手从零开始搭一个很多人就懵了。这感觉就像告诉你“造一辆车需要四个轮子和一个发动机”但没告诉你轮子怎么装发动机怎么调。这正是我写这篇实战指南的初衷。我不想空谈概念而是想和你一起用最核心的技术——Function Calling实实在在地构建一个能跑起来的AI Agent。这个Agent的目标很明确它能理解你用自然语言下达的指令比如“帮我查一下北京明天下午的天气如果下雨就提醒我带伞”然后自动去调用相应的工具查天气API、发通知来完成这个任务。整个过程不需要你写死逻辑Agent自己会“思考”该怎么做。为什么是Function Calling因为它是目前连接大语言模型LLM的“大脑”和外部世界“手脚”最实用、最标准化的桥梁。你可以把它理解为给LLM一本工具使用说明书。LLM虽然知识渊博但它本身无法操作数据库、调用API或控制你的智能家居。Function Calling定义了工具的名称、描述和参数LLM在理解了你的意图后会返回一个结构化的调用请求告诉你“现在该用哪个工具参数是什么”然后由我们的程序去真正执行这个调用并把结果返回给LLM进行下一步分析。所以这个项目不只是学一个API调用。你将完整经历一个AI Agent的核心工作流意图理解 - 工具匹配与规划 - 执行 - 结果处理与响应。我们会从最简单的单工具调用开始逐步升级到多工具协作、状态记忆和复杂任务分解。无论你是想为自己的产品增加智能助理功能还是单纯对AI应用开发感兴趣这篇从零开始的实战指南都能给你一套可落地的代码和清晰的架构思路。2. 核心架构设计拆解AI Agent的“大脑”与“肢体”在开始写代码之前我们必须把Agent的骨架搭清楚。一个典型的、基于Function Calling的AI Agent其核心架构可以抽象为以下几个关键组件它们共同协作完成从用户输入到最终输出的闭环。2.1 核心组件与工作流想象一下这个Agent就是一个聪明的实习生。它的工作流程是这样的你用户给实习生下达一个指令比如“看看我日程表里明天下午三点后有没有空有的话预约一个会议室”。实习生的大脑LLM Function Calling逻辑实习生听到指令后会思考“要完成这个任务我需要做两件事第一查看日程表这需要get_calendar_events工具第二如果有空预定会议室这需要book_meeting_room工具。” 然后它不会直接去做而是先向你实则是向调度系统报告它的行动计划“我将先调用get_calendar_events参数是datetomorrow和after_time15:00。”调度系统你的代码收到大脑的“行动计划”即Function Call请求后调度系统找到对应的工具函数真正的get_calendar_events函数并传入参数执行它。工具执行外部API/数据库工具函数开始工作它可能去调用Google Calendar API查询真实的日程数据然后返回结果比如“明天下午三点到五点有一个产品评审会”。结果整合与下一步决策调度系统把工具执行的结果“明天下午三点到五点有会议”反馈给实习生的大脑。大脑再次思考“哦那段时间没空所以预定会议室的任务无法执行。我需要把这个情况告诉用户。” 于是它生成最终的自然语言回复“您明天下午三点到五点有一个产品评审会因此无法在那个时间段预定会议室。”这个流程中最精妙的部分在于第2步和第5步即LLM如何决定调用哪个工具以及如何处理工具返回的结果。这完全依赖于我们预先定义好的“工具描述”。2.2 工具Function的定义给LLM的“说明书”工具定义的质量直接决定了Agent的智商上限。它不是一个普通的函数注释而是一份需要精心编写的、给LLM看的“工具使用说明书”。一份好的工具定义通常包含name名称唯一标识符如get_weather。description描述这是最重要的部分必须用清晰、无歧义的自然语言描述这个工具是干什么的在什么场景下使用。例如“获取指定城市当前或未来某天的天气情况包括温度、天气状况、湿度、风速等。”parameters参数定义工具需要的输入参数每个参数也要有名称、类型、描述和是否必需。city城市名称类型为字符串描述为“要查询天气的城市名例如‘北京’、‘上海’”。date日期类型为字符串描述为“查询的日期格式为‘YYYY-MM-DD’。默认为今天”。这里有一个关键技巧描述要站在任务意图的角度而非技术实现的角度。不要写“调用某某天气API”而要写“查询某城市的天气”。LLM只关心“做什么”不关心“怎么做”。2.3 状态管理与对话记忆一个只会处理单轮对话的Agent是“金鱼记忆”实用性大打折扣。真正的Agent需要记住上下文。这通常通过维护一个“对话历史Message History”列表来实现。每次交互我们都把用户的问题、AI的回复包括中间的Function Call和结果都追加到这个历史中并在下一次请求LLM时将整个历史或最近N条作为上下文喂给它。这样当你问“北京天气怎么样”Agent调用天气工具并回答后你再问“那上海呢”LLM就能从历史中知道“你刚才在问天气”并且自动将“上海”作为参数填入get_weather工具无需你重复说明。注意历史上下文会消耗模型的Tokens增加成本和延迟。在实际项目中需要设计策略对长历史进行摘要Summarization或选择性遗忘这是构建高级Agent的进阶课题。3. 从零开始构建你的第一个单功能Agent理论说得再多不如一行代码。我们从一个最简单的例子开始构建一个只能查询天气的Agent。这个例子麻雀虽小五脏俱全能让你看清所有核心环节。我们将使用OpenAI的Chat Completions API因为它对Function Calling的支持最成熟、文档最全。你需要准备一个OpenAI的API Key。3.1 环境准备与依赖安装首先创建一个新的项目目录并初始化Python环境。我强烈建议使用虚拟环境。mkdir ai-agent-project cd ai-agent-project python -m venv venv # Windows: venv\Scripts\activate # Mac/Linux: source venv/bin/activate然后安装核心依赖。我们主要需要openai库另外用python-dotenv来管理API密钥等敏感信息。pip install openai python-dotenv在项目根目录创建一个.env文件存放你的API密钥OPENAI_API_KEY你的sk-xxx密钥 OPENAI_BASE_URLhttps://api.openai.com/v1 # 如果你用官方API此项可选3.2 定义第一个工具模拟天气查询在真实场景中你需要接入一个真实的天气API如和风天气、OpenWeatherMap。为了简化演示我们先模拟一个本地函数。创建一个名为weather_agent.py的文件。import os import json from datetime import datetime from dotenv import load_dotenv from openai import OpenAI # 加载环境变量 load_dotenv() # 初始化OpenAI客户端 client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) # 1. 定义工具函数真实情况下这里会调用第三方API def get_weather(city: str, date: str None) - str: 模拟获取天气信息。 在实际应用中这里应替换为对真实天气API如和风天气的调用。 if date is None: date datetime.now().strftime(%Y-%m-%d) # 模拟一些返回数据 weather_data { 北京: {2024-05-20: 晴 15~25°C 微风}, 上海: {2024-05-20: 多云 18~28°C 东南风3-4级}, 深圳: {2024-05-20: 阵雨 22~30°C 南风2-3级}, } city_data weather_data.get(city, {}) forecast city_data.get(date, f未找到{city}在{date}的天气信息) return f{city}在{date}的天气情况是{forecast} # 2. 定义给LLM看的“工具描述” tools [ { type: function, function: { name: get_weather, description: 获取指定城市在特定日期的天气信息。如果未提供日期则默认为今天。, parameters: { type: object, properties: { city: { type: string, description: 要查询天气的城市名称例如‘北京’、‘上海’、‘广州’。, }, date: { type: string, description: 查询的日期格式为YYYY-MM-DD。例如‘2024-05-20’。默认为今天。, }, }, required: [city], # 指定必填参数 }, }, } ] # 3. 对话历史管理 conversation_history [] def run_conversation(user_input: str): 处理一轮用户对话的核心函数 # 将用户输入加入历史 conversation_history.append({role: user, content: user_input}) # 第一步将用户输入和工具描述发送给LLM询问它是否需要调用工具 response client.chat.completions.create( modelgpt-3.5-turbo, # 或 gpt-4 messagesconversation_history, toolstools, tool_choiceauto, # 让模型自动决定是否调用工具 ) response_message response.choices[0].message # 将模型的初始回复也加入历史可能包含tool_calls conversation_history.append(response_message) # 第二步检查模型是否决定调用工具 tool_calls response_message.tool_calls if tool_calls: # 可能有多个工具调用我们这里只处理一个 for tool_call in tool_calls: function_name tool_call.function.name function_args json.loads(tool_call.function.arguments) print(f[Agent 决策] 决定调用工具: {function_name}) print(f[Agent 决策] 调用参数: {function_args}) # 第三步根据工具名找到本地函数并执行 available_functions { get_weather: get_weather, } function_to_call available_functions[function_name] # 执行真正的函数 function_response function_to_call(**function_args) print(f[工具执行] 结果: {function_response}) # 第四步将工具执行的结果作为新的消息再次发送给LLM让它生成面向用户的回复 conversation_history.append({ role: tool, tool_call_id: tool_call.id, content: function_response, }) # 请求LLM根据工具执行结果生成最终回复 second_response client.chat.completions.create( modelgpt-3.5-turbo, messagesconversation_history, ) final_message second_response.choices[0].message.content # 将LLM的最终回复加入历史 conversation_history.append({role: assistant, content: final_message}) return final_message else: # 如果模型没有调用工具直接返回它的回复 return response_message.content # 4. 主循环启动一个简单的对话 if __name__ __main__: print(天气查询Agent已启动输入‘退出’或‘quit’结束对话。) while True: user_input input(\n你: ) if user_input.lower() in [退出, quit, exit]: break answer run_conversation(user_input) print(fAgent: {answer})3.3 代码逐行解析与首次运行现在我们来运行这个脚本。在终端执行python weather_agent.py。尝试输入“北京今天天气怎么样”你会看到类似以下的输出你: 北京今天天气怎么样 [Agent 决策] 决定调用工具: get_weather [Agent 决策] 调用参数: {city: 北京} [工具执行] 结果: 北京在2024-05-20的天气情况是晴 15~25°C 微风 Agent: 北京今天2024-05-20的天气是晴天气温在15到25摄氏度之间有微风。发生了什么你的输入“北京今天天气怎么样”被添加到conversation_history。代码将历史和tools描述一起发送给GPT-3.5。GPT看到用户问题又看到有一个叫get_weather的工具描述是“获取天气信息”它立刻明白“这个问题需要调用get_weather工具参数是city北京”。于是它返回了一个结构化的tool_calls响应而不是直接回答天气。我们的代码检测到tool_calls解析出函数名和参数然后调用本地的get_weather(‘北京’)函数。模拟函数返回了天气字符串。代码把这个结果以role: tool的身份追加到历史中再次请求GPT。GPT看到了工具执行的结果“北京...晴15~25°C”它这次的任务是把这串原始数据组织成一句通顺的人话回复给你于是生成了“北京今天...是晴天...”。最终回复呈现给你并且这一轮完整的对话用户问题、AI的tool call、工具结果、AI最终回复都被保存在conversation_history中为后续对话提供上下文。恭喜你已经完成了AI Agent最核心的闭环。虽然它现在只能查天气但你已经掌握了让LLM“思考-行动-再思考”的魔法。4. 功能升级打造多工具协作的智能助理单功能Agent只是个开始。真正的价值在于让Agent能根据复杂指令自主选择并组合多个工具。我们来给它增加两个新能力计算器和时间查询把它变成一个多功能助理。4.1 定义与集成新工具我们在weather_agent.py的基础上修改创建一个新的文件multi_tool_agent.py。首先增加两个新的工具函数和它们的描述# ... (保留之前的 get_weather 函数和导入) ... # 新增工具函数1计算器 def calculator(expression: str) - str: 执行一个数学表达式计算。支持加减乘除和括号。 注意使用eval存在安全风险此处仅用于演示。生产环境应使用安全表达式解析库如ast.literal_eval限制范围。 try: # 警告实际产品中严禁直接eval用户输入 result eval(expression) return f表达式 {expression} 的计算结果是: {result} except Exception as e: return f计算表达式‘{expression}’时出错: {e} # 新增工具函数2时间查询 def get_current_time(timezone: str Asia/Shanghai) - str: 获取指定时区的当前日期和时间。 from datetime import datetime import pytz # 需要安装: pip install pytz try: tz pytz.timezone(timezone) current_time datetime.now(tz) return f当前时间{timezone}是: {current_time.strftime(%Y-%m-%d %H:%M:%S %Z%z)} except pytz.exceptions.UnknownTimeZoneError: return f未知时区: {timezone}。请提供有效的时区名称如‘Asia/Shanghai’ ‘America/New_York’。 # 更新工具列表 tools [ { type: function, function: { name: get_weather, description: 获取指定城市在特定日期的天气信息。如果未提供日期则默认为今天。, parameters: {...}, # 参数部分与之前相同此处省略 }, }, { type: function, function: { name: calculator, description: 执行一个数学表达式计算。例如可以计算‘(3 4) * 5 / 2’。, parameters: { type: object, properties: { expression: { type: string, description: 要计算的数学表达式例如‘35*2’或‘(10-4)/3’。, }, }, required: [expression], }, }, }, { type: function, function: { name: get_current_time, description: 获取当前日期和时间。可以指定时区例如‘Asia/Shanghai’或‘UTC’。, parameters: { type: object, properties: { timezone: { type: string, description: 时区名称遵循IANA时区数据库格式如‘Asia/Shanghai’ ‘America/New_York’ ‘UTC’。默认为‘Asia/Shanghai’。, }, }, required: [], # 时区参数非必需 }, }, }, ] # 更新可用函数映射 available_functions { get_weather: get_weather, calculator: calculator, get_current_time: get_current_time, }重要安全提示上面的calculator函数为了演示简单使用了eval()这在生产环境中是极其危险的因为它会执行任意代码。在实际项目中你必须使用安全的数学表达式解析库如ast.literal_eval但只能用于简单字面量或专门的库如numexpr、simpleeval并严格限制可用的操作符和函数。4.2 处理并行工具调用与复杂逻辑我们的run_conversation函数已经能处理单个工具调用。但OpenAI的API实际上支持模型在一次响应中返回多个tool_calls例如用户说“查一下北京天气再算一下123乘以456”。我们需要升级函数来处理这种情况。修改run_conversation函数的核心循环部分def run_conversation(user_input: str): conversation_history.append({role: user, content: user_input}) # 第一轮LLM决定行动 response client.chat.completions.create( modelgpt-3.5-turbo, messagesconversation_history, toolstools, tool_choiceauto, ) response_message response.choices[0].message conversation_history.append(response_message) tool_calls response_message.tool_calls final_message None # 如果存在工具调用可能是一个或多个 if tool_calls: print(f[Agent 决策] 检测到 {len(tool_calls)} 个工具调用。) # 用于收集所有工具执行结果 tool_messages [] for tool_call in tool_calls: function_name tool_call.function.name function_args json.loads(tool_call.function.arguments) print(f - 调用 {function_name}, 参数: {function_args}) # 执行对应的函数 if function_name in available_functions: function_to_call available_functions[function_name] try: function_response function_to_call(**function_args) except Exception as e: function_response f调用工具 {function_name} 时发生错误: {e} else: function_response f未知工具: {function_name} print(f - 结果: {function_response}) # 将每个工具的结果收集起来 tool_messages.append({ role: tool, tool_call_id: tool_call.id, content: function_response, }) # 将所有工具执行结果一次性加入历史 conversation_history.extend(tool_messages) # 请求LLM基于所有工具结果生成最终回复 second_response client.chat.completions.create( modelgpt-3.5-turbo, messagesconversation_history, ) final_message second_response.choices[0].message.content conversation_history.append({role: assistant, content: final_message}) else: # 没有工具调用直接使用模型的回复 final_message response_message.content if final_message: conversation_history.append({role: assistant, content: final_message}) return final_message if final_message else 未生成回复现在运行新的multi_tool_agent.py尝试一些复杂指令指令1“现在几点了顺便算一下(1527)除以6等于多少。”预期行为LLM应该同时调用get_current_time可能用默认时区和calculator两个工具。指令2“如果北京明天天气好就告诉我‘适合出游’否则说‘建议室内’。”预期行为这是一个条件逻辑。LLM会先调用get_weather城市北京日期明天拿到结果后在生成最终回复时判断“天气好”与否并给出相应建议。注意LLM本身并不“执行”if-else逻辑它是在生成文本时根据工具返回的信息进行推理和判断。通过这个升级你的Agent已经具备了基本的任务理解和多工具调度能力。你可以通过不断添加新的工具函数如查股票、订机票、控制智能设备来无限扩展它的能力边界。5. 工程化与优化让Agent更健壮、更高效一个能在Demo里跑通的Agent离投入实际使用还差得很远。接下来我们探讨几个关键的工程化议题让你的Agent从玩具变成工具。5.1 错误处理与鲁棒性增强现实世界充满意外。网络会超时API会返回错误用户会输入歧义或恶意指令。我们的Agent必须能妥善处理这些情况。工具执行异常处理我们已经在上面的代码中用了try...except包裹工具调用。但还需要更细致。例如天气API可能返回{“code”: “404”, “msg”: “城市不存在”}。我们的工具函数应该解析这种错误并返回清晰的错误信息给LLM而不是抛出一个Python异常导致整个对话中断。LLM响应解析与验证LLM有时会“胡言乱语”可能返回一个不存在的工具名或者参数格式错误。我们的代码在解析tool_calls和arguments时需要增加验证逻辑。# 在解析tool_call后可以增加验证 if function_name not in available_functions: function_response f错误系统不支持工具‘{function_name}’。 elif not _validate_arguments(function_name, function_args): # 自定义的参数验证函数 function_response f错误调用工具‘{function_name}’的参数不合法。用户输入清洗与安全永远不要相信用户的直接输入。特别是当工具涉及数据库操作或系统命令时。对于计算器我们替换了危险的eval。对于其他工具要严格校验参数范围、类型和长度防止SQL注入、命令注入等攻击。5.2 上下文管理与Token优化随着对话轮次增加conversation_history会越来越长导致每次请求的Token数暴涨成本增加速度变慢甚至可能超过模型上下文长度限制如GPT-3.5的16K。常见的优化策略有滑动窗口只保留最近N轮对话例如最近10轮。简单有效但会丢失早期的重要上下文。摘要压缩当历史达到一定长度时可以请求LLM本身对之前的对话历史生成一个简短的摘要例如“用户之前咨询了北京的天气并计算了数学题”然后用这个摘要替换掉大部分旧历史只保留最近几轮完整对话。这需要额外的LLM调用但能更好地保留长期记忆。选择性记忆更复杂的系统会区分不同类型的历史如工具调用结果、用户偏好、事实信息并决定哪些需要长期记住哪些可以丢弃。5.3 性能优化与成本控制缓存对于频繁且结果不变的工具调用如查询某个静态信息可以引入缓存如使用functools.lru_cache或Redis避免重复调用LLM或外部API。异步调用如果Agent需要调用多个彼此独立的、耗时的外部API应该使用异步IOasyncio来并发执行而不是同步等待这能极大减少整体响应时间。模型选择对于工具调用决策即判断该调用哪个工具使用更便宜、更快的模型如gpt-3.5-turbo通常就足够了。只有在需要复杂推理和文本生成的最终回复环节才考虑使用gpt-4等更强但更贵的模型。这被称为混合模型策略。5.4 可观测性与调试当Agent行为不符合预期时你需要知道它内部发生了什么。除了我们代码中的print语句一个成熟的系统应该具备结构化日志记录每一轮对话的完整信息用户输入、LLM的tool_calls决策、工具执行结果、最终回复并关联到一个唯一的会话ID。这便于事后分析和复现问题。链路追踪在微服务架构下一个用户请求可能触发多个工具调用进而调用多个外部服务。使用OpenTelemetry等工具进行链路追踪可以清晰看到耗时和错误发生在哪个环节。监控与告警监控Agent的调用频率、响应时间、错误率、Token消耗等关键指标并设置告警。6. 实战进阶实现复杂任务分解与规划到目前为止我们的Agent还停留在“用户问什么我就调用对应工具”的层面。但对于“帮我规划一个周末出行先看天气再推荐景点最后估算预算”这样的复杂指令它可能无法一次性规划好所有步骤。这就需要引入“任务分解Task Decomposition”和“规划Planning”的能力。这通常有两种实现思路6.1 思路一借助LLM自身进行链式规划ReAct模式ReActReasoning Acting是一种提示范式引导LLM以“思考 - 行动 - 观察”的循环来解决问题。我们可以通过设计系统提示词System Prompt来实现一个简单的版本。我们在multi_tool_agent.py的基础上修改run_conversation的初始消息加入一个强大的系统指令# 在conversation_history初始化时加入系统提示 conversation_history [ { role: system, content: 你是一个强大的任务规划与执行助手。你的工作方式是 1. 首先理解用户的最终目标。 2. 然后将这个目标分解成一系列可执行的子任务。每个子任务都应该能通过调用一个可用工具来完成。 3. 逐步执行这些子任务。在每一步你必须先说明你的思考Reason然后决定调用哪个工具Act并等待工具返回结果Observe。 4. 根据观察到的结果决定下一步是继续执行下一个子任务还是已经可以综合所有信息回答用户。 5. 最终给出一个完整、清晰的答案。 可用工具 - get_weather: 查询天气。 - calculator: 进行数学计算。 - get_current_time: 查询时间。 请严格按照“思考-行动-观察”的步骤进行。你的“思考”部分请以‘【思考】’开头。 } ]然后你需要修改对话循环使其能够处理多轮“思考-行动”的交互而不仅仅是一轮工具调用。这需要更复杂的循环逻辑每次LLM回复后都检查它是否表示任务已完成可以给出最终答案还是需要继续调用工具。这种方式的优点是实现相对直接完全依赖LLM的推理能力。缺点是步骤多、调用次数多、成本高且对提示词设计的要求极高。6.2 思路二使用专用规划模型或框架这是更工程化的方法。你可以使用一个专门的“规划器Planner”模块它可能是一个微调过的LLM或者一个基于规则的引擎。这个规划器接收用户指令输出一个结构化的任务执行计划Plan这个计划可能是一个有向无环图DAG定义了子任务的执行顺序和依赖关系。然后一个独立的“执行器Executor”模块按照这个计划依次调用相应的工具。执行器将每个工具的结果反馈给规划器或一个“监督器Supervisor”由它来决定是继续执行下一个任务还是需要调整计划。用户输入 | v [规划器 Planner] | (生成任务计划 DAG) v [执行器 Executor] - 调用工具1 - 获取结果1 | (根据结果和计划) v [执行器 Executor] - 调用工具2 - 获取结果2 | v [结果合成器] - 最终回复这种方式将规划与执行解耦逻辑更清晰易于测试和扩展但系统复杂度也更高。像AutoGPT、LangChain等框架在一定程度上提供了类似的能力。对于大多数应用场景从思路一强化提示词开始是更务实的选择。当任务复杂度达到一定程度后再考虑架构升级。7. 常见问题与避坑指南在开发和调试AI Agent的过程中我踩过不少坑。这里总结一些最常见的问题和解决方案希望能帮你节省大量时间。7.1 工具调用不触发或触发错误问题用户的问题明显需要某个工具但LLM就是不调用而是直接生成了一个猜测性的回答。排查检查工具描述这是最常见的原因。描述是否清晰、无歧义是否准确描述了工具的用途和适用场景尝试用更直接、任务导向的语言重写描述。例如将“进行数学运算”改为“计算一个数学表达式的数值结果”。检查参数描述参数描述是否清楚说明了需要什么格式的数据例如date参数是否说明了格式是“YYYY-MM-DD”检查系统提示如果你使用了系统提示确保它没有限制或干扰工具调用。可以尝试暂时移除或简化系统提示进行测试。模型能力gpt-3.5-turbo的工具调用能力已经很强但对于极其复杂或隐晦的指令gpt-4的准确率会更高。可以切换模型试试。7.2 参数解析错误问题LLM决定调用工具但返回的参数值格式不对比如应该是数字却给了字符串或者缺少必需参数。解决强化参数Schema在parameters的description里明确写出格式和示例。例如“description”: “日期格式必须为YYYY-MM-DD例如‘2024-05-20’。后置清洗与转换在工具函数内部对传入的参数进行类型转换和验证。如果转换失败或验证不通过返回明确的错误信息给LLM让它有机会纠正。例如def get_weather(city: str, date: str None): try: # 尝试将字符串日期转换为datetime对象进行验证 if date: datetime.strptime(date, “%Y-%m-%d”) except ValueError: return f“错误日期参数‘{date}’格式不正确请使用YYYY-MM-DD格式。” # ... 其余逻辑7.3 上下文混乱与记忆丢失问题在多轮对话中Agent忘记了之前说过的话或执行过的操作。解决确保历史被正确传递每次调用client.chat.completions.create时messages参数必须包含完整的conversation_history。注意角色Role用户输入是“user”LLM的回复是“assistant”工具执行结果是“tool”。角色错误会导致模型无法理解对话结构。管理历史长度如前所述实施滑动窗口或摘要策略防止关键信息被截断。7.4 成本与延迟过高问题Agent响应慢API调用费用增长快。优化精简上下文这是最有效的手段。积极管理对话历史移除不必要的信息。使用更便宜的模型做决策对于工具调用决策gpt-3.5-turbo在绝大多数情况下足够好且便宜。实现缓存对相同参数的工具调用结果进行缓存有效期根据数据性质设定如天气缓存30分钟汇率缓存1分钟。批量处理如果业务允许可以将多个用户的请求稍作聚合再与LLM交互但要注意不能影响用户体验。构建AI Agent是一个持续迭代的过程。从最简单的单工具调用开始逐步增加复杂度处理好错误和边界情况再考虑引入任务规划和状态管理。核心始终是清晰定义工具并相信LLM的理解与推理能力。当你看到它能够准确理解“如果明天下雨就提醒我带伞否则提醒我涂防晒霜”这样的指令并自动完成天气查询和条件判断时你会感受到这种技术带来的巨大潜力。