从零构建Python智能体:理解Agent核心原理与实战开发

从零构建Python智能体:理解Agent核心原理与实战开发 为什么现在一提到Agent开发大家首先想到的就是各种框架LangChain、AutoGPT、AgentScope...这些框架确实强大但如果你连Agent的基本工作原理都没搞懂就直接上框架就像还没学会走路就想开赛车——看似高效实则隐患重重。我见过太多开发者框架用得飞起但当需要定制一个简单功能时却无从下手。真正的Agent能力不在于你会用多少框架而在于你是否理解从输入到输出的完整决策链条。今天这篇文章我将带你从零开始不用任何框架只用Python基础库构建一个完整的Agent系统。1. 这篇文章真正要解决的问题很多开发者对Agent存在认知误区认为Agent就是调用API的封装或者必须依赖大模型才能工作。实际上Agent的核心是自主决策能力而大模型只是实现这种能力的一种工具。本文将解决三个关键问题概念澄清Agent到底是什么与普通程序的区别在哪里能力边界不用大模型Agent能做什么用大模型又该如何正确集成实战落地如何从最简单的规则引擎开始逐步升级到智能决策系统如果你符合以下情况这篇文章正是为你准备的想入门Agent开发但被各种框架搞晕的初学者希望理解Agent底层机制的中级开发者需要定制化Agent功能但不想被框架限制的实践者2. 基础概念与核心原理2.1 Agent的本质不只是代码更是决策体Agent智能体与传统程序的根本区别在于自主性。普通程序被动执行指令而Agent能够根据环境状态主动做出决策。用一个简单的类比理解普通程序像计算器输入11固定输出2Agent像厨师给你面粉和鸡蛋他能自主决定做蛋糕还是面条2.2 Agent的核心组件一个完整的Agent包含四个基本组件组件功能简单实现方式感知器接收环境信息函数参数、API调用决策器分析信息并制定策略if-else规则、模型推理执行器执行决策结果函数调用、系统命令记忆器存储历史经验变量、数据库2.3 有框架 vs 无框架开发的真实对比很多开发者担心不用框架会重复造轮子但实际情况是使用框架的优势快速上手提供现成组件社区支持遇到问题容易找到解决方案标准化团队协作更方便不用框架的优势深度理解每个组件的职责完全掌控定制化程度高依赖简单部署轻量性能优化空间大对于学习阶段从零开始构建是理解Agent的最佳路径。3. 环境准备与前置条件3.1 基础环境要求构建Agent不需要复杂的开发环境只需要# 检查Python版本 python --version # 需要Python 3.8及以上版本 # 创建项目目录 mkdir simple_agent cd simple_agent # 创建虚拟环境可选但推荐 python -m venv venv source venv/bin/activate # Linux/Mac # venv\Scripts\activate # Windows3.2 所需库的极简清单我们刻意保持依赖的最小化# requirements.txt # 基础库Python标准库已包含无需安装 # 如果需要网络功能可以添加requests requests2.25.1 # 如果需要简单的数据存储 json sqlite3 # Python内置 # 如果需要与LLM集成可选 openai1.0.0安装命令pip install -r requirements.txt3.3 开发工具建议IDEVS Code、PyCharm Community Edition免费调试使用Python内置的pdb或IDE调试器版本控制Git基础操作即可4. 最简单的Agent规则引擎实现让我们从最基础的规则引擎开始这是理解Agent决策过程的最佳起点。4.1 基础规则Agent类定义# simple_rule_agent.py class RuleBasedAgent: def __init__(self, nameSimpleAgent): self.name name self.memory [] # 简单的记忆存储 self.rules self._initialize_rules() def _initialize_rules(self): 初始化决策规则 return { greeting: { condition: lambda input_text: any(word in input_text.lower() for word in [hello, hi, hey]), action: lambda: Hello! How can I help you? }, farewell: { condition: lambda input_text: any(word in input_text.lower() for word in [bye, goodbye, see you]), action: lambda: Goodbye! Have a great day! }, question: { condition: lambda input_text: ? in input_text, action: lambda: Thats an interesting question. Im still learning! }, default: { condition: lambda input_text: True, # 默认匹配所有 action: lambda: Im not sure how to respond to that. } } def perceive(self, input_text): 感知输入并做出决策 self.memory.append(fInput: {input_text}) # 决策过程按优先级检查规则 for rule_name, rule in self.rules.items(): if rule_name default: continue # 默认规则最后检查 if rule[condition](input_text): response rule[action]() self.memory.append(fResponse: {response} (Rule: {rule_name})) return response # 如果没有匹配的规则使用默认规则 default_response self.rules[default][action]() self.memory.append(fResponse: {default_response} (Rule: default)) return default_response def get_memory(self): 获取记忆历史 return self.memory.copy()4.2 测试基础Agent# test_rule_agent.py def test_basic_agent(): agent RuleBasedAgent(TestAgent) test_cases [ Hello there!, How are you?, Goodbye!, What time is it? ] print(fTesting {agent.name}:) for i, test_input in enumerate(test_cases, 1): response agent.perceive(test_input) print(f{i}. Input: {test_input}) print(f Response: {response}) print() print(Memory log:) for entry in agent.get_memory(): print(f- {entry}) if __name__ __main__: test_basic_agent()运行结果应该类似Testing TestAgent: 1. Input: Hello there! Response: Hello! How can I help you? 2. Input: How are you? Response: Thats an interesting question. Im still learning! 3. Input: Goodbye! Response: Goodbye! Have a great day! 4. Input: What time is it? Response: Im not sure how to respond to that.5. 进阶具有状态管理的能力Agent基础规则引擎太简单让我们给它添加状态管理和更复杂的决策逻辑。5.1 状态管理Agent实现# stateful_agent.py import json import time from datetime import datetime class StatefulAgent: def __init__(self, nameStatefulAgent): self.name name self.state { conversation_count: 0, last_interaction: None, user_preferences: {}, current_context: idle } self.memory [] self.conversation_history [] def perceive(self, input_text, user_iddefault_user): 感知输入更新状态并做出决策 # 更新状态 self.state[conversation_count] 1 self.state[last_interaction] datetime.now().isoformat() self.state[current_context] self._determine_context(input_text) # 记录交互 interaction { timestamp: self.state[last_interaction], user_id: user_id, input: input_text, context: self.state[current_context] } # 决策逻辑 response self._make_decision(input_text, user_id) interaction[response] response interaction[state_snapshot] self.state.copy() self.conversation_history.append(interaction) self.memory.append(interaction) return response def _determine_context(self, input_text): 根据输入确定当前上下文 text_lower input_text.lower() if any(word in text_lower for word in [help, assist, support]): return assistance elif any(word in text_lower for word in [weather, time, news]): return information elif any(word in text_lower for word in [joke, fun, entertain]): return entertainment else: return general def _make_decision(self, input_text, user_id): 基于状态和上下文做出决策 context self.state[current_context] count self.state[conversation_count] # 基于上下文的决策逻辑 if context assistance: return self._handle_assistance_request(input_text) elif context information: return self._handle_information_request(input_text) elif context entertainment: return self._handle_entertainment_request(input_text) else: return self._handle_general_conversation(input_text, count) def _handle_assistance_request(self, input_text): 处理帮助请求 assistance_responses [ Id be happy to help! What do you need assistance with?, Im here to help. Please describe your issue in more detail., Let me see how I can assist you with that. ] return assistance_responses[len(input_text) % len(assistance_responses)] def _handle_information_request(self, input_text): 处理信息查询 if time in input_text.lower(): current_time datetime.now().strftime(%Y-%m-%d %H:%M:%S) return fThe current time is {current_time} else: return I can provide basic information like time. For other queries, Im still learning! def _handle_entertainment_request(self, input_text): 处理娱乐请求 jokes [ Why dont scientists trust atoms? Because they make up everything!, Why did the scarecrow win an award? He was outstanding in his field!, Why dont eggs tell jokes? Theyd crack each other up! ] return jokes[len(input_text) % len(jokes)] def _handle_general_conversation(self, input_text, count): 处理一般对话 if count 1: return Nice to meet you! Im a learning agent. else: return Im still learning how to have natural conversations. What would you like to talk about? def get_conversation_summary(self): 获取对话摘要 return { total_interactions: self.state[conversation_count], last_interaction: self.state[last_interaction], current_context: self.state[current_context], recent_history: self.conversation_history[-5:] # 最近5条记录 } def save_state(self, filenameagent_state.json): 保存Agent状态到文件 state_data { agent_name: self.name, state: self.state, conversation_history: self.conversation_history, save_timestamp: datetime.now().isoformat() } with open(filename, w) as f: json.dump(state_data, f, indent2) def load_state(self, filenameagent_state.json): 从文件加载Agent状态 try: with open(filename, r) as f: state_data json.load(f) self.state state_data[state] self.conversation_history state_data[conversation_history] print(fLoaded state for {state_data[agent_name]}) except FileNotFoundError: print(No saved state found. Starting fresh.)5.2 测试状态管理Agent# test_stateful_agent.py def test_stateful_agent(): agent StatefulAgent(AdvancedAgent) # 模拟对话流程 dialogues [ Hello, I need some help, What time is it?, Tell me a joke, How does this work? ] print( Stateful Agent Conversation ) for i, dialogue in enumerate(dialogues, 1): print(fTurn {i}:) print(fUser: {dialogue}) response agent.perceive(dialogue, fuser_{i}) print(fAgent: {response}) print(fContext: {agent.state[current_context]}) print() # 显示摘要 summary agent.get_conversation_summary() print( Conversation Summary ) print(fTotal interactions: {summary[total_interactions]}) print(fLast interaction: {summary[last_interaction]}) # 保存状态 agent.save_state(test_agent_state.json) print(Agent state saved to test_agent_state.json) if __name__ __main__: test_stateful_agent()6. 集成LLM从规则到智能的跨越现在让我们给Agent添加真正的智能——集成大语言模型。但重要的是我们要理解LLM在Agent中的正确角色。6.1 LLM集成的架构设计关键理念LLM不是替代整个Agent而是增强决策器的能力。# llm_enhanced_agent.py import openai import os from stateful_agent import StatefulAgent class LLMEnhancedAgent(StatefulAgent): def __init__(self, nameLLMAgent, use_llmTrue): super().__init__(name) self.use_llm use_llm self.llm_client None self.llm_cost_tracker 0 if use_llm: self._setup_llm() def _setup_llm(self): 设置LLM客户端 try: # 从环境变量获取API密钥 api_key os.getenv(OPENAI_API_KEY) if api_key: self.llm_client openai.OpenAI(api_keyapi_key) print(LLM client initialized successfully) else: print(OPENAI_API_KEY not found. LLM features disabled.) self.use_llm False except Exception as e: print(fLLM setup failed: {e}) self.use_llm False def _call_llm(self, prompt, max_tokens150): 调用LLM生成响应 if not self.use_llm or not self.llm_client: return None try: response self.llm_client.chat.completions.create( modelgpt-3.5-turbo, messages[{role: user, content: prompt}], max_tokensmax_tokens, temperature0.7 ) # 简单成本追踪近似值 self.llm_cost_tracker len(prompt) / 1000 * 0.0015 # 输入成本 self.llm_cost_tracker response.usage.completion_tokens / 1000 * 0.002 # 输出成本 return response.choices[0].message.content.strip() except Exception as e: print(fLLM call failed: {e}) return None def _make_decision_with_llm(self, input_text, user_id, context): 使用LLM增强决策过程 # 首先尝试规则引擎 rule_based_response self._make_decision(input_text, user_id) # 在特定条件下使用LLM use_llm_conditions [ context general and len(input_text) 20, # 复杂一般对话 explain in input_text.lower(), # 解释性请求 opinion in input_text.lower(), # 观点性请求 self.state[conversation_count] % 3 0 # 每3次对话使用一次LLM控制成本 ] if any(use_llm_conditions) and self.use_llm: llm_prompt f 你是一个有帮助的AI助手。用户说{input_text} 当前上下文{context} 对话历史长度{self.state[conversation_count]} 请生成一个自然、有帮助的回复。如果合适可以基于规则引擎的初步响应{rule_based_response} 但不要直接重复它。保持回复简洁最多2句话。 llm_response self._call_llm(llm_prompt) if llm_response: return f{llm_response} [LLM Enhanced] return rule_based_response def perceive(self, input_text, user_iddefault_user): 重写感知方法集成LLM # 更新状态继承父类逻辑 self.state[conversation_count] 1 self.state[last_interaction] datetime.now().isoformat() self.state[current_context] self._determine_context(input_text) # 使用LLM增强的决策 response self._make_decision_with_llm(input_text, user_id, self.state[current_context]) # 记录交互 interaction { timestamp: self.state[last_interaction], user_id: user_id, input: input_text, response: response, context: self.state[current_context], used_llm: LLM Enhanced in response if response else False } self.conversation_history.append(interaction) self.memory.append(interaction) return response def get_llm_usage(self): 获取LLM使用统计 return { total_cost_estimate: round(self.llm_cost_tracker, 4), llm_enabled: self.use_llm, total_interactions: self.state[conversation_count] }6.2 配置和使用LLM增强Agent# config_llm_agent.py import os from llm_enhanced_agent import LLMEnhancedAgent def setup_llm_agent(): 设置LLM Agent的配置示例 # 方法1设置环境变量推荐 # 在终端中执行export OPENAI_API_KEYyour-api-key # 或者在代码中设置 # os.environ[OPENAI_API_KEY] your-api-key-here # 创建Agent实例 agent LLMEnhancedAgent(SmartAssistant, use_llmTrue) return agent def demo_llm_agent(): 演示LLM Agent的能力 agent setup_llm_agent() test_inputs [ Can you explain how machine learning works?, Whats your opinion on climate change?, I need help with programming, Tell me a fun fact about space ] print( LLM Enhanced Agent Demo ) for i, input_text in enumerate(test_inputs, 1): print(f\n{i}. User: {input_text}) response agent.perceive(input_text) print(f Agent: {response}) # 显示使用统计 usage agent.get_llm_usage() print(f\n Usage Statistics ) print(fLLM Enabled: {usage[llm_enabled]}) print(fEstimated Cost: ${usage[total_cost_estimate]}) print(fTotal Interactions: {usage[total_interactions]}) if __name__ __main__: # 如果没有设置API密钥Agent会自动回退到规则引擎 demo_llm_agent()7. 完整项目任务导向型Agent系统现在我们将所有组件整合构建一个能够处理多步骤任务的完整Agent系统。7.1 任务管理系统实现# task_agent.py import json import re from enum import Enum from llm_enhanced_agent import LLMEnhancedAgent class TaskStatus(Enum): PENDING pending IN_PROGRESS in_progress COMPLETED completed FAILED failed class TaskOrientedAgent(LLMEnhancedAgent): def __init__(self, nameTaskAgent): super().__init__(name) self.tasks {} self.task_id_counter 1 self.available_skills self._initialize_skills() def _initialize_skills(self): 初始化Agent可用的技能集 return { calculate: { description: Perform mathematical calculations, function: self._skill_calculate }, search_memory: { description: Search through conversation history, function: self._skill_search_memory }, schedule_reminder: { description: Set a simple reminder, function: self._skill_schedule_reminder }, analyze_sentiment: { description: Analyze text sentiment, function: self._skill_analyze_sentiment } } def create_task(self, task_description, priority1): 创建新任务 task_id self.task_id_counter self.task_id_counter 1 task { id: task_id, description: task_description, priority: priority, status: TaskStatus.PENDING, created_at: datetime.now().isoformat(), steps: self._break_down_task(task_description), current_step: 0, result: None } self.tasks[task_id] task return task_id def _break_down_task(self, task_description): 将任务分解为步骤 # 简单的任务分解逻辑 steps [] if calculate in task_description.lower(): steps.extend([ Identify mathematical expression, Parse and validate expression, Perform calculation, Verify result ]) if remind in task_description.lower(): steps.extend([ Extract reminder time and content, Validate time format, Store reminder, Confirm with user ]) if not steps: # 默认步骤 steps [ Analyze task requirements, Determine appropriate approach, Execute task, Review results ] return steps def execute_task(self, task_id): 执行任务 if task_id not in self.tasks: return fTask {task_id} not found task self.tasks[task_id] task[status] TaskStatus.IN_PROGRESS print(fExecuting task {task_id}: {task[description]}) try: # 使用LLM分析任务并选择技能 if self.use_llm: skill_choice self._llm_analyze_task(task[description]) else: skill_choice self._rule_based_skill_selection(task[description]) # 执行任务 result self._execute_with_skill(task[description], skill_choice) task[status] TaskStatus.COMPLETED task[result] result task[completed_at] datetime.now().isoformat() return result except Exception as e: task[status] TaskStatus.FAILED task[result] fError: {str(e)} return fTask failed: {str(e)} def _llm_analyze_task(self, task_description): 使用LLM分析任务并选择技能 prompt f 分析以下任务描述选择最合适的处理技能 任务: {task_description} 可用技能: {json.dumps({k: v[description] for k, v in self.available_skills.items()}, indent2)} 只需回复技能名称calculate, search_memory, schedule_reminder, analyze_sentiment中的一个。 如果都不合适回复general。 response self._call_llm(prompt, max_tokens50) if response and response in self.available_skills: return response else: return general def _rule_based_skill_selection(self, task_description): 基于规则的技能选择 text_lower task_description.lower() if any(word in text_lower for word in [calculate, math, add, multiply]): return calculate elif any(word in text_lower for word in [find, search, remember]): return search_memory elif any(word in text_lower for word in [remind, schedule, alert]): return schedule_reminder elif any(word in text_lower for word in [feel, sentiment, mood]): return analyze_sentiment else: return general def _execute_with_skill(self, task_description, skill_name): 使用特定技能执行任务 if skill_name in self.available_skills: return self.available_skills[skill_name][function](task_description) else: return self._handle_general_task(task_description) # 技能实现 def _skill_calculate(self, task_description): 计算技能实现 # 简单的数学表达式提取和计算 numbers re.findall(r\d, task_description) if len(numbers) 2: result sum(map(int, numbers)) return fThe sum of numbers {, .join(numbers)} is {result} else: return I need more numbers to perform a calculation def _skill_search_memory(self, task_description): 记忆搜索技能 search_terms task_description.lower().split() relevant_entries [] for entry in self.conversation_history[-10:]: # 搜索最近10条记录 entry_text f{entry.get(input, )} {entry.get(response, )}.lower() if any(term in entry_text for term in search_terms if len(term) 3): relevant_entries.append(entry) if relevant_entries: return fFound {len(relevant_entries)} relevant conversations else: return No relevant conversations found def _skill_schedule_reminder(self, task_description): 提醒调度技能 # 简单的提醒提取 time_pattern r(\d{1,2}:\d{2}) times re.findall(time_pattern, task_description) if times: return fReminder set for {times[0]} else: return Please specify a time for the reminder (e.g., 14:30) def _skill_analyze_sentiment(self, task_description): 情感分析技能 positive_words [good, great, excellent, happy, love] negative_words [bad, terrible, awful, sad, hate] text_lower task_description.lower() positive_count sum(1 for word in positive_words if word in text_lower) negative_count sum(1 for word in negative_words if word in text_lower) if positive_count negative_count: return The text seems positive elif negative_count positive_count: return The text seems negative else: return The sentiment is neutral def _handle_general_task(self, task_description): 处理一般任务 return fIll work on: {task_description}. This is a general task handling. def get_task_status(self, task_id): 获取任务状态 if task_id in self.tasks: return self.tasks[task_id] else: return None def list_tasks(self): 列出所有任务 return self.tasks.values()7.2 完整系统演示# demo_complete_agent.py from task_agent import TaskOrientedAgent, TaskStatus def demo_complete_agent_system(): 演示完整的Agent系统 agent TaskOrientedAgent(CompleteTaskAgent) print( Complete Agent System Demo ) # 创建多个任务 tasks [ (Calculate the sum of 5, 10, and 15, 2), (Remind me to call John at 15:00, 1), (Find our previous conversation about weather, 2), (How do I feel about this project?, 3) ] task_ids [] for description, priority in tasks: task_id agent.create_task(description, priority) task_ids.append(task_id) print(fCreated task {task_id}: {description} (Priority: {priority})) print(\n Executing Tasks ) # 执行任务 for task_id in task_ids: print(f\n--- Executing Task {task_id} ---) result agent.execute_task(task_id) print(fResult: {result}) # 显示任务状态 task_status agent.get_task_status(task_id) print(fStatus: {task_status[status].value}) print(fSteps: {task_status[steps]}) print(\n Task Summary ) all_tasks agent.list_tasks() completed sum(1 for t in all_tasks if t[status] TaskStatus.COMPLETED) total len(all_tasks) print(fTasks completed: {completed}/{total}) # 显示系统状态 print(f\n System Status ) print(fTotal conversations: {agent.state[conversation_count]}) print(fAvailable skills: {list(agent.available_skills.keys())}) if __name__ __main__: demo_complete_agent_system()8. 常见问题与排查思路在开发和使用自定义Agent过程中你会遇到各种问题。以下是典型问题及解决方案8.1 Agent基础问题排查问题现象可能原因排查方式解决方案Agent不响应输入感知器逻辑错误检查perceive方法输入处理添加输入验证和日志决策结果不符合预期规则条件设置不当测试单个规则条件使用更具体的条件匹配记忆功能异常内存数据结构错误检查记忆存储和检索逻辑实现数据序列化备份状态管理混乱状态更新时机错误添加状态变更日志使用状态机模式管理8.2 LLM集成问题排查问题现象可能原因排查方式解决方案LLM调用失败API密钥错误或网络问题检查环境变量和网络连接实现降级到规则引擎响应速度慢LLM API延迟添加超时机制使用异步调用或缓存成本不可控频繁调用LLM实现调用频率限制添加成本监控和预算响应质量差Prompt设计不佳分析LLM输入输出优化Prompt工程8.3 任务执行问题排查问题现象可能原因排查方式解决方案任务卡在进行中异常未处理添加异常捕获和重试实现任务超时机制技能选择错误技能匹配逻辑问题记录技能选择过程添加多技能协作任务结果不一致技能实现有bug单元测试每个技能实现结果验证机制8.4 性能优化建议# performance_optimizations.py class OptimizedAgent(TaskOrientedAgent): def __init__(self, nameOptimizedAgent): super().__init__(name) self.response_cache {} # 响应缓存 self.cache_ttl 300 # 5分钟缓存 def perceive(self, input_text, user_iddefault_user): 带缓存的感知方法 # 生成缓存键 cache_key f{user_id}:{input_text} # 检查缓存 if cache_key in self.response_cache: cache_entry self.response_cache[cache_key] if time.time() - cache_entry[timestamp] self.cache_ttl: return cache_entry[response] # 正常处理 response super().perceive(input_text, user_id) # 更新缓存 self.response_cache[cache_key] { response: response, timestamp: time.time() } # 清理过期缓存 self._clean_expired_cache() return response def _clean_expired_cache(self): 清理过期缓存 current_time time.time() expired_keys [ key for key, entry in self.response_cache.items() if current_time - entry[timestamp] self.cache_ttl ] for key in expired_keys: del self.response_cache[key]9. 最佳实践与工程建议9.1 Agent设计原则单一职责原则每个组件只负责一个明确的功能开闭原则对扩展开放对修改关闭依赖倒置依赖抽象而非具体实现9.2 代码组织规范agent_project/ ├── agents/ # Agent核心类 │ ├── base_agent.py │ ├── rule_agent.py │ └── llm_agent.py ├── skills/ # 技能实现 │ ├── calculator.py │ ├── searcher.py │ └── analyzer.py ├── memory/ # 记忆管理 │ ├── short_term.py │ └── long_term.py ├── config/ # 配置文件 │ └── settings.py ├── tests/ # 测试代码 │ └── test_agents.py └── examples/ # 使用示例 └── demo.py9.3 生产环境注意事项错误处理每个外部调用都要有异常处理日志记录详细的运行日志便于排查问题性能监控监控响应时间和资源使用安全考虑验证输入防止注入攻击数据备份定期备份Agent