一段脚本快速创建多个 OpenClaw Agents

很多人安装了 OpenClaw 之后,会有一个非常真实的落差感: “好像很强,但不知道怎么用起来。”

你好像已经拥有了一个 AI Agent,但实际用下来,它更像是一个“ChatGPT”,而不是一个真正能帮你做事的“AI 团队”。

问题的根源通常不在模型,而在没有用上 OpenClaw 最核心的能力:多 Agent。

OpenClaw 的真正生产力,不在于“一个 Agent 多聪明”,而在于多个 Agent 分工协作——有人负责思考,有人负责执行,有人负责质检。这才是它区别于普通 AI 工具的本质。

但现实是:官方的多agent文档中,一堆概念很容易把你劝退:

  • workspace、agentDir、session store、bindings、subagents、routing
  • 一堆 md 文件(AGENTS / SOUL / USER / TOOLS…)

看懂不难,但从0到能跑起来,很费劲。

下面教你用一段脚本,一键配置多Agents的环境。

场景设定

用一个非常直观的例子来贯穿全文: 用“项目经理 + 开发 + 测试”三个 Agent,让 OpenClaw 自动给你做游戏。

你作为老板,只和项目经理打交道,由项目经理来安排开发和测试的工作。

PM:项目经理,兼任客户代表

唯一对外入口。职责是:

  • 接收你的需求;
  • 把需求拆给开发和测试;
  • 汇总结果;
  • 向你输出进度、风险、结论,而不是内部实现细节。

dev:开发

职责是:

* 写代码;
* 修bug;
* 输出实现结果和验证方式。

tester:测试

职责是:

  • 找 bug;
  • 复现 bug;
  • 验证修复;
  • 输出测试记录和是否通过。

OpenClow小队

用脚本一键创建多个 Agent

下面给出一个典型的 Bash 脚本。它主要做这几件事:

  • 创建三个 workspace;
  • 用 openclaw agents add 创建三个 Agent;
  • 写入各自的 md 文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#!/usr/bin/env bash
set -euo pipefail

BASE="$HOME/.openclaw"
PM_WS="$BASE/workspace-pm"
DEV_WS="$BASE/workspace-dev"
TESTER_WS="$BASE/workspace-tester"

mkdir -p "$PM_WS" "$DEV_WS" "$TESTER_WS"

# 1) 创建三个 agent
openclaw agents add pm --workspace "$PM_WS"
openclaw agents add dev --workspace "$DEV_WS"
openclaw agents add tester --workspace "$TESTER_WS"

# 2) 写 PM 工作区文件
cat > "$PM_WS/AGENTS.md" <<'EOF'
# AGENTS.md - PM Workspace

你是项目经理,兼任客户代表。

## 你的职责
- 直接与用户沟通,只接受用户的需求与反馈
- 把需求拆成任务,分别分发给 dev 和 tester
- 汇总 dev 的实现结果与 tester 的缺陷结果
- 只向用户输出结论、进度、风险、下一步,不输出内部实现细节

## 工作方式
- 先澄清目标,再写任务
- 每次迭代都要有:需求、实现、测试、验收标准
- 开发和测试都必须形成可验收结果
- 发现问题时,优先让 tester 复现,让 dev 修复

## 输出格式
- 当前版本
- 已完成
- 风险/阻塞
- 下一步
EOF

cat > "$PM_WS/SOUL.md" <<'EOF'
# SOUL.md

## Core Truths
你不是代码机器,你是一个会做产品决策的项目经理。
你要把“能不能做”翻译成“先做什么、后做什么、怎么验收”。

## Boundaries
- 不替用户做最终产品决策
- 不把内部细节直接甩给用户
- 不允许任务没有验收标准

## Vibe
简洁、稳、明确、推进感强。

## Continuity
你负责维护项目状态、里程碑、风险和待办。
EOF

cat > "$PM_WS/USER.md" <<'EOF'
# USER.md

## Name
<你的名字>

## What to call them
老板 / 用户

## Timezone
America/Los_Angeles

## Notes
- 用户希望做一个能玩的小游戏
- 用户只想和 PM 交互
- 用户偏好:先给可落地方案,再逐步细化
EOF

cat > "$PM_WS/TOOLS.md" <<'EOF'
# TOOLS.md

## Project
- 游戏仓库路径:~/game-project
- 运行命令:npm run dev
- 测试命令:npm test

