Python Ai Agent
Before diving into the code, let's establish a clear understanding: you can think of an AI Agent as an **intelligent program with a brain and hands**.\\\\\\\\n\\\\\\\\n* **Brain (Core)**: A model capable of **understanding, reasoning, and making decisions** (such as a Large Language Model LLM). It is responsible for processing information and making plans.\\\\\\\\n* **Perception (Input)**: The Agent acquires external information through its senses, such as user commands, database query results, web content, sensor data, etc.\\\\\\\\n* **Action (Output)**: The Agent affects the external world through its hands, for example, by calling a function, sending an email, outputting text on a screen, controlling a robotic arm, etc.\\\\\\\\n* **Goal**: All of the Agent's behaviors revolve around a clear **goal**, for example: check the weather in Beijing for tomorrow.\\\\\\\\n\\\\\\\\nIts core workflow is a classic **Perception-Thinking-Action** loop, as shown in the following figure:\\\\\\\\n\\\\\\\\n!(#)\\\\\\\\n\\\\\\\\n* * *\\\\\\\\n\\\\\\\\n## Simple Test Case\\\\\\\\n\\\\\\\\nagent-demo/ agent.py # Main implementation (provided below) tools.py # Tool implementation (can be a separate file) memory.py # Simple memory implementation (can be a separate file) README.md\\\\\\\\n\\\\\\\\n## Examples\\\\\\\\n\\\\\\\\n"""\\\\\\\\n\\\\\\\\n agent.py - Minimal AI Agent prototype (can be run directly)\\\\\\\\n\\\\\\\\n Description:\\\\\\\\n\\\\\\\\n - The LLM part is simulated using a very simple "rule-based responder", replace LLMInterface.generate(...) when actually connecting to an LLM\\\\\\\\n\\\\\\\\n - Included components: LLM abstraction, Brain (parsing/decision), Planner, Tool Registry, Memory, Executor\\\\\\\\n\\\\\\\\n """\\\\\\\\n\\\\\\\\nfrom typing import Any, Dict, List, Callable\\\\\\\\n\\\\\\\\nimport time\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\n# Memory (very lightweight)\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\nclass Memory:\\\\\\\\n\\\\\\\\ndef __init__ (self):\\\\\\\\n\\\\\\\\nself.short={}# Current session context\\\\\\\\n\\\\\\\\nself.long={}# Long-term preferences/contacts, etc.\\\\\\\\n\\\\\\\\ndef get_short(self, k, default=None):\\\\\\\\n\\\\\\\\nreturn self.short.get(k, default)\\\\\\\\n\\\\\\\\ndef set_short(self, k, v):\\\\\\\\n\\\\\\\\nself.short= v\\\\\\\\n\\\\\\\\ndef get_long(self, k, default=None):\\\\\\\\n\\\\\\\\nreturn self.long.get(k, default)\\\\\\\\n\\\\\\\\ndef set_long(self, k, v):\\\\\\\\n\\\\\\\\nself.long= v\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\n# LLM abstraction (replacement point)\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\nclass LLMInterface:\\\\\\\\n\\\\\\\\ndef generate(self, prompt: str) ->str:\\\\\\\\n\\\\\\\\n"""\\\\\\\\n\\\\\\\\n Here we provide a very simple rule-based simulated responder.\\\\\\\\n\\\\\\\\n For real use: replace with OpenAI/other model's calling code, returning the model text.\\\\\\\\n\\\\\\\\n """\\\\\\\\n\\\\\\\\n# Minimal parsing example: identify if "raining" needs to be determined\\\\\\\\n\\\\\\\\nif"whether or notRaining / If it rains"in prompt or"Raining / If it rains"in prompt:\\\\\\\\n\\\\\\\\nreturn"Please query Weather first; if there is Rain, please Generate reminder and send it to the target contact."\\\\\\\\n\\\\\\\\nif"Generate reminder"in prompt:\\\\\\\\n\\\\\\\\nreturn"Please / Directive markerremindXiao WangοΌtomorrowBeijinghasRainοΌPlease / Directive markerbring an umbrellaγ"\\\\\\\\n\\\\\\\\nreturn"I understand."\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\n# Tool registration and simulated tools\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\nclass ToolRegistry:\\\\\\\\n\\\\\\\\ndef __init__ (self):\\\\\\\\n\\\\\\\\nself.tools: Dict[str, Callable[..., Any]]={}\\\\\\\\n\\\\\\\\ndef register(self, name: str, fn: Callable[..., Any]):\\\\\\\\n\\\\\\\\nself.tools= fn\\\\\\\\n\\\\\\\\ndef call(self, name: str, *args, **kwargs):\\\\\\\\n\\\\\\\\nif name not in self.tools:\\\\\\\\n\\\\\\\\nraise ValueError(f"Tool not registered: {name}")\\\\\\\\n\\\\\\\\nreturn self.tools(*args, **kwargs)\\\\\\\\n\\\\\\\\n# Simulated tool: weather query (in reality, this would call a weather API)\\\\\\\\n\\\\\\\\ndef mock_weather_api(city: str, date: str) -> Dict[str, Any]:\\\\\\\\n\\\\\\\\n# Simple rule: if city contains "Beijing" and date contains "tomorrow", return rain example\\\\\\\\n\\\\\\\\nif"Beijing"in city and"tomorrow"in date:\\\\\\\\n\\\\\\\\nreturn{"city": city,"date": date,"cond": "Rain","precip_mm": 5}\\\\\\\\n\\\\\\\\nreturn{"city": city,"date": date,"cond": "Sunny","precip_mm": 0}\\\\\\\\n\\\\\\\\n# Simulated tool: send message (in reality, this would call SMS/email/WeCom, etc.)\\\\\\\\n\\\\\\\\ndef mock_send_message(contact: str, message: str) ->bool:\\\\\\\\n\\\\\\\\nprint(f" to={contact} message={message}")\\\\\\\\n\\\\\\\\nreturn True\\\\\\\\n\\\\\\\\n# Simulated tool: simple search (illustrative)\\\\\\\\n\\\\\\\\ndef mock_search(query: str) ->str:\\\\\\\\n\\\\\\\\nreturn f"Simulated search results: Regarding `{query}` information summary."\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\n# Planner / Executor\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\nclass SimplePlanner:\\\\\\\\n\\\\\\\\ndef plan(self, goal: str) -> List[Dict[str, Any]]:\\\\\\\\n\\\\\\\\n"""\\\\\\\\n\\\\\\\\n Break down the goal into a list of steps (very simplified implementation)\\\\\\\\n\\\\\\\\n Each step contains: action (tool name or internal action), params\\\\\\\\n\\\\\\\\n """\\\\\\\\n\\\\\\\\n steps =[]\\\\\\\\n\\\\\\\\n# Example: if the prompt contains "weather", generate two steps: check weather, decide and possibly send reminder\\\\\\\\n\\\\\\\\nif"Weather"in goal or"Raining / If it rains"in goal:\\\\\\\\n\\\\\\\\n steps.append({"action": "query_weather","params": {"city": "Beijing","date": "tomorrow"}})\\\\\\\\n\\\\\\\\n steps.append({"action": "decide_and_notify","params": {"contact_name": "Xiao Wang"}})\\\\\\\\n\\\\\\\\nelse:\\\\\\\\n\\\\\\\\n steps.append({"action": "search","params": {"query": goal}})\\\\\\\\n\\\\\\\\nreturn steps\\\\\\\\n\\\\\\\\nclass Executor:\\\\\\\\n\\\\\\\\ndef __init__ (self, tools: ToolRegistry, memory: Memory, llm: LLMInterface):\\\\\\\\n\\\\\\\\nself.tools= tools\\\\\\\\n\\\\\\\\nself.memory= memory\\\\\\\\n\\\\\\\\nself.llm= llm\\\\\\\\n\\\\\\\\ndef run_step(self, step: Dict[str, Any]):\\\\\\\\n\\\\\\\\n action = step\\\\\\\\n\\\\\\\\n params = step.get("params",{})\\\\\\\\n\\\\\\\\nif action =="query_weather":\\\\\\\\n\\\\\\\\n res =self.tools.call("weather", params, params)\\\\\\\\n\\\\\\\\nself.memory.set_short("last_weather", res)\\\\\\\\n\\\\\\\\nreturn res\\\\\\\\n\\\\\\\\nif action =="decide_and_notify":\\\\\\\\n\\\\\\\\n weather =self.memory.get_short("last_weather",{})\\\\\\\\n\\\\\\\\n# Simple rule-based decision\\\\\\\\n\\\\\\\\nif weather.get("cond")=="Rain":\\\\\\\\n\\\\\\\\n# Let LLM generate reminder text (example)\\\\\\\\n\\\\\\\\n prompt = f"Based on weather information:{weather}οΌGenerate a reminder to send to{params['contact_name']}reminder for."\\\\\\\\n\\\\\\\\n reminder =self.llm.generate(prompt)\\\\\\\\n\\\\\\\\n# Get contact info from long-term memory\\\\\\\\n\\\\\\\\n contact =self.memory.get_long(params)or"13800000000"\\\\\\\\n\\\\\\\\n ok =self.tools.call("send_message", contact, reminder)\\\\\\\\n\\\\\\\\nreturn{"notified": ok,"message": reminder}\\\\\\\\n\\\\\\\\nelse:\\\\\\\\n\\\\\\\\nreturn{"notified": False,"reason": "WeatherSunnyclear (weather)"}\\\\\\\\n\\\\\\\\nif action =="search":\\\\\\\\n\\\\\\\\nreturn self.tools.call("search", params)\\\\\\\\n\\\\\\\\nraise ValueError(f"Unknown action: {action}")\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\n# Agent Body\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\nclass SimpleAgent:\\\\\\\\n\\\\\\\\ndef __init__ (self):\\\\\\\\n\\\\\\\\nself.memory= Memory()\\\\\\\\n\\\\\\\\nself.tools= ToolRegistry()\\\\\\\\n\\\\\\\\nself.llm= LLMInterface()\\\\\\\\n\\\\\\\\nself.planner= SimplePlanner()\\\\\\\\n\\\\\\\\nself.executor= Executor(self.tools,self.memory,self.llm)\\\\\\\\n\\\\\\\\n# Register default tools\\\\\\\\n\\\\\\\\nself.tools.register("weather", mock_weather_api)\\\\\\\\n\\\\\\\\nself.tools.register("send_message", mock_send_message)\\\\\\\\n\\\\\\\\nself.tools.register("search", mock_search)\\\\\\\\n\\\\\\\\n# Assume Xiao Wang's contact info is stored in long-term memory\\\\\\\\n\\\\\\\\nself.memory.set_long("Xiao Wang","13911112222")\\\\\\\\n\\\\\\\\ndef handle(self, user_prompt: str):\\\\\\\\n\\\\\\\\n# 1) Brain parsing (using LLM abstraction)\\\\\\\\n\\\\\\\\n intent =self.llm.generate(user_prompt)\\\\\\\\n\\\\\\\\n# 2) Planning\\\\\\\\n\\\\\\\\n steps =self.planner.plan(user_prompt)\\\\\\\\n\\\\\\\\n# 3) Step-by-step execution\\\\\\\\n\\\\\\\\n results =[]\\\\\\\\n\\\\\\\\nfor step in steps:\\\\\\\\n\\\\\\\\n r =self.executor.run_step(step)\\\\\\\\n\\\\\\\\n results.append({"step": step,"result": r})\\\\\\\\n\\\\\\\\n# 4) Output merging\\\\\\\\n\\\\\\\\nreturn{"intent": intent,"steps": results}\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\n# Run example\\\\\\\\n\\\\\\\\n# -----------------------------\\\\\\\\n\\\\\\\\nif __name__ =="__main__":\\\\\\\\n\\\\\\\\n agent = SimpleAgent()\\\\\\\\n\\\\\\\\n task ="check / look uptomorrowBeijingof / 's (possessive particle)WeatherοΌifRaining / If it rainsοΌhelp me / for mewrite aremindand sendtoXiao Wangγ"\\\\\\\\n\\\\\\\\n out = agent.handle(task)\\\\\\\\n\\\\\\\\nimport json\\\\\\\\n\\\\\\\\nprint(json.dumps(out, ensure_ascii=False, indent=2))\\\\\\\\n\\\\\\\\n**Explanation:**\\\\\\\\n\\\\\\\\n1. **LLM Abstraction**: `LLMInterface.generate()` is the replacement point. Just replace this with code to connect to OpenAI, Claude, or a local LLM.\\\\\\\\n2. **Planner**: Responsible for breaking down natural language goals into ordered steps. For beginners, rules or templates can be used; for advanced use, LLM can output steps which are then parsed into actions.\\\\\\\\n3. **Tool Layer (Tools)**: Each tool is an independent function, uniformly registered in `ToolRegistry`. In real projects, these might be HTTP requests, SDK calls, database read/writes, etc.\\\\\\\\n4. **Memory**: Distinguishes between short-term/long-term. Short-term is used for intermediate results of the current task, long-term for contacts, preferences, etc.\\\\\\\\n5. **Executor**: Maps steps to tool calls and handles return values, failures, and retry logic.\\\\\\\\n\\\\\\\\n* * *\\\\\\\\n\\\\\\\\n## Build Your First AI Agent: Task Planning Assistant\\\\\\\\n\\\\\\\\nWe will build a **Task Planning Assistant**. Its goal is: given a complex task by the user (for example: I want to travel), automatically break it down into a series of ordered, executable specific steps.\\\\\\\\n\\\\\\\\nThe directory structure is as follows:\\\\\\\\n\\\\\\\\n!(#)\\\\\\\\n\\\\\\\\n### Step 1: Build the Intelligent Brain\\\\\\\\n\\\\\\\\nThe Agent's brain needs reasoning capabilities. We will use OpenAI's GPT model (via API call) as our Agent's brain.\\\\\\\\n\\\\\\\\nYou need to prepare an OpenAI API key, or you can use DeepSeek's API
YouTip