摘要:智能体(agent)是能自主感知环境、做出决策并付诸行动的计算实体;多智能体系统(MAS)是一群这样的实体加上它们共同栖居的环境与交互关系。本节给出权威定义、拆解智能体的四大特性、给环境做形式化画像,并搭出"感知—决策—行动"的最小代码骨架。
「Agent」这个词在计算机科学里流浪了很久,直到分布式人工智能的研究者把它领回家,它才有了稳定的户口。本节是全册的地基:导读里那张小镇地图上的每一栋建筑,都建立在"镇民到底是谁"这个问题的答案之上。读完这一节,你才能进入第 2 章去解剖镇民的内部结构。
多智能体系统的身世要追溯到人工智能研究的一次分家。早期的研究者幻想造出一个无所不能的中央大脑,把推理、知识、感知全部塞进同一个系统;结果发现路越走越窄——真实世界是分布式的:数据长在不同的机器上,传感器长在不同的机器人上,决策权分散在不同的利益方手里。于是有人掉头:与其造一个神,不如造一个社会。让每个计算单元只管自己看得见的局部,通过交互把整体智能"涌现"出来。这个转向催生了分布式人工智能,后来软化成我们今天说的多智能体系统——一群相对简单、自主、会打交道的计算个体。
被引用得最多的定义来自 Wooldridge 与 Jennings:智能体是处于环境之中、能感知环境、并通过对环境采取行动以实现自身目标的设计体。这个定义看似平淡,狠话都藏在四个特性里。
自主性(autonomy):镇民自己拿主意,不被人或其他镇民牵着走。对象的方法被人调用,函数被人触发;智能体 Decide 自己的下一步,外界只能影响它的输入,不能替它做决定。这是智能体与普通软件模块的分水岭。
社会性(social ability):镇民之间用某种智能体通信语言打交道,能交换信息、提出请求、做出承诺。孤胆英雄不算镇民,起码要有邻居。
反应性(reactivity):镇民能及时感知环境变化并回应。仓库火警响起,巡逻机器人不该还在慢悠悠规划下季度的巡查路线。
能动性(pro-activeness):镇民不光被动应对,还会主动出击实现目标。电池还够用时主动找充电桩排队,而不是等没电了再哭。
💡 一个常见的误判:把任何并发程序都叫多智能体系统。八线程下载器没有自主性(线程不会拒绝任务),也没有社会性(线程之间不协商)——它是并发软件,不是社会。判断口诀:看它们是"被调度"还是"自己做主"。
谈智能体离不开环境。形式化一点,环境是状态空间加上转移规律,镇民通过感知函数获得观察,通过行动影响状态。教材里常用的几个分类维度值得背下来,因为它们直接决定后面机制选型:
| 维度 | 一端 | 另一端 | 对机制的影响 |
|---|---|---|---|
| 可观察性 | 完全可观察 | 部分可观察 | 后者需要信念维护与通信补盲 |
| 确定性 | 确定转移 | 随机转移 | 随机环境下要引入期望与学习 |
| 动态性 | 静态 | 动态 | 动态环境逼迫反应式成分登场 |
| 离散性 | 离散状态 | 连续状态 | 连续世界需要抽象或函数逼近 |
| 镇民密度 | 单智能体 | 多智能体 | 多智能体环境天生非平稳 |
最后那行是全册的伏笔:只要环境里还有别的会学习的镇民,你面对的就不是固定的转移规律,而是"我变你也变"的追逐——这是第 7 章学堂要直面的大麻烦。
定义念完,动手最实在。下面这段代码用纯 Python 标准库搭出智能体的最小骨架:网格小镇里散落垃圾,扫地镇民按简单规则游走捡拾。注意三个函数的分工——perceive 决定它能看见什么,decide 装着它的"性格",act 把决策交给环境执行。
import random class SweeperAgent: """扫地镇民:感知相邻格位,决定移动方向,行动交由环境裁决。""" def __init__(self, name, pos): self.name = name # 镇民名册 self.pos = pos # 在网格里的坐标 self.bag = 0 # 已捡垃圾数 def perceive(self, env): # 感知函数:只暴露当前位置与四邻,镇民看不见全镇 return { "here_dirty": env.is_dirty(self.pos), "neighbors": env.free_neighbors(self.pos), } def decide(self, obs): # 决策函数:有垃圾就捡;否则在可行邻格中随机游走 if obs["here_dirty"]: return ("pick", None) return ("move", random.choice(obs["neighbors"])) class GridTown: """网格小镇:垃圾随时间新增,负责裁决所有镇民的行动。""" def __init__(self, size, agent_count, seed=7): random.seed(seed) self.size = size self.dirty = {(random.randrange(size), random.randrange(size)) for _ in range(size * size // 3)} self.agents = [SweeperAgent(f"sweeper-{i}", (random.randrange(size), random.randrange(size))) for i in range(agent_count)] def is_dirty(self, pos): return pos in self.dirty def free_neighbors(self, pos): x, y = pos cand = [(x+dx, y+dy) for dx, dy in ((0,1),(0,-1),(1,0),(-1,0))] return [(nx, ny) for nx, ny in cand if 0 <= nx < self.size and 0 <= ny < self.size] def step(self): for a in self.agents: # 环境轮询每个镇民 act = a.decide(a.perceive(self)) if act[0] == "pick": self.dirty.discard(a.pos); a.bag += 1 else: a.pos = act[1] town = GridTown(size=8, agent_count=3) for _ in range(40): town.step() print("剩余垃圾:", len(town.dirty)) print("战果:", [(a.name, a.bag) for a in town.agents])
运行它,你会看到三个互不通信的镇民纯粹靠局部规则就把垃圾清掉了大半。把 agent_count 调大,清扫变快但镇民会互相"踩"同一片区域——这就是缺乏协调的浪费,第 4 章市政分工要解决的头号矛盾。

有了镇民与环境,多智能体系统的定义水到渠成:由多个自主智能体组成的系统,智能体之间以及智能体与环境之间存在交互,系统整体要解决单个智能体无力解决或解决不好的问题。注意三个关键词——自主(没有总指挥)、交互(不是各干各的)、整体目标(不是乌合之众)。
判定一个系统是不是 MAS,可以依次问三个问题:计算单元能不能自己做决定(自主性)?单元之间有没有有语义的交互(社会性)?整体是否呈现出单个单元没有的能力(涌现)?三个都答"是",才发镇民证。
问:智能体和微服务有什么区别? 微服务是工程分工,服务之间是调用与被调用;智能体之间是对等协商。把微服务加上自主决策与协议化交互,它就开始像多智能体系统了。
问:机器人才能算智能体吗? 不。软件镇民(交易智能体、调度智能体、爬虫协商体)占文献的半壁江山;机器人只是长了身体的镇民。
问:多智能体系统和"群体智能"是一回事吗? 群体智能(蚁群、鸟群)通常指简单个体无规划的涌现,偏反应式、无显式通信;MAS 更宽,允许聪明的镇民、显式协议与博弈。前者可以看作本册镇民光谱上"本能端"的近亲。
下一节给镇民分门别类——你会发现"智能体"这个词底下住着习性迥异的一大家子。