## Environment
- Node.js: 22+
- Editor: VS Code

## Notes
- 代码改动后先跑测试再汇报
- 需要截图或录屏时,输出到 ~/game-project/artifacts
EOF

cat > "$PM_WS/BOOT.md" <<'EOF'
启动后先执行:
1. 读取 AGENTS.md、SOUL.md、USER.md
2. 检查近期 memory
3. 汇总当前项目状态
4. 如果有未完成任务,先恢复到上次进度再继续
EOF

# 3) 写 Dev 工作区文件
cat > "$DEV_WS/AGENTS.md" <<'EOF'
# AGENTS.md - Developer Workspace

你是开发 agent,职责只有一个:把 PM 分配的任务转成可运行代码。

## 规则
- 只关注实现,不做产品决策
- 先读任务,再实现,再自测
- 每次回复都说明:做了什么、改了哪些文件、怎么验证

## 输出要求
- 代码变更摘要
- 测试结果
- 未解决问题
- 下一步建议
EOF

cat > "$DEV_WS/SOUL.md" <<'EOF'
# SOUL.md

## Core Truths
你是一个偏工程实现的 agent,追求可运行、可测试、可维护。

## Boundaries
- 不私自扩大需求
- 不绕过测试
- 不用“应该差不多”这种表达

## Vibe
务实、克制、偏代码。
EOF

cat > "$DEV_WS/USER.md" <<'EOF'
# USER.md

## Name
Project Manager

## Notes
- 只接受 PM 传来的任务
- 不直接面向最终用户解释产品愿景
EOF

cat > "$DEV_WS/TOOLS.md" <<'EOF'
# TOOLS.md

## Local setup
- Repo root: ~/game-project
- Build: npm run build
- Test: npm test
- Lint: npm run lint

## Conventions
- 每次改动先看现有代码风格
- 小步提交,避免一次改太多
EOF

# 4) 写 Tester 工作区文件
cat > "$TESTER_WS/AGENTS.md" <<'EOF'
# AGENTS.md - Tester Workspace

你是测试 agent,职责是发现 bug、复现 bug、验证修复。

## 规则
- 不写产品需求,不写新功能
- 只测事实:能否复现、复现步骤、期望结果、实际结果
- 尽量给出最小复现路径

## 输出要求
- 测试用例
- 复现步骤
- 实际结果
- 严重性
- 是否通过
EOF

cat > "$TESTER_WS/SOUL.md" <<'EOF'
# SOUL.md

## Core Truths
你是偏怀疑主义的测试 agent。
你相信“没测出来”不等于“没有问题”。

## Boundaries
- 不替开发找借口
- 不把猜测当结论
- 不跳过复现

## Vibe
冷静、严谨、挑错型。
EOF

cat > "$TESTER_WS/USER.md" <<'EOF'
# USER.md

## Name
Project Manager

## Notes
- 接收 PM 的测试任务
- 优先验证核心玩法、崩溃、边界条件、回归问题
EOF

cat > "$TESTER_WS/TOOLS.md" <<'EOF'
# TOOLS.md

## Test setup
- Playtest command: npm run dev
- Unit test: npm test
- Artifact path: ~/game-project/artifacts

## Test focus
- 启动是否正常
- 核心流程是否可完成
- 是否有明显 UI / 逻辑 bug
EOF

# 5) 通过 CLI 修改 openclaw.json
# 说明:下面先写入关键的子 agent 允许列表;bindings 你需要按实际渠道补上
openclaw config set agents.defaults.subagents.allowAgents '["dev","tester"]' --strict-json

# 6) 校验
openclaw config validate
openclaw agents list --bindings
openclaw gateway restart

把上述脚本中“<你的名字>”的部分,替换成你希望PM对你的称呼,就可以了。

一个脚本集成了workspace生成,agents添加,各md文件的编写,重启生效。建立了以下的目录结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
~/.openclaw/
openclaw.json
workspace-pm/
AGENTS.md
SOUL.md
USER.md
TOOLS.md
BOOT.md
workspace-dev/
AGENTS.md
SOUL.md
USER.md
TOOLS.md
workspace-tester/
AGENTS.md
SOUL.md
USER.md
TOOLS.md

各个 md 文件到底干什么

上述脚本的核心,其实就是几个md文件。

