Join our community Discord: AI Stack Devs
AI 小镇是一个虚拟城镇,AI 角色在其中生活、聊天和社交。
本项目是一个可部署的入门套件,方便您轻松构建和定制自己的 AI 小镇版本。灵感来源于研究论文
Generative Agents: Interactive Simulacra of Human Behavior。
该项目的主要目标不仅是让开发充满乐趣,更是提供一个基础稳固、易于扩展的平台。后端原生支持共享全局状态、事务和模拟引擎,适用于从简单的实验项目到可扩展的多人在线游戏等各种场景。次要目标是提供一个 JS/TS 框架,因为该领域的大多数模拟器(包括上述原始论文)都是用 Python 编写的。
llama3,嵌入模型为 mxbai-embed-large。其他致谢:
<Game/> 组件渲染均由 PixiJS 提供支持。总体步骤如下:
有几种方式可以在 Convex(后端)上运行应用。
注意:如果您使用 Windows,请参阅 下方。
git clone https://github.com/a16z-infra/ai-town.git
cd ai-town
npm install
如果没有登录 Convex 账户,将会要求登录。
运行项目:
npm run dev
现在可以访问 http://localhost:5173。
如果想分别运行前端和后端(保存后端函数时会同步),可以在两个终端中执行:
npm run dev:frontend
npm run dev:backend
详情请见 package.json。
也可以使用自托管的 Docker 容器运行 Convex 后端。以下设置将前端、后端和仪表板全部通过 Docker Compose 运行。
docker compose up --build -d
如果传递了 -d 参数,容器将在后台持续运行。完成一次后,可以使用 stop 和 start 命令控制服务。
要登录仪表板并从 Convex CLI 进行部署,需要生成一个管理员密钥。
docker compose exec backend ./generate_admin_key.sh
将其添加到 .env.local 文件中。注意:如果执行 down 和 up 操作,需要重新生成密钥并更新 .env.local。
# in .env.local
CONVEX_SELF_HOSTED_ADMIN_KEY="<admin-key>" # 确保有引号
CONVEX_SELF_HOSTED_URL="http://127.0.0.1:3210"
然后设置 Convex 后端(只需一次):
npm run predev
持续部署新代码到后端并打印日志:
npm run dev:backend
要查看仪表板,请访问 http://localhost:6791 并提供之前生成的管理员密钥。
如果使用 Ollama 进行本地推理,需要配置 Docker 以连接到它。
npx convex env set OLLAMA_HOST http://host.docker.internal:11434
测试连接(在保证 Ollama 正在运行 后):
docker compose exec backend /bin/bash curl http://host.docker.internal:11434
如果显示 "Ollama is running",则表示成功!否则,请查看 故障排除 部分。
注意:如果想要在后端云端运行时使用 LLM,可以使用基于云的 LLM API,如 OpenAI 或 Together.ai,或者将流量从云端代理到本地 Ollama。相关说明见 下方。
默认情况下,应用会尝试使用 Ollama 进行完全本地化运行。
ollama serve。如果应用已在运行,ollama serve 会提示警告。ollama pull llama3 以下载 llama3。ollama run llama3 进行测试。Ollama 模型选项可查阅 此处。
如果要自定义模型,请调整 convex/util/llm.ts 或设置 npx convex env set OLLAMA_MODEL # model。如果要修改嵌入模型:
convex/util/llm.ts 中的 OLLAMA_EMBEDDING_DIMENSION,并确保:export const EMBEDDING_DIMENSION = OLLAMA_EMBEDDING_DIMENSION;npx convex env set OLLAMA_EMBEDDING_MODEL # model。注意:如果遇到性能缓慢,可以在 constants.ts 中将 NUM_MEMORIES_TO_SEARCH 设置为 1,以减少对话提示的大小。
使用 OpenAI 需要:
// 在 convex/util/llm.ts 中更改以下行:
export const EMBEDDING_DIMENSION = OPENAI_EMBEDDING_DIMENSION;
设置 OPENAI_API_KEY 环境变量。如果没有,可访问 https://platform.openai.com/account/api-keys。
npx convex env set OPENAI_API_KEY 'your-key'
可选:通过 OPENAI_CHAT_MODEL 和 OPENAI_EMBEDDING_MODEL 选择模型。
使用 Together.ai 需要:
// 在 convex/util/llm.ts 中更改以下行:
export const EMBEDDING_DIMENSION = TOGETHER_EMBEDDING_DIMENSION;
设置 TOGETHER_API_KEY 环境变量。如果没有,可访问 https://api.together.xyz/settings/api-keys。
npx convex env set TOGETHER_API_KEY 'your-key'
可选:通过 TOGETHER_CHAT_MODEL、TOGETHER_EMBEDDING_MODEL 选择模型。嵌入模型的维度必须与 EMBEDDING_DIMENSION 匹配。
您可以使用任何兼容 OpenAI 的 API,例如 Anthropic、Groq 或 Azure。
convex/util/llm.ts 中的 EMBEDDING_DIMENSION 以匹配嵌入模型的维度。llm.ts 中的 getLLMConfig 或设置环境变量:npx convex env set LLM_API_URL 'your-url'
npx convex env set LLM_API_KEY 'your-key'
npx convex env set LLM_MODEL 'your-chat-model'
npx convex env set LLM_EMBEDDING_MODEL 'your-embedding-model'
注意:如果不需要 LLM_API_KEY,则不要设置。
如果更改了 LLM 提供商或嵌入模型,应删除数据并重新开始。因为用于记忆的嵌入是基于所选嵌入模型的,向量数据库的维度必须与嵌入模型的维度匹配。如何进行删除,请参见 下方。
注意:每次更改角色数据后,应重新运行 npx convex run testing:wipeAllTables,然后运行 npm run dev 重新将数据上传到 Convex。这是因为角色数据在初始加载时发送到 Convex。但请注意,npx convex run testing:wipeAllTables 将删除所有数据。
创建自己的角色和故事:所有角色、故事及其精灵图表引用均存储在 characters.ts 中。可以从更改角色描述开始。
更新精灵图表:在 data/characters.ts 中,会看到如下代码:
ts
export const characters = [
{
name: 'f1',
textureUrl: '/assets/32x32folk.png',
spritesheetData: f1SpritesheetData,
speed: 0.1,
},
...
];
您需要为角色找到精灵图,并在相应的文件中定义精灵运动/资源(上述示例中,f1SpritesheetData 定义在 f1.ts 中)。
data/gentle.js 加载到 convex/init.ts 中。更新地图,请按以下步骤操作:convertMap.js 脚本将 JSON 转换为引擎可用的格式。console
node data/convertMap.js <mapDataPath> <assetPath> <tilesetpxw> <tilesetpxh>
<mapDataPath>: Tiled JSON 文件的路径。<assetPath>: 瓦片资源图片的路径。<tilesetpxw>: 瓦片集宽度(像素)。<tilesetpxh>: 瓦片集高度(像素)。生成 converted-map.js,您可以像使用 gentle.js 一样使用它。要每天生成背景音乐,请创建 Replicate 账户,并在个人资料的 API 令牌页面 创建一个令牌。npx convex env set REPLICATE_API_TOKEN # token
仅当可以接收 Replicate 的 webhook 时才有效。如果在正常的 Convex 云端运行,则默认有效。如果是自托管,需要配置它指向应用 URL 的 /http 路径。如果使用 Docker Compose,将是 http://localhost:3211,但需要将流量代理到本地机器。
注意:如果窗口空闲超过 5 分钟,模拟将暂停。加载页面将恢复模拟。您也可以通过 UI 中的按钮手动冻结和解冻世界。如果希望在没有浏览器的情况下运行世界,可以注释掉 convex/crons.ts 中的 "stop inactive worlds" 定时任务。
convex/music.ts 中的提示词更改背景音乐。convex/crons.ts 中的 generate new background music 任务来更改生成新音乐的频率。在活动过多时停止后端
这将停止运行引擎和代理。您仍然可以运行查询和函数进行调试。
npx convex run testing:stop
停止后重新启动后端
npx convex run testing:resume
在游戏引擎或代理未运行时启动引擎
npx convex run testing:kick
归档世界
如果想重置世界并从头开始,可以归档当前世界:
npx convex run testing:archive
这样,您仍然可以在仪表板中查看世界数据,但引擎和代理将不再运行。
然后可以通过 init 创建一个全新的世界。
npx convex run init
暂停后端部署
可以进入 dashboard 中的部署设置,暂停和恢复部署。这将停止所有函数,无论是客户端调用的、定时调度的还是定时任务调用的。请将此作为最后手段,因为上述有更温和的停止方式。
步骤:
首先需要安装 WSL2。按照 此指南 在 Windows 机器上设置 WSL2。建议使用 Ubuntu 作为 Linux 发行版。
打开 WSL 终端(Ubuntu)并更新软件包:
sh
sudo apt update
NVM(Node 版本管理器)有助于管理多个 Node.js 版本。安装 NVM 和 Node.js 18(稳定版本):
sh
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
source ~/.bashrc
nvm install 18
nvm use 18
某些依赖需要 Python。安装 Python 和 Pip:
sh
sudo apt-get install python3 python3-pip sudo ln -s /usr/bin/python3 /usr/bin/python
至此,您可以按照 上方 的说明继续操作。
在运行应用之前,需要确保 Convex 函数已部署到生产环境中。注意:这假设您使用的是默认的 Convex 云产品。
npx convex deploy 部署 Convex 函数到生产环境。npx convex run init --prod。要将本地数据传输到云端,可以运行 npx convex export,然后使用 npx convex import --prod 导入。
如果要清除现有数据,可以运行 npx convex run testing:wipeAllTables --prod。
可以通过 git revert b44a436 恢复 Clerk 认证。或者查看该差异以了解移除认证的更改内容。
创建 Clerk 账户
VITE_CLERK_PUBLISHABLE_KEY 和 CLERK_SECRET_KEY 添加到 .env.local。VITE_CLERK_PUBLISHABLE_KEY=pk_***
CLERK_SECRET_KEY=sk_***
npx convex env set CLERK_ISSUER_URL # 例如 https://your-issuer-url.clerk.accounts.dev/
vercel login 在 codespaces CLI 中进行身份验证。vercel --prod 将应用部署到 Vercel。我们支持使用 Ollama 进行对话生成。为了使其可以从网络访问,可以使用 Tunnelmole 或 Ngrok 等工具,以便云端后端向本地机器上运行的 Ollama 发送请求。
步骤:
sh
npx convex env set OLLAMA_HOST # 替换为上一步中的 tunnelmole/ngrok 唯一 urlTunnelmole 是一个开源隧道工具。
您可以通过以下方式之一安装 Tunnelmole:
npm install -g tunnelmolecurl -s https://tunnelmole.com/sh/install-linux.sh | sudo bashcurl -s https://tunnelmole.com/sh/install-mac.sh --output install-mac.sh && sudo bash install-mac.shexe 文件 here 并将其放在 PATH 中。安装 Tunnelmole 后,运行以下命令:
tmole 11434
Tunnelmole 应该会输出一个唯一的 URL。
Ngrok 是一个流行的闭源隧道工具。
安装并认证 ngrok 后,运行以下命令:
ngrok http http://localhost:11434
Ngrok 应该会输出一个唯一的 URL。
可以通过运行以下命令清空数据库:
npx convex run testing:wipeAllTables
然后重置:
npx convex run init
如果在应用启动时遇到 Node 版本错误,请使用 Node 版本 18,这是最稳定的版本。可以通过 安装 nvm 并运行 nvm install 18 和 nvm use 18 来实现。
如果后端无法与 Ollama 通信,根据您的设置,调试方法不同:
npx convex env set OLLAMA_HOST http://localhost:11434
默认情况下,主机设置为 http://127.0.0.1:11434。某些系统更喜欢 localhost ¯_(ツ)_/¯。
如果在按照 windows 和常规 安装 说明操作后仍然无效,并且您 没有 使用 Docker,可以尝试以下方法。
如果使用 Docker,请参阅 下一节 的 Docker 故障排除。
对于直接在 Windows 上运行,可以尝试以下方法:
unzip 和 socat:sh
sudo apt install unzip socat
socat 以桥接 Ollama 端口运行以下命令来桥接端口:
sh
socat TCP-LISTEN:11434,fork TCP:$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):11434 &
sh
curl http://127.0.0.1:11434
如果响应 OK,则 Ollama API 应该可以访问。
如果后端无法与 Ollama 通信,有几点需要检查:
Docker 版本是否至少为 18.03?这样才可以在容器内部使用 host.docker.internal 主机名连接到主机。
Ollama 是否在运行?可以通过在容器外部运行 curl http://localhost:11434 来检查。
是否能从容器内部访问 Ollama?可以通过运行 docker compose exec backend curl http://host.docker.internal:11434 来检查。
如果 1 和 2 正常,但 3 不正常,可以使用 socat 将流量从容器内部桥接到主机上运行的 Ollama。
socat。sh
docker compose exec backend /bin/bash
HOST_IP=YOUR-HOST-IP
socat TCP-LISTEN:11434,fork TCP:$HOST_IP:11434
保持此命令运行。
sh
npx convex env set OLLAMA_HOST http://localhost:11434
sh
docker compose exec backend curl http://localhost:11434
如果响应 OK,则 Ollama API 可访问。否则,尝试将前两个命令中的 http://localhost:11434 更改为 http://127.0.0.1:11434。
如果想检查容器内部情况,可以为 frontend、backend 或 dashboard 服务启动一个交互式的 Docker 终端:
docker compose exec frontend /bin/bash
要退出容器,运行 exit。
docker compose exec frontend npx update-browserslist-db@latest
Convex 是一个托管的后端平台,内置数据库,允许您使用 TypeScript 编写 数据库模式 和 服务器函数。服务器端数据库 查询 自动 缓存 和 订阅 数据,为我们的 React 客户端 中的 实时 useQuery 钩子 提供支持。此外还提供 Python、Rust、ReactNative 和 Node 客户端,以及一个简单的 HTTP API。
数据库支持 NoSQL 风格文档,具有 可选模式验证、关系 和 自定义索引(包括嵌套对象中的字段)。
query 和 mutation 服务器函数具有事务性、低延迟的数据库访问,并且利用我们的 v8 运行时 和 确定性护栏 提供市场上最强大的 ACID 保证:立即一致性、可序列化隔离以及通过 乐观多版本并发控制 (OCC / MVCC) 自动解决冲突。
action 服务器函数 可以访问外部 API,并在我们经过优化的 v8 运行时 或更灵活的 node 运行时 中启用其他副作用和非确定性。
开发以云优先,具有 服务器函数的热重载 编辑功能(通过 CLI)、预览部署、日志和异常报告集成。有一个 仪表板 UI 用于 浏览和编辑数据、编辑环境变量、查看日志、运行服务器函数 等。
内置功能包括 响应式分页、文件存储、响应式文本搜索、向量搜索、HTTP 端点(用于 Webhook)、快照导入/导出、流式导入/导出,以及用于 函数参数 和 数据库数据 的 运行时验证。
所有功能自动扩展,并且 免费开始。