Python 基础知识点大全(50 + LangGraph 扩展)
引言:Python 语法速查手册
本节汇总了 Python 最核心的 50 个知识点,涵盖从最基础的 print() 到高级的正则表达式。无论你是初学者还是有经验的开发者,这份手册都可以作为快速查阅的参考。
🎯 小白理解:为什么要学这么多知识点?
想象你在学一门新语言(比如英语):
- 单词 = Python 的各种语法元素(变量、函数、类...)
- 语法规则 = 如何组合这些元素
- 常用表达 = 这 50 个知识点
就像你不需要背完整本字典才能说英语一样,掌握这 50 个核心知识点,你就能用 Python 做大部分事情了!
学习目标
- ✅ 快速回顾 Python 核心语法
- ✅ 理解每个知识点的应用场景
- ✅ 掌握常用的代码模式和最佳实践
- ✅ 为后续的 AI 开发打下坚实基础
第一部分:基础语法(1-10)
1. Print 语句
print() 是 Python 最基础的输出函数,用于在控制台显示信息。
print('Hello, World!')输出:
Hello, World!💡 小贴士:调试代码时,
print()是最简单直接的方法。在 AI 开发中,我们经常用它来查看模型的输出结果。
2. 变量
变量是存储数据的"容器",可以在程序中随时使用。
x = 10
y = 20
print(x + y)输出:
30🎯 小白理解:变量就像"带标签的盒子"
x = 10意思是"在名为 x 的盒子里放入数字 10"- 之后说
x,Python 就知道你指的是盒子里的 10
3. 数据类型
Python 有四种最常用的基本数据类型:
| 类型 | 英文 | 示例 | 用途 |
|---|---|---|---|
| 整数 | int | 42 | 计数、索引 |
| 浮点数 | float | 3.14 | 小数计算 |
| 字符串 | str | 'Hello' | 文本处理 |
| 布尔值 | bool | True/False | 逻辑判断 |
num = 42
pi = 3.14
name = 'Alice'
is_active = True
print(type(num), type(pi), type(name), type(is_active))输出:
<class 'int'> <class 'float'> <class 'str'> <class 'bool'>4. 列表(List)
列表是有序、可变的数据集合,用方括号 [] 表示。
fruits = ['apple', 'banana', 'cherry']
print(fruits[1]) # 访问第二个元素(索引从 0 开始)
# 列表可以包含不同类型的元素
mixed_list = ['a', 1, True, [2, 3, 4]]输出:
banana🎯 小白理解:索引从 0 开始
fruits = ['apple', 'banana', 'cherry'] ↑ ↑ ↑ 索引0 索引1 索引2这是编程界的通用规则,虽然一开始会不习惯,但用久了就自然了。
5. 元组(Tuple)
元组是有序、不可变的数据集合,用圆括号 () 表示。
dimensions = (1920, 1080)
print(dimensions)输出:
(1920, 1080)💡 元组 vs 列表:
- 列表:可以增删改,适合动态数据
- 元组:创建后不能修改,适合固定数据(如屏幕分辨率、坐标点)
6. 字典(Dictionary)
字典存储键值对数据,用花括号 {} 表示。
person = {'name': 'Alice', 'age': 25}
print(person['name'])
# 字典可以嵌套更复杂的结构
data = {'names': ['Alice', 'Bob'], 'ages': [25, 24]}
import pandas as pd
df = pd.DataFrame(data)
print(df)输出:
Alice
names ages
0 Alice 25
1 Bob 24🔗 与 AI 的联系:JSON 格式本质上就是字典的文本表示,AI API 的请求和响应几乎都是 JSON 格式。
7. 集合(Set)
集合是无序、不重复的数据集合。
unique_numbers = {1, 2, 3, 2} # 重复的 2 会被自动去除
print(unique_numbers)输出:
{1, 2, 3}💡 使用场景:去重、检查元素是否存在(比列表更快)
8. 条件语句
使用 if、elif、else 进行条件判断。
x = 10
if x > 5:
print('x 大于 5')
elif x == 5:
print('x 等于 5')
else:
print('x 小于 5')输出:
x 大于 5⚠️ 注意缩进:Python 使用缩进(通常是 4 个空格)来表示代码块,缩进错误会导致语法错误。
9. 循环
使用 for 或 while 循环重复执行代码。
# for 循环
for i in range(5):
print(i)输出:
0
1
2
3
4🎯 小白理解:
range(5)生成 0, 1, 2, 3, 4注意不包括 5!这是 Python 的"左闭右开"原则:
range(0, 5)=[0, 5)
10. 函数
函数是可复用的代码块,用 def 关键字定义。
def greet(name):
return f'Hello, {name}!'
print(greet('Alice'))输出:
Hello, Alice!💡 f-string:
f'Hello, {name}!'是 Python 3.6+ 的格式化字符串,{}中的变量会被自动替换。
第二部分:面向对象与进阶语法(11-20)
11. 类和对象
Python 支持面向对象编程,用 class 定义类。
class Person:
def __init__(self, name, age):
self.name = name # 属性
self.age = age # 属性
person = Person('Alice', 25)
print(person.name, person.age)输出:
Alice 25🎯 小白理解:类 vs 对象
- 类(Class):设计图纸(比如"人"的定义)
- 对象(Object):根据图纸造出来的实物(比如"Alice")
__init__是构造函数,创建对象时自动调用
12. 列表推导式
用一行代码创建列表,简洁高效。
squares = [x**2 for x in range(10)]
print(squares)输出:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]💡 语法解析:
python[表达式 for 变量 in 可迭代对象]等价于:
pythonresult = [] for 变量 in 可迭代对象: result.append(表达式)
13. 文件处理
使用 open() 函数读写文件。
# 写入文件
with open('example.txt', 'w') as file:
file.write('Hello, World!')
# 读取文件
with open('example.txt', 'r') as file:
print(file.read())输出:
Hello, World!💡 使用
with的好处:自动关闭文件,即使发生错误也能正确处理。
14. 异常处理
使用 try、except、finally 处理错误。
try:
result = 10 / 0
except ZeroDivisionError:
print('不能除以零')
finally:
print('执行完毕')输出:
不能除以零
执行完毕💡 三个关键字的作用:
try:尝试执行可能出错的代码except:如果出错了,执行这里的代码finally:无论是否出错,最后都会执行
15. 模块导入
使用 import 导入外部模块。
import math
print(math.sqrt(16))输出:
4.016. Lambda 函数
匿名函数,适合简单的一次性操作。
square = lambda x: x**2
print(square(5))输出:
25💡 语法:
lambda 参数: 表达式等价于:
pythondef square(x): return x**2
17. Map 函数
将函数应用到可迭代对象的每个元素。
numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x**2, numbers))
print(squared)输出:
[1, 4, 9, 16]18. Filter 函数
根据条件过滤可迭代对象的元素。
numbers = [1, 2, 3, 4]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)输出:
[2, 4]19. Reduce 函数
对序列进行累积计算。
from functools import reduce
numbers = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, numbers)
print(product) # 1 * 2 * 3 * 4 = 24输出:
2420. 生成器
使用 yield 逐个产出值,节省内存。
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
for number in count_up_to(5):
print(number)输出:
1
2
3
4
5💡 生成器 vs 列表:
- 列表:一次性创建所有元素,占用大量内存
- 生成器:用到一个才生成一个,节省内存
第三部分:函数进阶(21-25)
21. 默认参数
函数参数可以有默认值。
def greet(name, message='Hello'):
return f'{message}, {name}!'
print(greet('Alice'))
print(greet('Bob', 'Hi'))输出:
Hello, Alice!
Hi, Bob!22. 可变参数(*args 和 **kwargs)
使用 * 和 ** 接收任意数量的参数。
def add(*args):
return sum(args)
print(add(1, 2, 3, 4))输出:
10💡 参数解包:
*args:接收任意数量的位置参数,打包成元组**kwargs:接收任意数量的关键字参数,打包成字典
23. F-String 格式化
Python 3.6+ 的字符串格式化语法。
name = 'Alice'
age = 25
print(f'{name} is {age} years old.')输出:
Alice is 25 years old.24. Enumerate 函数
同时获取索引和值。
names = ['Alice', 'Bob', 'Charlie']
for index, name in enumerate(names):
print(index, name)输出:
0 Alice
1 Bob
2 Charlie25. Zip 函数
将多个可迭代对象"拉链式"组合。
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
for item1, item2 in zip(list1, list2):
print(item1, item2)输出:
1 a
2 b
3 c第四部分:数据操作(26-35)
26. 列表切片
使用切片语法提取列表的子集。
numbers = [0, 1, 2, 3, 4, 5]
print(numbers[1:4]) # 索引 1 到 3
print(numbers[:3]) # 开头到索引 2
print(numbers[::2]) # 每隔一个元素输出:
[1, 2, 3]
[0, 1, 2]
[0, 2, 4]💡 切片语法:
[start:end:step]
start:起始索引(包含)end:结束索引(不包含)step:步长
27. 字符串方法
字符串有很多实用的内置方法。
text = ' Hello World '
print(text.strip()) # 去除首尾空格
print(text.upper()) # 转大写
print(text.lower()) # 转小写输出:
Hello World
HELLO WORLD
hello world28. 列表方法
列表的常用操作方法。
numbers = [1, 2, 3]
numbers.append(4) # 添加元素
numbers.remove(2) # 删除元素
print(numbers)输出:
[1, 3, 4]29. 布尔逻辑
使用 and、or、not 组合条件。
x = 10
y = 20
print(x > 5 and y < 25) # 两个都为真才为真
print(not (x > y)) # 取反输出:
True
True30. 嵌套循环
循环内部可以再嵌套循环。
for i in range(3):
for j in range(2):
print(f'i={i}, j={j}')输出:
i=0, j=0
i=0, j=1
i=1, j=0
i=1, j=1
i=2, j=0
i=2, j=131. Range 函数
生成数字序列。
for number in range(5):
print(number)输出:
0
1
2
3
4💡 range 的三种用法:
range(5)→ 0, 1, 2, 3, 4range(2, 5)→ 2, 3, 4range(0, 10, 2)→ 0, 2, 4, 6, 8
32. 递归
函数调用自身来解决问题。
def factorial(n):
if n == 1:
return 1
return n * factorial(n - 1)
print(factorial(5)) # 5! = 5 × 4 × 3 × 2 × 1 = 120输出:
12033. 从模块导入特定函数
使用 from ... import ... 语法。
from math import sqrt
print(sqrt(16))输出:
4.034. Assert 断言
用于调试时检查条件是否成立。
x = 5
assert x > 0, 'x 必须是正数'
print('断言通过!')输出:
断言通过!⚠️ 注意:如果断言失败,程序会抛出
AssertionError。
35. 浅拷贝 vs 深拷贝
理解对象复制的两种方式。
import copy
original = [1, [2, 3]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
# 修改原始列表中的嵌套列表
original[1][0] = 99
print('浅拷贝:', shallow) # 嵌套列表被影响
print('深拷贝:', deep) # 嵌套列表不受影响输出:
浅拷贝: [1, [99, 3]]
深拷贝: [1, [2, 3]]🎯 小白理解:
- 浅拷贝:只复制外层,内层还是共享的
- 深拷贝:完全复制,包括所有嵌套结构
第五部分:运算符与内置函数(36-45)
36. is 运算符
检查两个变量是否指向同一个对象。
a = [1, 2, 3]
b = a # b 指向 a 的同一个列表
c = [1, 2, 3] # c 是新的列表
print(a is b) # True,同一个对象
print(a is c) # False,不同对象,虽然内容相同输出:
True
False💡 is vs ==:
is:检查是否是同一个对象==:检查值是否相等
37. in 运算符
检查值是否存在于可迭代对象中。
fruits = ['apple', 'banana', 'cherry']
print('apple' in fruits)
print('grape' in fruits)输出:
True
False38. del 语句
删除变量或列表中的元素。
numbers = [1, 2, 3, 4]
del numbers[2] # 删除索引为 2 的元素
print(numbers)输出:
[1, 2, 4]39. 字典推导式
用一行代码创建字典。
squared = {x: x**2 for x in range(5)}
print(squared)输出:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}40. 上下文管理器(with 语句)
使用 with 高效管理资源。
with open('example.txt', 'w') as file:
file.write('Hello, World!')
# 文件会自动关闭41. 迭代器
使用 iter() 和 next() 手动迭代。
numbers = iter([1, 2, 3, 4])
print(next(numbers))
print(next(numbers))输出:
1
242. any 和 all 函数
检查可迭代对象中的元素。
numbers = [1, 0, 3, 4]
print(any(numbers)) # True,至少有一个非零
print(all(numbers)) # False,因为有 0输出:
True
False43. sorted 排序
对可迭代对象进行排序。
numbers = [3, 1, 4, 1, 5, 9]
print(sorted(numbers))
print(sorted(numbers, reverse=True))输出:
[1, 1, 3, 4, 5, 9]
[9, 5, 4, 3, 1, 1]44. 使用 key 参数排序
对复杂结构进行自定义排序。
data = [
{'name': 'Alice', 'age': 25},
{'name': 'Bob', 'age': 20}
]
sorted_data = sorted(data, key=lambda x: x['age'])
print(sorted_data)输出:
[{'name': 'Bob', 'age': 20}, {'name': 'Alice', 'age': 25}]45. 命名元组
使用 collections.namedtuple 创建带字段名的元组。
from collections import namedtuple
Point = namedtuple('Point', 'x y')
point = Point(10, 20)
print(point.x, point.y)输出:
10 20第六部分:高级工具(46-50)
46. Counter 计数器
统计元素出现次数。
from collections import Counter
numbers = [1, 2, 2, 3, 3, 3]
count = Counter(numbers)
print(count)输出:
Counter({3: 3, 2: 2, 1: 1})47. defaultdict 默认字典
自动处理不存在的键。
from collections import defaultdict
def_dict = defaultdict(int) # 默认值为 0
def_dict['a'] += 1
print(def_dict)输出:
defaultdict(<class 'int'>, {'a': 1})48. 时间测量
使用 time 模块测量代码执行时间。
import time
start = time.time()
result = sum(range(1000000))
end = time.time()
print(f'执行时间: {end - start:.4f} 秒')49. 正则表达式
使用 re 模块进行模式匹配。
import re
text = 'My phone number is 123-456-7890.'
match = re.search(r'\d{3}-\d{3}-\d{4}', text)
print(match.group())输出:
123-456-7890💡 正则表达式入门:
\d匹配数字{3}表示重复 3 次\d{3}-\d{3}-\d{4}匹配 xxx-xxx-xxxx 格式的电话号码
50. 全局与局部变量
理解变量的作用域。
x = 'global'
def func():
x = 'local'
print('函数内部:', x)
func()
print('函数外部:', x)输出:
函数内部: local
函数外部: global🎯 小白理解:作用域
- 全局变量:在函数外部定义,整个程序都能访问
- 局部变量:在函数内部定义,只在函数内有效
- 函数内部可以"看到"外部变量,但默认不会修改它
本章总结
知识点分类速查表
| 类别 | 知识点 |
|---|---|
| 基础语法 | print, 变量, 数据类型, 条件语句, 循环, 函数 |
| 数据结构 | 列表, 元组, 字典, 集合 |
| 面向对象 | 类, 对象, __init__ |
| 函数进阶 | lambda, 默认参数, *args, **kwargs |
| 函数式编程 | map, filter, reduce, 列表推导式 |
| 文件与异常 | open, with, try/except |
| 高级工具 | 生成器, 迭代器, 正则表达式 |
| 常用模块 | math, time, copy, collections, re |
学习建议
- 多练习:每个知识点都动手敲一遍代码
- 理解原理:不只是记住语法,要理解为什么这样设计
- 实际应用:尝试在小项目中使用这些知识点
- 查阅文档:遇到问题时,多查阅 Python 官方文档
思考题
is和==有什么区别?在什么情况下会产生不同的结果?- 浅拷贝和深拷贝分别适用于什么场景?
- 生成器相比列表有什么优势?什么时候应该使用生成器?
try...except...finally中的finally块一定会执行吗?
下一步
掌握了这 50 个核心知识点后,你已经具备了扎实的 Python 基础。接下来,让我们把这些知识应用到 AI Agent 开发中!
Part 2: LangGraph 1.x 扩展 - 从 Python 基础到 AI Agent 开发
LangGraph 是 LangChain 团队开发的图结构框架,用于构建有状态的、多参与者的 AI 应用程序。本部分将结合前面学到的 Python 基础知识,逐步介绍 LangGraph 的核心概念。
核心概念预览:
- StateGraph: 状态图 - 管理工作流的核心结构
- Nodes: 节点 - 执行具体任务的函数
- Edges: 边 - 定义节点间的执行流程
- State: 状态 - 在节点间传递的共享数据
51. LangGraph 安装与环境配置
首先安装 LangGraph 1.x 及相关依赖。
# 安装 LangGraph (如果尚未安装)
# !pip install -U langgraph langchain-openai
# 验证安装
import langgraph
print(f"LangGraph 版本: {langgraph.__version__}")💡 小贴士:LangGraph 1.x 版本带来了许多改进,包括更简洁的 API 和更强大的状态管理功能。
52. State 状态管理 - 从字典到 TypedDict
回顾前面学的字典(Dict),LangGraph 使用 TypedDict 来定义强类型的状态结构。这是 Python 类型提示系统的扩展,让我们能够定义具有特定键和值类型的字典。
from typing import TypedDict, Annotated
from operator import add
# 回顾: 普通字典
person_dict = {'name': 'Alice', 'age': 25}
print(f"普通字典: {person_dict}")
# LangGraph 风格: 使用 TypedDict 定义状态结构
class PersonState(TypedDict):
name: str
age: int
messages: list[str]
# 创建符合类型定义的状态
person_state: PersonState = {
'name': 'Alice',
'age': 25,
'messages': ['Hello']
}
print(f"TypedDict 状态: {person_state}")输出:
普通字典: {'name': 'Alice', 'age': 25}
TypedDict 状态: {'name': 'Alice', 'age': 25, 'messages': ['Hello']}🔗 与 Python 基础的联系:TypedDict 本质上还是字典,只是加了类型标注,让代码更清晰、更容易维护。
53. Annotated 类型与 Reducer 函数
在 LangGraph 中,使用 Annotated 来指定状态更新的方式。回顾前面的 reduce 函数,这里的 reducer 概念类似 - 它定义了如何将新值与旧值合并。
# 回顾 reduce 函数: 将序列逐步合并
from functools import reduce
numbers = [1, 2, 3, 4]
total = reduce(lambda x, y: x + y, numbers)
print(f"Reduce 结果: {total}")
# LangGraph 中的 Reducer: 使用 Annotated 定义状态如何更新
from typing import Annotated
class ChatState(TypedDict):
# messages 字段使用 add 作为 reducer
# 每次更新时,新消息会追加到列表而不是替换
messages: Annotated[list[str], add]
# 模拟状态更新过程
state1 = {'messages': ['Hello']}
update = {'messages': ['How are you?']}
# reducer 会执行: add(['Hello'], ['How are you?']) = ['Hello', 'How are you?']
merged = {'messages': state1['messages'] + update['messages']}
print(f"合并后的消息: {merged['messages']}")输出:
Reduce 结果: 10
合并后的消息: ['Hello', 'How are you?']🎯 小白理解:Reducer 决定"新旧值怎么合并"
- 默认行为:新值覆盖旧值
- 使用 add reducer:新值追加到旧值列表后面
- 这对于保存对话历史非常有用!
54. StateGraph 状态图 - 结合类与函数
StateGraph 是 LangGraph 的核心类,它管理整个工作流程。回顾前面的类(Classes)和函数(Functions),StateGraph 就是一个管理节点和边的类。
from langgraph.graph import StateGraph, START, END
# 定义状态结构 (类似于定义一个数据模型)
class SimpleState(TypedDict):
value: int
history: Annotated[list[str], add]
# 创建 StateGraph 实例,传入状态类型
graph_builder = StateGraph(SimpleState)
print(f"StateGraph 类型: {type(graph_builder)}")
print("StateGraph 已创建,接下来可以添加节点和边")输出:
StateGraph 类型: <class 'langgraph.graph.state.StateGraph'>
StateGraph 已创建,接下来可以添加节点和边55. Nodes 节点 - 函数作为处理单元
在 LangGraph 中,节点(Node) 就是处理状态的函数。回顾前面的函数定义,每个节点接收当前状态,返回状态更新。
# 节点函数: 接收 state,返回更新
def double_value(state: SimpleState) -> dict:
"""将 value 翻倍"""
new_value = state['value'] * 2
return {
'value': new_value,
'history': [f'doubled to {new_value}']
}
def add_ten(state: SimpleState) -> dict:
"""将 value 加 10"""
new_value = state['value'] + 10
return {
'value': new_value,
'history': [f'added 10, now {new_value}']
}
# 将节点添加到图中
graph_builder.add_node("double", double_value)
graph_builder.add_node("add_ten", add_ten)
print("已添加两个节点: 'double' 和 'add_ten'")🔗 与 Python 基础的联系:节点就是普通的 Python 函数!只需要接收状态字典,返回更新字典。
56. Edges 边 - 定义执行流程
边(Edge) 定义节点之间的连接关系,决定执行顺序。这类似于前面学的程序控制流,但以图结构表示。
LangGraph 中有三种边:
- 普通边: 直接从一个节点到另一个节点
- START 边: 定义图的入口点
- END 边: 定义图的终止点
# 添加边: 定义执行流程
# START -> double -> add_ten -> END
graph_builder.add_edge(START, "double") # 从起点到 double 节点
graph_builder.add_edge("double", "add_ten") # 从 double 到 add_ten
graph_builder.add_edge("add_ten", END) # 从 add_ten 到终点
# 编译图 - 使其可执行
simple_graph = graph_builder.compile()
print("图结构: START -> double -> add_ten -> END")
print("图已编译完成,可以执行了!")57. 执行图 - invoke 方法
使用 invoke() 方法执行编译后的图,传入初始状态。
# 执行图
initial_state = {
'value': 5,
'history': ['started with 5']
}
result = simple_graph.invoke(initial_state)
print(f"初始值: 5")
print(f"最终值: {result['value']}") # 5 * 2 + 10 = 20
print(f"执行历史: {result['history']}")输出:
初始值: 5
最终值: 20
执行历史: ['started with 5', 'doubled to 10', 'added 10, now 20']💡 理解执行流程:
- 初始值 5 →
double节点 → 变成 10- 值 10 →
add_ten节点 → 变成 20history使用 add reducer,所以每次更新都追加记录
58. Conditional Edges 条件边 - 结合条件语句
条件边 是 LangGraph 最强大的功能之一,它允许根据状态动态决定下一步执行哪个节点。回顾前面的 if/elif/else 条件语句,条件边将这个概念应用到图结构中。
from typing import Literal
# 定义带有条件路由的状态
class RouterState(TypedDict):
value: int
route: str
result: str
# 路由函数: 根据状态决定下一个节点
def decide_route(state: RouterState) -> str:
"""根据 value 决定走哪条路"""
# 这就像 if/elif/else,但返回节点名称
if state['value'] > 100:
return "big_handler"
elif state['value'] > 10:
return "medium_handler"
else:
return "small_handler"
# 各个处理节点
def big_handler(state: RouterState) -> dict:
return {'result': f"处理大数值: {state['value']}"}
def medium_handler(state: RouterState) -> dict:
return {'result': f"处理中等数值: {state['value']}"}
def small_handler(state: RouterState) -> dict:
return {'result': f"处理小数值: {state['value']}"}
# 创建带条件边的图
router_graph = StateGraph(RouterState)
# 添加所有节点
router_graph.add_node("big_handler", big_handler)
router_graph.add_node("medium_handler", medium_handler)
router_graph.add_node("small_handler", small_handler)
# 添加条件边: 从 START 根据 decide_route 函数决定去哪个节点
router_graph.add_conditional_edges(
START, # 从哪里开始
decide_route, # 路由函数
{ # 可能的目标节点
"big_handler": "big_handler",
"medium_handler": "medium_handler",
"small_handler": "small_handler"
}
)
# 所有处理节点都连接到 END
router_graph.add_edge("big_handler", END)
router_graph.add_edge("medium_handler", END)
router_graph.add_edge("small_handler", END)
# 编译并测试
conditional_graph = router_graph.compile()
# 测试不同的输入
test_cases = [5, 50, 500]
for value in test_cases:
result = conditional_graph.invoke({
'value': value,
'route': '',
'result': ''
})
print(f"输入 {value} -> {result['result']}")输出:
输入 5 -> 处理小数值: 5
输入 50 -> 处理中等数值: 50
输入 500 -> 处理大数值: 500🎯 小白理解:条件边就是"分岔路"
想象你在走迷宫,遇到岔路口时需要根据某些条件(比如手里的钥匙颜色)选择走哪条路。条件边就是这个选择过程。
59. MessagesState - LangGraph 内置消息状态
LangGraph 提供了内置的 MessagesState,专门用于处理对话消息。这是构建聊天机器人和 AI Agent 的基础。
from langgraph.graph import MessagesState
# MessagesState 等同于:
# class MessagesState(TypedDict):
# messages: Annotated[list[BaseMessage], add]
# 示例: 使用 MessagesState 创建简单的回显机器人
def echo_bot(state: MessagesState) -> dict:
"""简单的回显机器人 - 重复用户的最后一条消息"""
last_message = state['messages'][-1]
# 获取消息内容
if hasattr(last_message, 'content'):
content = last_message.content
else:
content = last_message.get('content', str(last_message))
return {
'messages': [{'role': 'assistant', 'content': f'你说的是: {content}'}]
}
# 创建回显机器人图
echo_graph = StateGraph(MessagesState)
echo_graph.add_node("echo", echo_bot)
echo_graph.add_edge(START, "echo")
echo_graph.add_edge("echo", END)
echo_app = echo_graph.compile()
# 测试
result = echo_app.invoke({
'messages': [{'role': 'user', 'content': 'Hello, LangGraph!'}]
})
print(f"用户: Hello, LangGraph!")
print(f"机器人: {result['messages'][-1].content}")60. 工具调用 Agent - 完整示例
这是一个完整的 LangGraph Agent 示例,展示如何:
- 定义工具 (Tools)
- 创建工具执行节点
- 使用条件边实现循环
from typing import Literal
# 定义工具 - 使用 Python 函数
def calculator(expression: str) -> str:
"""计算数学表达式"""
try:
result = eval(expression)
return f"计算结果: {expression} = {result}"
except:
return "计算错误"
def get_weather(city: str) -> str:
"""获取天气信息 (模拟)"""
weather_data = {
"北京": "晴天 25°C",
"上海": "多云 22°C",
"深圳": "小雨 28°C"
}
return weather_data.get(city, f"{city}天气数据暂不可用")
# Agent 状态
class AgentState(TypedDict):
messages: Annotated[list, add]
tool_calls: list
tool_results: list
# 判断是否需要调用工具
def should_continue(state: AgentState) -> Literal["tools", "end"]:
"""检查是否有工具调用请求"""
if state.get('tool_calls') and len(state['tool_calls']) > 0:
return "tools"
return "end"
# 工具执行节点
def execute_tools(state: AgentState) -> dict:
"""执行工具调用"""
results = []
for call in state.get('tool_calls', []):
tool_name = call.get('name')
args = call.get('args', {})
if tool_name == 'calculator':
result = calculator(args.get('expression', ''))
elif tool_name == 'get_weather':
result = get_weather(args.get('city', ''))
else:
result = f"未知工具: {tool_name}"
results.append(result)
return {
'tool_results': results,
'tool_calls': [] # 清空工具调用
}
print("Agent 组件已定义: calculator, get_weather, should_continue, execute_tools")🔗 与 Python 基础的联系:工具就是普通的 Python 函数!Agent 的强大之处在于可以智能地决定何时调用哪个工具。
61. 图可视化 - 理解工作流结构
LangGraph 支持将图导出为 Mermaid 格式进行可视化。
# 获取图的可视化表示
try:
mermaid_graph = simple_graph.get_graph().draw_mermaid()
print("简单图的 Mermaid 表示:")
print(mermaid_graph)
except Exception as e:
print(f"可视化需要额外依赖: {e}")
print("\n图结构描述:")
print("START --> double --> add_ten --> END")输出示例:
graph TD;
__start__ --> double;
double --> add_ten;
add_ten --> __end__;💡 小贴士:可以把 Mermaid 代码粘贴到支持 Mermaid 的工具中(如 GitHub、Notion)来查看图形化的流程图。
62. 循环图 - 迭代处理
LangGraph 支持创建循环图,这对于需要多次迭代的任务非常有用。回顾前面的 while 循环,这里用图结构实现类似功能。
# 循环图示例: 持续处理直到满足条件
class LoopState(TypedDict):
counter: int
max_count: int
log: Annotated[list[str], add]
def increment(state: LoopState) -> dict:
"""增加计数器"""
new_count = state['counter'] + 1
return {
'counter': new_count,
'log': [f'计数: {new_count}']
}
def should_continue_loop(state: LoopState) -> Literal["increment", "end"]:
"""检查是否继续循环"""
if state['counter'] < state['max_count']:
return "increment"
return "end"
# 创建循环图
loop_graph = StateGraph(LoopState)
loop_graph.add_node("increment", increment)
# START -> increment
loop_graph.add_edge(START, "increment")
# increment -> (条件) -> increment 或 end
loop_graph.add_conditional_edges(
"increment",
should_continue_loop,
{
"increment": "increment", # 循环回去
"end": END # 结束
}
)
loop_app = loop_graph.compile()
# 测试循环
result = loop_app.invoke({
'counter': 0,
'max_count': 5,
'log': ['开始']
})
print(f"最终计数: {result['counter']}")
print(f"执行日志: {result['log']}")输出:
最终计数: 5
执行日志: ['开始', '计数: 1', '计数: 2', '计数: 3', '计数: 4', '计数: 5']🎯 小白理解:这就是用图结构实现的 while 循环!条件边的返回值决定是继续循环还是退出。
63. Streaming 流式输出 - 结合生成器
LangGraph 支持流式输出,可以实时获取每个节点的执行结果。回顾前面的 生成器(Generators),stream() 方法返回一个生成器。
# 使用 stream() 获取流式输出
print("流式执行过程:")
print("-" * 40)
for step in simple_graph.stream({'value': 3, 'history': ['初始值: 3']}):
# 每次迭代返回一个节点的输出
for node_name, node_output in step.items():
print(f"节点 '{node_name}' 输出: {node_output}")
print("-" * 40)输出:
流式执行过程:
----------------------------------------
节点 'double' 输出: {'value': 6, 'history': ['doubled to 6']}
----------------------------------------
节点 'add_ten' 输出: {'value': 16, 'history': ['added 10, now 16']}
----------------------------------------🔗 与 Python 基础的联系:
stream()返回一个生成器,使用for循环遍历。每次迭代获取一个节点的输出,非常适合实时显示进度!
64. Checkpointer 检查点 - 状态持久化
LangGraph 提供 Checkpointer 来保存和恢复状态,实现:
- 对话记忆
- 故障恢复
- 时间旅行调试
from langgraph.checkpoint.memory import MemorySaver
# 创建内存检查点保存器
memory = MemorySaver()
# 使用检查点编译图
stateful_graph = StateGraph(MessagesState)
stateful_graph.add_node("echo", echo_bot)
stateful_graph.add_edge(START, "echo")
stateful_graph.add_edge("echo", END)
# 编译时传入 checkpointer
stateful_app = stateful_graph.compile(checkpointer=memory)
# 使用 thread_id 来区分不同的对话会话
config = {"configurable": {"thread_id": "user-123"}}
# 第一轮对话
result1 = stateful_app.invoke(
{'messages': [{'role': 'user', 'content': '你好!'}]},
config=config
)
print(f"第一轮回复: {result1['messages'][-1].content}")
# 第二轮对话 - 会记住之前的消息
result2 = stateful_app.invoke(
{'messages': [{'role': 'user', 'content': '记得我说的吗?'}]},
config=config
)
print(f"第二轮回复: {result2['messages'][-1].content}")
print(f"\n对话历史长度: {len(result2['messages'])} 条消息")输出:
第一轮回复: 你说的是: 你好!
第二轮回复: 你说的是: 记得我说的吗?
对话历史长度: 4 条消息💡 Checkpointer 的作用:
- 对话记忆:Agent 可以记住之前的对话
- 多会话管理:通过
thread_id区分不同用户/会话- 状态恢复:程序重启后可以恢复之前的状态
65. 知识点映射总结
下表展示了 Python 基础知识与 LangGraph 概念的对应关系:
| Python 基础概念 | LangGraph 对应概念 | 说明 |
|---|---|---|
| 字典 (Dict) | State | 状态使用 TypedDict 定义,本质是带类型的字典 |
| 类 (Class) | StateGraph | 图结构是一个类,管理节点和边 |
| 函数 (Function) | Node | 节点就是处理状态的函数 |
| 条件语句 (if/elif/else) | Conditional Edge | 条件边根据状态决定下一步 |
| 循环 (while/for) | Cyclic Graph | 循环图实现迭代处理 |
| 生成器 (Generator) | stream() | 流式输出返回生成器 |
| reduce 函数 | Reducer (Annotated) | 定义状态如何合并更新 |
| 列表 (List) | Messages | 消息列表是 Agent 的核心数据结构 |
🎯 核心理解:LangGraph 不是什么神秘的新技术,它只是用图结构来组织我们已经熟悉的 Python 代码!
66. 练习: 创建一个简单的数学 Agent
尝试创建一个能够执行基本数学运算的 Agent:
- 定义加、减、乘、除四个工具函数
- 创建一个路由函数,根据用户输入选择正确的运算
- 使用条件边连接各个节点
# 练习: 数学 Agent
# 请完成以下代码
class MathState(TypedDict):
num1: float
num2: float
operation: str # 'add', 'subtract', 'multiply', 'divide'
result: float
# TODO: 定义四个运算节点
def add_node(state: MathState) -> dict:
return {'result': state['num1'] + state['num2']}
def subtract_node(state: MathState) -> dict:
# 你的代码
pass
def multiply_node(state: MathState) -> dict:
# 你的代码
pass
def divide_node(state: MathState) -> dict:
# 你的代码 (注意处理除零情况)
pass
# TODO: 定义路由函数
def route_operation(state: MathState) -> str:
op = state['operation']
if op == 'add':
return 'add_node'
# 你的代码: 处理其他运算
pass
# TODO: 创建图并添加节点和边
# math_graph = StateGraph(MathState)
# ...
print("完成代码后,测试你的数学 Agent!")67. 进一步学习资源
官方文档:
核心概念回顾:
- StateGraph: 管理工作流的核心类
- Nodes: 执行具体任务的函数
- Edges: 定义节点间的连接
- Conditional Edges: 根据状态动态路由
- Checkpointer: 状态持久化和记忆
- Streaming: 流式输出支持
下一步学习建议:
- 结合 LangChain 的 LLM 集成
- 学习 Human-in-the-Loop 人机交互
- 探索多 Agent 系统架构
全文总结
本章内容分为两部分:
Part 1: Python 基础 50 个知识点
涵盖了从 print() 到正则表达式的核心语法,为 AI 开发打下坚实基础。
Part 2: LangGraph 扩展 (51-67)
展示了如何将 Python 基础知识应用到 AI Agent 开发中:
- TypedDict 用于定义状态结构
- 函数作为节点执行任务
- 条件边实现智能路由
- 流式输出提供实时反馈
- Checkpointer 实现状态持久化
核心启示:掌握了 Python 基础,学习 LangGraph 就是自然而然的延伸。LangGraph 只是用图结构组织我们已经熟悉的代码!