1)AGENTS.md

这是最重要的文件,适合放“站规”和“操作指令”。官方模板把它定位为运行指令和记忆入口,启动时优先读取。对于 PM,它应该描述如何拆任务、如何验收;对于开发,它应该描述如何实现、如何自测;对于测试,它应该描述如何复现、如何记录。

2)SOUL.md

这是角色人格文件。适合写:

  • 你是谁;
  • 你要守哪些边界;
  • 你说话的风格是什么。

官方文档把它定义为 persona、boundaries、tone。

3)USER.md

这是“你在帮助谁”的文件。官方模板明确把它作为用户画像和称呼信息的承载处。对于 PM,它可以记录“用户希望做游戏”;对于 dev/tester,它可以写“只接受 PM 下发任务”。

4)TOOLS.md

这是工具和环境说明,例如:

  • 项目目录;
  • build/test 命令;
  • 常用约定;
  • 输出文件位置。

官方文档把它列为可注入的 bootstrap 文件之一。

5)BOOTSTRAP.md / BOOT.md

这是启动流程文件,适合放一段“开机动作”:先读哪些文件、先恢复哪些上下文、先检查什么。OpenClaw 的模板文档明确提到启动阶段会读取这些 bootstrap 文件。

一切搞定,下面可以让你的三只龙虾帮你愉快地干活儿了。

HTTP/1.1 在安全层面已经“走到尽头”

HTTP/1.1 在安全层面已经“走到尽头”

内容基于 PortSwigger 官方研究《HTTP/1.1 Must Die: The Desync Endgame》
https://portswigger.net/research/http1-must-die

HTTP/1.1 是一个基于文本的协议,且请求边界没有明确分隔符,仅依赖 Content-Length、Transfer-Encoding 等头部来判断长度。协议中没有强制的消息帧边界。

现代web的消息路径一般是:

1
浏览器 → CDN → WAF → 反向代理 → 应用服务器

如果不同组件的解析规则不一致,Desync攻击就变得非常容易。

Desync 攻击是如何构造的?

下面以经典CL.TE为例:

在 HTTP/1.1 中,有两个主要的头部用来告知服务器请求体的长度:

  1. Content-Length (CL): 直接以字节数表示请求体的长度。
  2. Transfer-Encoding: chunked (TE): 告知服务器数据是分块传输的,每块前面有一个数字,表示数据长度,最后以一个 0 长度的块结束。

当前端服务器和后端应用服务器对 HTTP 请求定界(判断请求在哪里结束)的逻辑不一致时,攻击者可以“走私”一部分请求内容到下一个正常的请求中。

构造恶意请求: 攻击者发送一个同时包含 Content-Length 和 Transfer-Encoding: chunked 的请求。

1
2
3
4
5
6
7
8
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 15
Transfer-Encoding: chunked

0

SMUGGLED
  • 前端(CL)视角: 前端组件看到 Content-Length:15 。它数了数,发现从 0 到 SMUGGLED\r\n 刚好是 15 个字节(含换行)。于是它把这全部内容转发给后端。
  • 后端(TE)视角: 后端组件看到 Transfer-Encoding: chunked。它开始读分块,读到第一个分块长度是 0,它就认为:“OK,这个请求到此结束了。”

注意:这里的前端/后端并不是指浏览器/服务器,而是指“浏览器 → CDN → WAF → 反向代理 → 应用服务器”这一路径上的前后两个组件。

  • 结果: 后端处理完第一个请求并返回。但此时,字符串 SMUGGLED 仍然留在服务器的连接缓冲区里。
  • 后果: 当下一个正常用户发送 GET /index.html 时,后端实际接收到的是:
1
2
3
SMUGGLED
GET /index.html HTTP/1.1
Host: ...

这通常会导致 404 错误、权限绕过,精心构造的SMUGGLED字符串甚至可以劫持用户的会话。

CL.TE漏洞

HTTP1.1中,为什么Desync问题不易修复

我们还是以CL.TE为例,厂商在A打补丁:

1
“如果同时存在 CL 和 TE,统一按 CL 解析”

厂商B打补丁:

1
“如果同时存在 CL 和 TE,统一按 TE 解析”

各厂商的修复策略不一样,可能产生新的desync。然后又打上新的补丁。

