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

资讯详情

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

Python Agent 开发速通清单

Python Agent 开发速通清单 目录一、环境与工程对应 Maven/Gradle二、基础语法和 Java 不同的 7 个坑速查对照表1. 缩进即作用域没有 {}2. 变量是引用但不可变类型行为像值类3. 没有 / for(i0;i a 4. 字符串f-string 取代 String.format5. 字典 HashMap但语法是字面量6. 函数是一等公民可当参数传类似 Java 8 lambda7. 真值判断空容器、0、None 都是 False三、面向对象和 Java OO 的对照类与构造器私有没有真正的 private呼应你上一个问题接口 / 抽象类继承支持多继承 MRO四、类型系统dataclass 和 Pydanticagent 开发核心dataclass —— 对应 Java record轻量、快Pydantic —— 对应 Java record 校验agent 开发首选五、异常与资源管理try-with-resources → with 语句异常体系六、异步async/await对应 CompletableFuture / WebFlux七、装饰器对应 Java 注解 AOP八、Agent 核心一次完整的最小可用示例九、生态地图别全学按需挑前言约定每条都给 Java 对照 能跑的示例。你只需抓住和 Java 不一样的地方相同的地方直接跳过。一、环境与工程对应 Maven/GradleJava 概念Python 对应说明JDKPython 解释器用 3.10agent 生态最低要求Maven/Gradleuv 或 poetry别用裸pip依赖管理会乱pom.xmlpyproject.toml依赖与项目元信息都在这.m2本地仓库虚拟环境.venv每个项目隔离依赖Maven CentralPyPIuv add anthropic最快上手推荐 uv# 安装 uv一次 pip install uv # 建项目 uv init my-agent cd my-agent uv add anthropic # 类似 mvn install 写 pom uv run python main.py # 在隔离环境里跑关键差异Python 没有编译期类型检查。类型注解x: int只是提示运行时不校验。要真校验得靠 Pydantic下面会讲。二、基础语法和 Java 不同的 7 个坑速查对照表对象Python 规范示例Java 对比变量、函数snake_case蛇形user_nameuserName驼峰类PascalCase大驼峰ChatAgent一样常量UPPER_SNAKEMAX_RETRY一样模块文件lowercase/lower_with_underscoreagent_utils.py—包目录lowercase短、无下划线myagent全小写私有成员前缀__internal无约定俗成名字冲突/强制私有前缀____private—类型变量T/TypeVar单大写T,T_coT⚠️最大的坑Java 习惯用camelCase写变量名userNamePython 一律snake_caseuser_name。IDE 会标黄。1. 缩进即作用域没有{}# Java: if (x 0) { ... } # Python: 靠缩进 def check(x): if x 0: print(正数) # 4 空格缩进 在 if 内 print(总会执行) # 不缩进 if 外2. 变量是引用但不可变类型行为像值类a [1, 2, 3] b a # b 和 a 指向同一个 list类似 Java 引用 b.append(4) print(a) # [1, 2, 3, 4] —— a 也变了 # 想要副本 b a.copy() # 浅拷贝 b a[:] # 等价写法3. 没有/for(i0;in;i)# Java: for (int i 0; i 3; i) for i in range(3): print(i) # 0, 1, 2 # 遍历集合Java: for (String s : list) for item in [a, b, c]: print(item)4. 字符串f-string 取代String.formatname agent count 3 # Java: String.format(Hello %s, count%d, name, count) print(fHello {name}, count{count}) # f-string最常用 print(f{count:03d}) # 003格式化5. 字典 HashMap但语法是字面量# Java: MapString, Integer map new HashMap(); d {a: 1, b: 2} d[c] 3 print(d.get(z, 0)) # 不存在返回默认值 0类似 getOrDefault6. 函数是一等公民可当参数传类似 Java 8 lambda# Java: list.stream().map(x - x * 2).collect(...) nums [1, 2, 3] doubled [x * 2 for x in nums] # 列表推导最 Pythonic doubled list(map(lambda x: x * 2, nums)) # 也能这么写但不推荐7. 真值判断空容器、0、None 都是False# Java: if (list ! null !list.isEmpty()) lst [] if lst: # 非空为真无需判空 print(有元素) if not lst: print(空) # 打印这个三、面向对象和 Java OO 的对照类与构造器# Java: # public class User { # private String name; private int age; # public User(String name, int age) { ... } # } class User: def __init__(self, name: str, age: int): # 构造器self this self.name name self.age age u User(bot, 3) print(u.name)self必须显式写第一个参数Java 的this是隐式的。这是新手最容易忘的。私有没有真正的private呼应你上一个问题class Agent: def __init__(self): self.name bot # public self._config {} # 约定私有单下划线 self.__secret key # 名称改写双下划线→ 实际叫 _Agent__secret # 没有 private 关键字全靠约定。你上一题的报错就是这个。接口 / 抽象类from abc import ABC, abstractmethod # Java: interface Tool { String run(String input); } class Tool(ABC): # ABC Abstract Base Class abstractmethod def run(self, input: str) - str: ... class SearchTool(Tool): def run(self, input: str) - str: # 必须实现 return fsearching {input}还有更轻的 Protocol结构化类型类似 TypeScript interface / Go 接口不要求显式继承——agent 框架里很常见from typing import Protocol class ToolLike(Protocol): def run(self, input: str) - str: ... # 只定义形状不继承也能匹配继承支持多继承 MROclass Base: def greet(self): return base class Mixin: def log(self): print(logged) class Agent(Base, Mixin): # 多继承Java 不支持 pass a Agent() a.greet() # base a.log() # logged四、类型系统dataclass和Pydanticagent 开发核心Agent 开发要大量定义消息结构 / 工具参数 / API 响应。Java 用 record / POJOPython 用这两个。dataclass —— 对应 Java record轻量、快from dataclasses import dataclass # Java: public record User(String name, int age) {} dataclass class User: name: str age: int 18 # 默认值 u User(bot) print(u) # User(namebot, age18) —— 自动 __repr__Pydantic —— 对应 Java record 校验agent 开发首选from pydantic import BaseModel, Field class ToolArgs(BaseModel): query: str Field(..., min_length1, max_length100) limit: int Field(10, ge1, le50) # ge大于等于le小于等于 # 自动校验 报错运行时真正校验这是和 dataclass 的关键区别 args ToolArgs(queryhello, limit5) print(args.model_dump()) # {query: hello, limit: 5} # ToolArgs(query) # ❌ 校验失败抛 ValidationError # ToolArgs(queryx, limit0) # ❌ limit 必须 1为什么 agent 开发离不开 Pydantic LLM 返回的是 JSON你要把它映射成 Python 对象并校验。几乎所有 agent 框架LangChain、Anthropic SDK 的结构化输出底层都是 Pydantic。五、异常与资源管理try-with-resources →with语句# Java: # try (var br new BufferedReader(new FileReader(f.txt))) { ... } with open(data.txt, r, encodingutf-8) as f: # 退出 with 自动关闭 content f.read() # 这里 f 已关闭无需 finally异常体系# Java: try { ... } catch (IOException e) { ... } finally { ... } try: result 10 / 0 except ZeroDivisionError as e: # 捕获具体异常 print(f除零: {e}) except (ValueError, TypeError): # 多个异常一起捕获 print(类型错误) except Exception as e: # 兜底类似 catch Throwable print(f其他: {e}) else: print(无异常时执行) finally: print(总执行)Python 异常不要求声明或捕获没有 checked exception。这更灵活但也意味着你得主动列出可能出错的点不能靠编译器提醒。六、异步async/await对应 CompletableFuture / WebFluxAgent 经常要并发调多个工具或 LLM异步是必修。import asyncio import anthropic # Java CompletableFuture: # CompletableFuture.supplyAsync(() - callA()) # .thenCombine(CompletableFuture.supplyAsync(() - callB()), ...) async def call_llm(prompt: str) - str: client anthropic.AsyncAnthropic() # 异步客户端 resp await client.messages.create( # await 阻塞等待不占线程 modelclaude-opus-5, max_tokens1024, messages[{role: user, content: prompt}], ) return resp.content[0].text async def main(): # 并发执行多个类似 CompletableFuture.allOf results await asyncio.gather( call_llm(写一句诗), call_llm(写一句歌词), ) print(results) asyncio.run(main()) # 启动事件循环入口必须这么调三条铁律async def定义的函数必须用await调用不能直接call()。await只能在async def内部。事件循环入口脚本顶层用asyncio.run(main())。七、装饰器对应 Java 注解 AOPPython 装饰器是真正的函数包装不像 Java 注解只是标记。import time from functools import wraps # Java AOP Around 思路在方法前后插逻辑 def log_time(func): wraps(func) def wrapper(*args, **kwargs): start time.time() result func(*args, **kwargs) print(f{func.__name__} 耗时 {time.time()-start:.2f}s) return result return wrapper log_time # 等价于 search log_time(search) def search(q): time.sleep(0.5) return f结果: {q} search(hello) # 打印: search 耗时 0.50sAgent 框架大量用装饰器注册工具例如 Anthropic SDK 的beta_tool。把它理解成声明这个函数是个工具 自动生成参数 schema。八、Agent 核心一次完整的最小可用示例下面用 Anthropic 官方 SDK 做一个带工具调用的 agent loop——这是 agent 开发的本质LLM 决定调什么工具 → 你执行 → 把结果喂回去 → 循环直到完成。# pip install anthropic import anthropic client anthropic.Anthropic() # 读 ANTHROPIC_API_KEY 环境变量 # 1) 定义工具LLM 看得懂的函数签名 tools [{ name: get_weather, description: 查询某城市天气, input_schema: { type: object, properties: { city: {type: string, description: 城市名}, }, required: [city], }, }] # 2) 实际执行工具的 Python 函数 def get_weather(city: str) - str: # 真实场景里这里调天气 API return f{city} 今天 25°C 晴 # 3) Agent 主循环 def run_agent(user_input: str): messages [{role: user, content: user_input}] while True: # agent loop resp client.messages.create( modelclaude-opus-5, max_tokens1024, toolstools, messagesmessages, ) # 4) LLM 想调工具 → stop_reason tool_use if resp.stop_reason tool_use: # 把 assistant 这轮含 tool_use 块加回历史 messages.append({role: assistant, content: resp.content}) # 执行所有被请求的工具把结果作为 user 消息回传 tool_results [] for block in resp.content: if block.type tool_use: result get_weather(**block.input) # ** 解包字典为参数 tool_results.append({ type: tool_result, tool_use_id: block.id, content: result, }) messages.append({role: user, content: tool_results}) # 继续 while让 LLM 看到工具结果后决定下一步 else: # 5) 不再需要工具 → end_turn输出最终回答 for block in resp.content: if block.type text: print(block.text) return run_agent(北京天气怎么样)这段就是 agent 的全部内核。不管框架多花哨本质都是这个while循环。理解了它LangChain / LangGraph / Anthropic Tool Runner 都只是这个循环的不同封装。九、生态地图别全学按需挑层工具类比何时用LLM SDKanthropic直接调 API最底层、最可控先掌握这个Agent 框架LangGraph工作流引擎多步骤、带状态的复杂 agentAgent 框架LangChainSpring 全家桶功能多但重不建议入门Web 框架FastAPISpring Boot把 agent 包成 HTTP 服务数据校验PydanticBean Validation必学FastAPI/agent 都依赖它包管理uvMaven必学测试pytestJUnit语法最简assert即测试
返回列表