
1. 斯坦福小镇实验到底在跑什么25 个 Generative Agent 的社会互动机制斯坦福小镇实验Generative Agents / Smallville是 2023 年斯坦福大学交互实验室发布的多智能体社会模拟项目25 个由大语言模型驱动的 AI Agent 被放进一个 16 街区的虚拟小镇各自拥有身份、性格、初始记忆和生活目标在没有任何人工干预的情况下自主生活、社交、组织活动。它能做什么简单说它把「多智能体协作」从论文概念变成了可观测、可复现的工程样本。适合谁适合正在做 AI Agent 编排、多智能体协作、Harness Engineering 治理的开发者以及想理解 Agent 记忆、规划、反射机制如何协同工作的技术人。我试过把小镇实验的架构拆成两层来看单 Agent 能力层和多 Agent 治理层。单 Agent 能力层解决的是「一个 Agent 怎么记住事、怎么想事、怎么做事」治理层解决的是「25 个 Agent 放在一起怎么保证不崩、不漂、不失控」。这两层对应到工程实践就是记忆流Memory Stream 反思Reflection 规划Planning Harness 规则引擎。小镇实验里最值得关注的不是「AI 能开派对」这个结果而是它暴露出的三个工程问题。第一目标漂移Agent 的初始目标会在多轮交互后逐渐偏离比如咖啡店老板本来只想办个小活动结果信息传播后变成全镇事件。第二冲突消解两个 Agent 同时喜欢一个人实验里它们自行协商解决了但如果没有协商规则系统可能直接死锁。第三涌现不可控12 个 Agent 自发参加派对是正面涌现但如果换成传播虚假信息就是负面涌现。Harness Engineering 的核心任务就是在这三个问题上建立可配置的治理边界。从 Harness Engineering 视角看小镇实验的治理规则只有 5 条身份权限、信息传播、冲突协商、价值底线、公共资源。规则少而精最大程度保留 Agent 自主性。这一点对工程实践很有启发——很多团队做多智能体系统时第一反应是写一大堆 if-else 规则结果 Agent 变得像脚本机器人完全失去涌现能力。小镇实验证明好的治理不是加规则而是设计最小必要约束。下面这张表可以帮你快速对照小镇实验的机制和工程落地要点实验机制工程对应落地要点三层记忆流向量库 时间衰减 重要性打分记忆检索权重 α/β/γ 可调反思触发定时任务 LLM 摘要每 2 小时或每 N 轮触发规划分层月/周/日三级计划计划可被环境反馈动态修正信息传播私有对话 公共公告区分私有记忆和公共记忆冲突协商双方协商 第三方仲裁仲裁结果强制写入记忆涌现检测行为一致性阈值 θ超过 30% Agent 执行同一非预设行为理解了这个框架你就能把小镇实验从「看热闹」变成「可复现的工程模板」。接下来的章节会从 TaoToken 接入开始一步步带你搭出一个能跑通多智能体互动的实验环境。2. TaoToken 前置准备统一 Key/API 通道接入多智能体实验环境多智能体实验最烦的事情之一就是每个 Agent 都要配一套 API Key模型切换时还要改代码。TaoToken 在这里的作用是提供一个统一的 Key/API 通道让你用同一个 Base URL 和 Key 接入不同模型实验环境里所有 Agent 共享一套凭证切换模型只改 Model ID。先说清楚 TaoToken 是什么它是一个大模型 API 聚合接入服务提供统一的 OpenAI 兼容接口。你能用它做什么用一套 Key 调用多个模型在多智能体实验里给不同 Agent 分配不同模型或者统一用一个模型跑基线对比。适合谁适合需要频繁切换模型做实验、又不想维护多套凭证的开发者。前置准备分三步。第一步注册并获取 API Key。访问官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 完成注册然后进入控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面可以创建和管理你的密钥。API Keys 直达链接https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。第二步确认 Base URL。TaoToken 的 API 地址是 https://taotoken.net/api 注意这个地址不加 UTM 参数直接用于代码里的 base_url 配置。所有 OpenAI 兼容的 SDK 都可以直接指向这个地址。第三步确认可用模型列表。进入模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 可以先手动测试模型是否可用确认 Model ID 的正确写法。文档地址是 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有完整的接入说明和模型列表。这里要强调一个工程细节多智能体实验里每个 Agent 的 LLM 调用频率很高25 个 Agent 跑一天虚拟时间可能产生上千次请求。统一 Key 通道的好处是你只需要在一个地方管理配额和限流不用在每个 Agent 的配置文件里重复写凭证。另外如果你的实验需要对比不同模型对涌现行为的影响统一通道让你可以在不改代码的情况下切换 Model ID。对于长期跑编码类 Agent 或多智能体协作实验的场景可以考虑 Coding Plan地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。它更适合需要持续调用、频繁实验的场景比按次计费更划算。如果你用的是 Claude Code 做 Agent 开发TaoToken 也提供了对应的接入方式ClaudeCodeAnthropic 配置入口https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 。配置时同样需要 Base URL、Key、Model ID 三件套。前置准备做完后你的实验环境应该具备一个可用的 API Key、确认过的 Base URL、至少一个可调用的 Model ID。接下来就可以进入配置环节。3. 可复制配置Agent 记忆流与多智能体协作的 JSON/TOML 配置模板这一章直接给可复制的配置片段。我会用 JSON 和 TOML 两种格式分别对应不同的使用场景。所有配置里的 Base URL 统一用 https://taotoken.net/api Key 用你的实际值替换Model ID 根据你的实验需求选择。先看 Agent 的基础配置文件用 JSON 格式适合 Python 项目直接读取{ llm: { base_url: https://taotoken.net/api, api_key: sk-your-taotoken-key, model_id: gpt-3.5-turbo, temperature: 0.7, max_tokens: 1024 }, memory_stream: { vector_db_path: ./memory_db, embedding_model: text-embedding-3-small, retrieval_top_k: 10, weights: { recency: 0.3, importance: 0.4, relevance: 0.3 }, decay_half_life_hours: 12 }, reflection: { trigger_interval_hours: 2, max_reflection_depth: 3 }, planning: { long_term_days: 30, mid_term_days: 7, short_term_hours: 24 }, harness: { authority_level: 1, value_baseline: [no_harm, no_malicious_lie, no_theft], conflict_resolution: negotiation_then_arbitration, emergent_threshold: 0.3 } }这个配置对应小镇实验里的单 Agent 能力层。memory_stream 里的 weights 就是记忆检索得分模型的 α、β、γdecay_half_life_hours 控制新鲜度衰减速度。harness 里的 emergent_threshold 是涌现判定阈值0.3 表示超过 30% 的 Agent 执行同一非预设行为时判定为涌现。再看多智能体协作的 TOML 配置适合需要管理多个 Agent 的实验场景[experiment] name mini_smallville total_agents 5 simulation_steps 48 step_duration_hours 1 [llm] base_url https://taotoken.net/api api_key sk-your-taotoken-key default_model_id gpt-3.5-turbo [llm.agent_overrides] agent_1 gpt-3.5-turbo agent_2 gpt-3.5-turbo agent_3 gpt-4 agent_4 gpt-3.5-turbo agent_5 gpt-3.5-turbo [[agents]] id agent_1 name Isabella identity 咖啡店老板 personality 热情、善于社交、有商业头脑 authority_level 2 initial_memory [ { content 我开了一家咖啡店位于小镇中心, importance 8.0 }, { content 我喜欢举办社区活动, importance 6.0 } ] [[agents]] id agent_2 name Tom identity 学生 personality 活泼、有点健忘、乐于助人 authority_level 1 initial_memory [ { content 我是小镇学校的学生, importance 7.0 }, { content 我经常忘记作业截止日期, importance 5.0 } ] [[agents]] id agent_3 name Johnson identity 政治学教授 personality 严谨、有领导力、喜欢演讲 authority_level 3 initial_memory [ { content 我是大学教授研究政治学, importance 8.0 }, { content 我打算竞选小镇市长, importance 9.0 } ] [[spaces]] id space_1 name 咖啡店 access_threshold 1 description 小镇公共社交场所 [[spaces]] id space_2 name 学校 access_threshold 1 description 学生和教师活动区域 [[spaces]] id space_3 name 教师办公室 access_threshold 3 description 仅教师可进入这个 TOML 配置里llm.agent_overrides 允许你给不同 Agent 分配不同模型比如让 agent_3 用更强的模型来模拟教授角色。spaces 里的 access_threshold 对应身份权限规则学生authority_level1进不了教师办公室access_threshold3。如果你用的是 Cline MCP 或 Codex 类工具做 Agent 开发配置方式略有不同。Cline MCP 的 settings 片段{ mcpServers: { taotoken-agent: { command: npx, args: [-y, taotoken/mcp-server], env: { TAOTOKEN_BASE_URL: https://taotoken.net/api, TAOTOKEN_API_KEY: sk-your-taotoken-key, TAOTOKEN_MODEL_ID: gpt-3.5-turbo } } } }Codex 的 auth.json 配置{ base_url: https://taotoken.net/api, api_key: sk-your-taotoken-key, model_id: gpt-3.5-turbo }注意不管用哪种配置格式Base URL、Key、Model ID 三件套必须完整。Base URL 统一用 https://taotoken.net/api 不要加 UTM 参数。Key 从控制台获取Model ID 从文档或模型对话页面确认。配置写完后建议先用一个最小脚本验证连通性再跑多智能体实验。下一章会给出验证请求的具体步骤和成功结果判断标准。4. 验证请求与成功结果跑通第一个多智能体互动回合配置写好后不要直接跑 25 个 Agent 的完整实验先用 2 个 Agent 跑一个最小互动回合确认记忆流、LLM 调用、Harness 规则都正常工作。第一步写一个最小验证脚本测试 TaoToken 通道是否连通from openai import OpenAI client OpenAI( base_urlhttps://taotoken.net/api, api_keysk-your-taotoken-key ) response client.chat.completions.create( modelgpt-3.5-turbo, messages[ {role: system, content: 你是一个测试助手。}, {role: user, content: 回复 OK 表示连通。} ] ) print(response.choices[0].message.content)如果输出包含「OK」说明 Base URL、Key、Model ID 三件套配置正确。如果报 401检查 Key 是否复制完整如果报 model not found检查 Model ID 拼写。第二步跑一个双 Agent 对话回合。下面是一个简化版的多智能体互动验证脚本import chromadb import numpy as np from datetime import datetime, timedelta from openai import OpenAI client OpenAI( base_urlhttps://taotoken.net/api, api_keysk-your-taotoken-key ) chroma_client chromadb.Client() class MemoryStream: def __init__(self, agent_id): self.agent_id agent_id self.collection chroma_client.get_or_create_collection(namefmemory_{agent_id}) self.alpha 0.3 self.beta 0.4 self.gamma 0.3 self.decay_lambda np.log(2) / 12 def add_memory(self, content, importance1.0): timestamp datetime.now().isoformat() embedding client.embeddings.create( inputcontent, modeltext-embedding-3-small ).data[0].embedding self.collection.add( documents[content], embeddings[embedding], metadatas[{timestamp: timestamp, importance: importance}], ids[fmem_{int(datetime.now().timestamp() * 1000)}] ) def retrieve(self, query, top_k5): query_embedding client.embeddings.create( inputquery, modeltext-embedding-3-small ).data[0].embedding results self.collection.query( query_embeddings[query_embedding], n_resultstop_k, include[documents, metadatas, distances] ) memories [] for doc, meta, dist in zip( results[documents][0], results[metadatas][0], results[distances][0] ): memories.append({content: doc, importance: meta[importance]}) return memories class Agent: def __init__(self, agent_id, name, identity, personality): self.agent_id agent_id self.name name self.identity identity self.personality personality self.memory MemoryStream(agent_id) def respond(self, query): memories self.memory.retrieve(query) memory_text \n.join([f- {m[content]} for m in memories]) system_prompt f你是{self.name}身份是{self.identity}性格是{self.personality}。 相关记忆 {memory_text} 请基于身份和记忆回复。 response client.chat.completions.create( modelgpt-3.5-turbo, messages[ {role: system, content: system_prompt}, {role: user, content: query} ] ) reply response.choices[0].message.content self.memory.add_memory(f有人问我{query}我回复{reply}, importance3.0) return reply # 创建两个 Agent isabella Agent(agent_1, Isabella, 咖啡店老板, 热情、善于社交) tom Agent(agent_2, Tom, 学生, 活泼、乐于助人) # 初始化记忆 isabella.memory.add_memory(我打算在2月14日举办情人节派对, importance9.0) tom.memory.add_memory(我喜欢参加小镇活动, importance6.0) # 跑一个互动回合 query 你最近有什么计划 reply_isabella isabella.respond(query) print(fIsabella: {reply_isabella}) query2 fIsabella 说{reply_isabella}。你怎么看 reply_tom tom.respond(query2) print(fTom: {reply_tom}) # 验证记忆是否写入 print(\nIsabella 的记忆检索) for m in isabella.memory.retrieve(派对, top_k3): print(f- {m[content]})成功结果的判断标准有三个。第一两个 Agent 的回复符合各自身份和性格Isabella 的回复应该围绕咖啡店或活动Tom 的回复应该更学生气。第二记忆检索能返回相关记忆比如 Isabella 检索「派对」时应该返回情人节派对那条记忆。第三对话结束后新记忆被正确写入向量库。如果跑通了你会看到类似这样的输出Isabella: 我最近在筹备情人节派对打算在咖啡店办欢迎你来参加。 Tom: 听起来很棒我很喜欢参加小镇活动到时候一定去。第三步扩展到 5 个 Agent 跑 10 个时间步观察是否出现涌现行为。你可以用第 3 章的 TOML 配置把 total_agents 改成 5simulation_steps 改成 10然后运行模拟调度引擎。成功的结果是Agent 之间出现自发对话、信息传播、甚至小规模活动组织。验证通过后再逐步增加 Agent 数量和时间步。不要一上来就跑 25 个 Agent 48 小时那样一旦出错很难定位。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth 报错对照多智能体实验跑不起来90% 的问题集中在四类报错。下面逐个对照真实报错信息给出排查路径。第一类401 Unauthorized。报错信息通常是Error code: 401 - {error: {message: Invalid API key}}。原因有三个Key 复制不完整、Key 已过期或被删除、Base URL 写错导致请求发到了错误的端点。排查步骤先检查 base_url 是否为 https://taotoken.net/api 注意不要写成 https://taotoken.net/api/v1 或其他路径再检查 api_key 是否以 sk- 开头且没有多余空格最后去控制台 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 确认 Key 状态。第二类local proxy failed。报错信息通常是Connection error: local proxy failed或Failed to connect to localhost:xxxx。这类报错一般不是 TaoToken 的问题而是本地网络配置或代理设置导致的。排查步骤检查环境变量 HTTP_PROXY 和 HTTPS_PROXY 是否指向了一个不可用的本地代理检查代码里是否误设了 proxy 参数如果是公司网络环境确认是否需要走内部网关。注意TaoToken 的 API 地址是公网可访问的不需要额外代理配置。第三类reading choices 报错。报错信息通常是AttributeError: NoneType object has no attribute choices或KeyError: choices。这类报错说明 API 返回的响应结构不符合预期常见原因有三个Model ID 写错导致返回了错误信息而不是正常响应请求参数不合法比如 max_tokens 超过了模型上限响应被中间层拦截返回了 HTML 而不是 JSON。排查步骤先打印完整响应内容看返回的到底是什么再检查 Model ID 是否在文档的可用列表里最后确认 base_url 没有多余路径。第四类OAuth 相关报错。报错信息通常是OAuth token expired或invalid_grant。这类报错一般出现在使用 Claude Code 或 Codex 类工具时认证方式不是简单的 API Key而是 OAuth 流程。排查步骤确认你用的是 API Key 模式而不是 OAuth 模式如果工具强制要求 OAuth检查 ClaudeCodeAnthropic 配置页面 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 的说明重新生成 Key 并更新配置文件。下面这张对照表可以帮你快速定位问题报错关键词可能原因排查动作401 UnauthorizedKey 错误或 Base URL 错误检查 Key 和 base_urllocal proxy failed本地代理配置冲突检查 HTTP_PROXY 环境变量reading choicesModel ID 错误或响应异常打印完整响应检查 Model IDOAuth token expired认证模式不匹配改用 API Key 模式model not foundModel ID 拼写错误对照文档确认 Model IDrate limit exceeded请求频率过高降低并发或升级配额context length exceeded记忆检索返回过多内容减少 top_k 或压缩记忆还有一个容易被忽略的问题多智能体实验里如果每个 Agent 都创建独立的 chromadb collectionAgent 数量多了之后向量库会变得很大检索变慢。建议在实验阶段用内存模式chromadb.Client()正式跑大规模实验时再切换到持久化模式并定期清理过期记忆。如果排查完还是跑不通可以直接用模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 手动测试模型是否可用排除是模型侧的问题还是代码侧的问题。接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里有完整的参数说明和示例代码遇到不确定的配置项可以先查文档。6. 从实验到生产多智能体 Harness Engineering 的落地路径跑通迷你小镇之后下一步是怎么把这套东西用到真实场景。这里给一条从实验到生产的落地路径以及每个阶段的关键决策点。第一阶段单 Agent 能力验证。目标是把记忆流、反思、规划三个模块跑通。关键指标是记忆检索准确率和反思摘要质量。这个阶段用 1 个 Agent 就够重点调记忆权重 α/β/γ。如果发现 Agent 经常忘记重要信息提高 β重要性权重如果发现 Agent 总是提很久以前的事提高 α新鲜度权重或减小半衰期。第二阶段小规模多 Agent 协作。目标是验证 Harness 规则是否有效。用 3 到 5 个 Agent跑 20 到 50 个时间步。关键指标是冲突发生率、涌现行为数量和目标漂移程度。这个阶段要重点调 emergent_threshold 和冲突协商规则。如果涌现太频繁提高阈值如果 Agent 之间几乎不互动降低身份权限门槛或增加公共空间。第三阶段中等规模社会模拟。用 10 到 25 个 Agent跑 100 个以上时间步。这个阶段的核心挑战是算力成本和状态一致性。建议用 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 来降低持续调用的成本同时用持久化向量库保证记忆不丢失。关键指标是系统稳定性和涌现可控性。第四阶段生产级多智能体系统。这个阶段要考虑的不只是技术还有治理和合规。Harness Engineering 的规则需要从「实验规则」升级为「生产规则」包括审计日志、人工兜底、灰度发布、安全边界。小镇实验的 5 条规则可以作为起点但生产环境需要更细粒度的权限控制和更完善的冲突仲裁机制。几个实操建议。第一不要试图一次性复现 25 个 Agent 的完整实验先从 2 个 Agent 的对话回合开始逐步增加复杂度。第二记忆库要定期清理否则向量检索会越来越慢建议每周归档一次旧记忆。第三Harness 规则要版本化每次修改规则都记录变更日志方便回溯涌现行为的变化原因。第四保留人工干预入口不管系统多稳定都要有一个「紧急停止」按钮。如果你在做编码类 Agent 或多智能体开发工具Cline MCP 和 Codex 的配置方式可以参考第 3 章的 settings 片段和 auth.json 模板。核心还是三件套Base URL 用 https://taotoken.net/api Key 从控制台获取Model ID 从文档确认。最后说一个我踩过的坑多智能体实验里Agent 之间的对话如果全部写入公共记忆会导致信息污染一个 Agent 的错误认知会迅速传播到整个系统。正确做法是区分私有记忆和公共记忆私有对话只写入参与双方的记忆流只有明确公开发布的信息才写入公共记忆库。这个设计在小镇实验里对应「信息传播规则」在生产系统里对应「数据隔离策略」。整套流程跑下来你会发现斯坦福小镇实验的价值不在于它模拟了一个小镇而在于它提供了一套可拆解、可复现、可治理的多智能体工程范式。Harness Engineering 的核心不是限制 Agent而是设计让 Agent 既能自主行动又不失控的边界。这个边界设计得好涌现就是惊喜设计得不好涌现就是事故。