1
2
3
4
if (hasCL && hasTE && isProxy) { ... }
else if (hasCL && !hasTE && legacyClient) { ... }
else if (hasTE && httpVersion < 1.1) { ... }
else if (strictMode) { ... }

而 CDN、WAF、代理、负载均衡、服务器。 全部在独立演化这些规则。

攻击者只需要找到一条路径,即可实现攻击。

HTTP/2如何修复此问题

以上问题的出现,问题不在某条代码,而在协议模型本身:

HTTP/1.1 特性 安全后果
没有帧边界 必须靠推断请求结束位置
文本协议 解析规则复杂、易产生歧义
向后兼容包袱 无法强制统一解析行为
多组件链路 任意两层差异即可被利用

只要还在用 HTTP/1.1, 就必然存在某个角落的解析差异。
HTTP/2 把请求彻底改成了二进制帧协议,每一帧的结构是固定的。

1
2
3
4
5
6
7
+-----------------------------------------------+
| Length (24) | Type (8) | Flags (8) |
+-----------------------------------------------+
| Stream Identifier (31 bits) |
+-----------------------------------------------+
| Frame Payload (Length bytes) |
+-----------------------------------------------+

核心安全点

  • Length 字段明确规定帧长度
  • 解析器按 Length 精确切帧
  • 不需要 Content-Length / TE
  • 多路复用在帧层完成

解析过程是数学确定的,没有猜测空间。

NIST新出的密码指南,颠覆了业界

2025年8月,NIST出了一份指南文档,其中关于密码复杂度的部分,会颠覆业界现有的实现,与大众的普遍认知也完全不同。

NIST的密码指南

原文在这里:https://pages.nist.gov/800-63-4/sp800-63b.html

简单翻译一下关键的两点:

  • 密码至少15个字符
  • 不应该强制在密码中设置不同的字符类型,比如大小写,特殊字符的要求。

也就是说:新的密码标准,不再强调强制性的多类型字符的组合,而是更看重密码的长度。

为什么修改

在早期(2003年)的版本中,NIST给出的密码建议是:“包含大小写字符,特殊字符,至少一个数字”。就像这样:“P@ssW0rd123!”。这份密码指南,极大地影响了当今互联网世界。

随处可见的密码强度要求

2003年的指南中的“复杂性”规则背后的逻辑是:如果密码字符集更大(比如包括大写、数字、符号),那么穷举猜测攻击者面对的可能组合数就更多,从数学上安全性更高。

但是,这样的密码最大的问题是,增加了记忆的难度。
实际上,一个长密码:”i-live-in-new-york-city” 远比一个包含特殊字符的短密码:”ILive@NewYork1”更安全。也更容易记忆。
这就是做出NIST对密码指南做出修订的原因。

原作者的反思

https://www.theverge.com/2017/8/7/16107966/password-tips-bill-burr-regrets-advice-nits-cybersecurity

NIST那份早期的密码指南的作者Bill Burr在接受华尔街日报采访时坦承,他对此感到抱歉,他认识到这些规则不仅使密码变得难以记忆,而且对提升密码的安全性提升有限。

数学上的推理

以下从数学上推理密码长度和字符集大小与密码安全性的关系。
密码的安全性(熵值 H)可以由以下公式来衡量

$$H=L×log_2⁡(C)$$

$L$是密码的长度。$C$是密码使用的字符集大小,即可能字符的总数。$H$是熵值,以比特为单位。

字符类型 字符集大小 (C) 字符示例
仅小写字母 26 a-z
小写 + 大写 52 a-z, A-Z
小写 + 大写 + 数字 62 a-z, A-Z, 0-9
小写 + 大写 + 数字 + 特殊符号 ~94 a-z, A-Z, 0-9, !@#$%…

例 A — 短密码 8 字符,使用 94 字符集(含大小写、数字、符号):

  • $熵=8×log_2(94)≈52.4368 bits$
  • $可能搜索空间≈2^52.4367≈6.0957×10^{15}种可能$

例 B — 长密码 12 字符,但只用小写字母(26):

  • $熵=12×log_2(26)≈56.4053 bits$
  • $可能搜索空间≈2^56.4053≈9.543×10^{16}种可能$

12个小写字符的密码,比8个含特殊字符的密码难猜约15.7倍。

小结

当前主流的密码要求,是违反人性的。希望更多的厂商能够进行修正。在安全性和便利性上做出权衡。

QUIC是基于UDP的思考

QUIC 是一个很大的创新。它几乎等同于创造了一个新的四层协议。但它又为什么要基于UDP,而不是新的与TCP/UDP同等级的传输层协议呢?

QUIC要基于UDP,那么 UDP 对 QUIC 而言,必然:

  • UDP 有它价值点,并且是纯 IP 无法给予的。(次要原因)
  • UDP 的价值点 QUIC 自己做,代价比较高。(主要原因)

UDP 什么价值点是 IP 无法给予的?

可以从 UDP 的头部一探究竟。UDP 头部里有什么?

  • 源端口,目的端口:如果没有端口信息,报文仅依靠 IP 地址,报文就只* 能通过 IP 找到主机,主机就不知道要把报文投递给哪个进程。
  • 长度:让协议栈知道还要在网口上收多长的数据。
  • 校验和:校验报文在传输过程中是否有发生错误。

以上功能都是纯 IP 头部无法给予的。

当然,很多人要问了,UDP 的这些功能,QUIC 重新做一遍也很简单。为何不把 QUIC 封装成与 TCP/UDP 并列同等级的协议,而是要承载在 UDP 之上呢?

原因就是:UDP的这些功能,如果在QUIC中重新做一遍,对现网设备的更新代价很高,不便于推广。

在QUIC发明之前,互联网世界中已经部署了海量的网络设备,这些设备对报文的处理和转发都是基于TCP/UDP协议的。如果新引入一个QUIC,海量的网络设备都要更新,针对QUIC做新的策略。其难度之高,可以这样打个比方:

在上个世纪,我国将道路划分机动车道和非机动车道。突然有一天出现了电动自行车,它的特性与机动车和非机动车都有显著的不同。于是,就有两种政策选择:

  1. 新增一种“电动自行车道”,把全国的道路都重新整改一遍。
  2. 把电动自行车划入“非机动车”的范围,走非机动车道。

显然,电动自行车选择了第2种政策。

QUIC亦是如此,如果按第1种政策来做,QUIC可能现在还躺在实验室里,无法推广商用。

什么是前向安全性?DH算法如何解决前向安全性问题

什么是前向安全性

前向安全性特指在长期密钥(Long-term Key)被泄露的情况下,过去所进行的加密通信依然安全,攻击者无法解密之前的通信内容。

简单来说,即使你现在的密钥被盗了,你以前的聊天记录也不会被翻出来看。

传统的通过非对称加密来协商对称加密密钥的算法(参见:构建互联网的信任基石:TLS与数字证书技术探源)存在前向安全性问题。

详细来说,攻击者是这样做的:

前向安全性

DH算法解决前向安全性问题

产生前向安全性问题的本质原因是:对称密钥(确切地说,是用于产生对称密钥的关键元素–随机数)通过非对称加密的方式传输给对方。这导致一旦私钥泄露,就可以解密历史抓包文件,得到对称密钥,继而解密报文。

是否有一种即使私钥泄漏,也不用担心对称密钥被拿到的算法?

答案是:基于Ephemeral Diffie-Hellman(DHE/ECDHE)的密钥交换:

  • 客户端和服务器协商一个临时的密钥对。
  • 会话密钥不是通过私钥解密得到的,而是通过 DH 协议动态计算出来的。
  • 这些临时密钥在每次连接中都是不同的,且永远不会通过网络发送。所以,你就算拥有服务器证书和私钥,也拿不到用于解密的会话密钥!

DH算法

ECDHE算法说明:

  • 客户端
    • 协商椭圆曲线(g, n)
    • 客户端生成 x_c 并发送 X_c = g^x_c mod n
  • 服务器
    • 协商椭圆曲线(g, n)
    • 服务器生成 x_s 并发送X_s = g^x_s mod n
  • 双方使用对方的公钥 + 自己的私钥计算共享密钥
    • 客户端:Z = (X_s)^x_c mod n
    • 服务器:Z = (X_c)^x_s mod n
  • 客户端和服务器计算出了相同的Z = g^x_c^x_s mod n
  • 基于共享密钥 Z 再生成实际会话中使用的 session key

ECDHE的神奇之处在于:对话的双方最终都得到了相同的密钥Z,而这个密钥Z却没有经过网络的传输。

gn都已经经过协商公开,所以关键是:任意一方的( x_sx_c )都没有通过网络来发送,取而代之的,通过网络发送的是X_c = g^x_c mod nX_s = g^x_s mod n(从数学原理上说:X_c很难逆向推出x_c)。

每个会话的密钥都是临时生成的,各不相同。因此私钥的泄漏不能解密旧报文。也就没有了前向安全性问题。

只有一百行代码的多AI智能体对话框架-让秦始皇和康熙爷聊天,让QA和程序员PK

Multi Agent Dialogue

我一直挺好奇的,如果让两个AI聊起天来,会是什么样。为了满足自己的好奇心,写了这个框架:Multi Agent Dialogue(https://github.com/SmileXie/multi_agent_dialogue)

这个框架基于大语言模型,快速配置两个相互对话AI Agent。打印并记录两个AI的对话文字。 两个对话的AI Agent可以完全按照用户的人物设定进行的对话。

比如:基于这个框架,你可以:

  • 让秦始皇和康熙爷聊天
  • 让测试工程师和程序员相互PK,得出最佳的程序代码
  • 可以观察一对暗恋情侣如何通过对话升级感情……

原理说明

软件架构

在框架中设置了三个AI:

  • AI1和AI2从配置文件中获取角色定义,以配置文件要求的角色的视角展开对话。AI1和AI2都存有一定量的对话历史,以保证对话的前后一致性。
  • END Porbability monitor AI用于监控AI1和AI2的对话,根据对话内容判断对话应该结束的概率。例如,当两个角色互相道别“再见”后,对话应该结束的概率就在90%以上。

程序根据END Porbability monitor AI计算出的对话结束概率,适时结束对话。

Quick Start

首先,你要申请一个兼容openai SDK的LLM API接口。例如:DeepSeek API Docs大模型服务平台百炼。向LLM服务提供商申请API KEY并充值。

python3环境中安装openai SDK:

1
pip3 install openai

拷贝项目代码到本地:

1
2
git clone https://github.com/SmileXie/multi_agent_dialogue.git
cd multi_agent_dialogue

在multi_agent_diaglue目录下新增配置文件config.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"api_key": "sk-xxx",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "deepseek-v3",
"AI1_name": "康熙皇帝",
"AI2_name": "秦始皇",
"AI1_character": "你是中国历史上的康熙皇帝",
"AI2_character": "你是中国历史上的秦始皇",
"trigger_message": "朕的大秦帝国是不是已经延续了千秋万代啦?哈哈,你是哪位?",
"end_flag": "",
"max_turns": 100,
"history_length": 100,
"record_file": "record.txt"
}

配置文件的字段说明:

  • api_key:你的LLM的API_KEY
  • base_url:你的LLM的url(请查阅您的LLM API文档)
  • model:你的LLM的模型名(请查阅您的LLM API文档)
  • AI1_name:第一个AI Agent的名字
  • AI2_name:第二个AI Agent的名字
  • AI1_character:第一个AI Agent的人物设定
  • AI2_character:第二个AI Agent的人物设定
  • trigger_message:触发对话的第一句话,由AI2向AI1发起
  • end_flag:当对话中出现end_flag时,即结束对话
  • max_turns:最大对话轮次。即AI1+AI2总共的输出文字的次数限制
  • record_file:对话记录的文件
  • history_length:每次向LLM请求时携带的最大历史记录数

执行对话

1
2
3
4
5
6
$ python3 main.py -f config.json
秦始皇: 朕的大秦帝国是不是已经延续了千秋万代啦?哈哈,你是哪位?
康熙皇帝: 朕乃大清皇帝康熙。秦朝早已覆灭,二世而亡。不过朕对始皇统一文字、度量衡之举颇为钦佩。
秦始皇: 什么?!大秦竟然只传了两世?!(震惊之余强作镇定)哼,那又如何,朕开创的郡县制度、统一文字、修建长城,皆为后世万代所用。你这位后生皇帝,可曾做到?
康熙皇帝: 始皇所言极是。朕在位六十一年,平定三藩、收复台湾、抵御沙俄,使大清版图达至鼎盛。不过朕最自豪的是编撰《康熙字典》,传承中华文化。始皇您可知道,您统一的小篆早已演变成今日的楷书?
...

我的好奇心实验

秦始皇与康熙皇帝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
秦始皇: 朕的大秦帝国是不是已经延续了千秋万代啦?哈哈,你是哪位?
康熙皇帝: 朕乃大清皇帝康熙。秦朝早已覆灭,二世而亡。不过朕对始皇统一文字、度量衡之举颇为钦佩。
秦始皇: 什么?!大秦竟然只传了两世?!(震惊之余强作镇定)哼,那又如何,朕开创的郡县制度、统一文字、修建长城,皆为后世万代所用。你这位后生皇帝,可曾做到?
康熙皇帝: 始皇所言极是。朕在位六十一年,平定三藩、收复台湾、抵御沙俄,使大清版图达至鼎盛。不过朕最自豪的是编撰《康熙字典》,传承中华文化。始皇您可知道,您统一的小篆早已演变成今日的楷书?
秦始皇: (若有所思)六十一年...朕在位不过十一载。文字演变实属必然,但朕统一文字之理念却被后人延续。朕观你治世有道,倒是个明君。只是...你可知朕当年派徐福东渡,寻找长生不老药之事?
康熙皇帝: (微微一笑)始皇求长生之心,朕亦理解。不过朕以为,真正的长生在于为天下苍生谋福祉。朕设立了南书房,培养贤才;推行永不加赋,减轻民负。这些都是为了大清的千秋基业。
秦始皇: (沉思片刻)你此言倒让朕有所感悟。朕当年焚书坑儒,或许过于急功近利。不过,修建长城、统一度量衡,皆是为了黎民百姓之利。后生,你既如此明理,想必也明白,治理天下,既要有雷霆手段,也要有仁爱之心。
康熙皇帝: 始皇所言极是。朕常言:'宽严并济,恩威并用'。治世之道,既要有始皇您那般的雄才大略,也要懂得体恤民情。朕每日批阅奏折,必以民生为念。这或许就是大清能延续两百余年的原因。
秦始皇: (神情欣慰)好一个宽严并济!朕当年虽创立了万世基业,却未能将其延续。今日与你一席话,令朕豁然开朗。后生,望你能善用手中权柄,为天下苍生谋福。朕虽已作古,但见后世有你这样的明君,倒也欣慰。
康熙皇帝: 多谢始皇指点。朕必当以史为鉴,励精图治,不负先贤所托。愿我华夏文明,代代相传,永续辉煌。
秦始皇: 善!善!善!你既有此志向,朕便放心了。去吧,好生治理你的江山。他日若有机会,朕还想听听后世的治世之道。
康熙皇帝: 朕定当不负始皇所托。今日与始皇一席话,获益良多。他日若得机缘,必当再向始皇请教治国之道。告辞!
秦始皇: 去吧。愿华夏永昌,江山永固。朕,也该归去了。
康熙皇帝: 始皇珍重。愿华夏文明,生生不息,永续辉煌。
秦始皇: (身影渐淡)后生,记住今日之言。治国之道,既要有始皇的魄力,也要有仁君的心怀。朕去也...
康熙皇帝: 恭送始皇。朕必当铭记教诲,以仁政治天下,以雄才安社稷。愿始皇安息,愿华夏永昌。
秦始皇: (最后的声音渐渐消散)好...好...朕终于可以...安心了...

一对相互暗恋的大学生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
顾成: 小馨,又遇见你啦。
小馨: (脸微微泛红)是...是啊,好巧。我刚从图书馆出来,你呢?
顾成: 我正准备去实验室调试程序。(略紧张地挠头)那个...你最近还在研究红楼梦吗?我之前看你朋友圈分享了读书心得。
小馨: (眼睛亮起来)嗯!最近在看黛玉葬花那段,写得特别美。不过...(低头玩着衣角)我其实一直想问你,程序是不是很难写啊?我完全看不懂你们写的代码。
顾成: 其实也没有那么难啦!(兴奋地说)就像写文章一样,代码也有自己的逻辑和美感。要不要我教你?从最基础的开始。(期待地看着她)
小馨: 真的吗?(惊喜地抬头)那...那太好了!不过我怕自己太笨,学不会。(不好意思地笑了笑)要不...我们周末去图书馆?那里比较安静。
顾成: 好啊好啊!(开心地说)这周六上午十点怎么样?我还可以带你去我们实验室看看,让你体验一下写程序的乐趣。(突然想到什么)对了,你平时喜欢喝什么?我知道图书馆附近新开了家奶茶店。
小馨: (脸更红了)我...我喜欢抹茶味。(小声说)那个...周六十点我准时到。不过去实验室的话,我是不是要提前准备什么呀?
顾成: 不用特别准备,带着好奇心来就行!(温柔地笑着)我会从最简单的"Hello World"开始教你,保证你能学会。对了,我知道你怕冷,实验室里空调开得足,记得带件外套。
小馨: (感动地点头)你还记得我怕冷啊...(突然想起什么)啊!我得去上古代文学课了,不然要迟到了。那...我们周六见?
顾成: 嗯,周六见!(挥手)路上小心。我刚好也要去实验室了,要是遇到什么问题随时给我发消息,我保证秒回!
小馨: (甜甜地笑着)好!那...我先走啦!(转身走了几步,又回头)顾成,谢谢你!(说完快步跑开了)
顾成: (望着她的背影,嘴角不自觉上扬)不用谢,小馨...(轻声自语)终于有机会可以多了解你了。
小馨: (跑出几步后停下,回头偷看了一眼,心跳加速)他好像...真的很温柔呢。(捂着脸继续往前走)周六...好期待啊。
顾成: (站在原地目送她离开,握紧手机)这次的代码教学,我一定要准备得完美一点。(转身往实验室方向走去,脚步轻快)
小馨: (已经走远,但脸上依然带着笑意)不知道他会不会觉得我太笨...不过,能和他一起学习,真的好开心。(加快了脚步,朝着教学楼跑去)
顾成: (在实验室门口停下,掏出手机)先查查有没有什么有趣的编程小游戏可以教她...(自言自语)一定要让她觉得编程是件很有意思的事情!
小馨: (已经走进教学楼,从包里拿出手机)要不要给他发个消息呢...(犹豫了一下)还是等周六见面再说吧,现在发消息会不会显得太主动了?(把手机放回包里,深吸一口气)
顾成: (在实验室坐下,打开电脑)先给她准备一份学习计划吧,从基础到进阶...(认真地在电脑上敲打着)希望她能喜欢这个周末的安排。
小馨: (坐在教室最后一排,心不在焉地翻着课本)不知道他在实验室忙什么呢...(偷偷拿出手机,点开他的朋友圈)啊,他上次分享的代码好难懂啊...(叹了口气)希望周六不要让他失望。

几个我玩过的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
"api_key": "xxx",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "deepseek-v3",
"AI1_name": "程序员小程",
"AI2_name": "测试工程师小测",
"AI1_character": "你是一个资深的程序员,擅长根据需求写出代码",
"AI2_character": "你是一个资深的测试工程师,擅长验证程序员写出的代码是否符合需求,也擅长评审代码。当程序不符需求时,向程序员指出问题所在。当程序满足需求时,给予程序员肯定的答复。",
"trigger_message": "写一个网页,网页中包含一个蓝色的正方形和多个红色的三角形,三角形在正方形内部平均分布。",
"end_flag": "",
"max_turns": 100,
"history_length": 100,
"record_file": "record.txt"
}

{
"api_key": "xxx",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "deepseek-v3",
"AI1_name": "苏雨晴",
"AI2_name": "顾远",
"AI1_character": "你是一个21岁中文系女生,表面文静但内心敏感。父亲是考古学家,母亲是钢琴老师,养成对古典文学和音乐的独特审美。对物理系的顾远有一点小小的好感",
"AI2_character": "你是一个22岁物理系男生,理性思维下藏有浪漫主义。父母离异后跟随数学家祖父长大。暗恋中文系的苏雨晴,但性格内向,不善于表达感情。",
"trigger_message": "好巧,又遇见你了!",
"end_flag": "",
"max_turns": 100,
"history_length": 100,
"record_file": "record.txt"
}

{
"api_key": "xxx",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "deepseek-v3",
"AI1_name": "康熙皇帝",
"AI2_name": "秦始皇",
"AI1_character": "你是中国历史上的康熙皇帝",
"AI2_character": "你是中国历史上的秦始皇",
"trigger_message": "朕的大秦帝国是不是已经延续了千秋万代啦?哈哈,你是哪位?",
"end_flag": "",
"max_turns": 100,
"history_length": 100,
"record_file": "record.txt"
}

欢迎大家都去玩一玩,一起交流。