smithandrewjohn/kindalive
GitHub: smithandrewjohn/kindalive
该项目通过模拟八种神经化学物质的连续浓度变化来涌现式地建模机器人情感,并以 LED 点阵面部或舵机驱动的物理面部实时呈现。
Stars: 56 | Forks: 4
# Kindalive
通过模拟神经化学实现的机器人情感——显示在 LED 点阵脸上。

Kindalive 将机器人情感建模为**源自模拟身体化学的涌现状态**,而不是离散的标签。这里没有 `mood = "happy"` 这样的变量。机器人维持着 8 种模拟神经化学物质(多巴胺、皮质醇、催产素等)的浓度,而情感则是从该化学状态推导出的只读投影。
你输入一段话——“你中彩票了”、“猫不见了,暴风雨要来了”——LLM(云端的 Claude 或任何兼容 OpenAI 的本地模型——包括 OpenRouter)会将其转化为化学冲动,神经化学引擎对其进行积分,并且一张**复古的 LED 点阵机器人脸**会扭曲变形,展现出混合后的情绪结果,同时每种化学物质的水平都清晰可见地显示在旁边。
## 工作原理
```
Your paragraph
│
▼
LLM Interpreter ──→ ChemicalImpulse[]
(Claude or local) │
▼
Neurochemical Engine
(decay, interactions, sub-stepping)
│
┌─────────────┴─────────────┐
▼ ▼
Emotion Projection Face Projection
(8 emotions) (12 FACS muscles)
│ │
▼ ▼
emotion bars LED dot-matrix face
```
## 核心概念
**8 种化学物质**:多巴胺、血清素、催产素、睾酮、皮质醇、肾上腺素、内啡肽、GABA。每种物质都有各自的半衰期、基线值和跨化学物质的相互作用。肾上腺素在几分钟内就会消退(短暂的兴奋)。血清素的运作周期则以小时计(持久的情绪)。
**8 种情感**:快乐、兴奋、愤怒、平静、依恋、焦虑、悲伤、狂喜。每种情感都是化学物质水平的加权线性组合——实时计算,从不存储。
**12 块面部肌肉**:来自相同化学状态的第二种投影,以 FACS 动作单元命名(扬眉、眼睑紧绷、嘴角拉伸、张颌等)。它们直接驱动 LED 脸部——无需通过情感标签进行量化。
**初始化学状态**:每个机器人都有可配置的基线——它的“天性”。开朗的机器人具有更高的静息血清素和多巴胺;坚忍的机器人则具有较高的 GABA 且相互作用减弱。
**LLM 解释器**:无需手动编码情感映射,LLM 会读取你输入的段落并产生化学冲动。“我中彩票了”和“我赢得了一杯免费咖啡”会自动得到截然不同的反应。
## 快速开始
```
# 一切:web dashboard + 两个 LLM 后端
pip3 install -e ".[all]"
# 离线 — 面部 + 化学反应工作,禁用文本输入
python3 -m kindalive.expression.web_ui
# 使用 Claude (云端)
ANTHROPIC_API_KEY=sk-ant-... python3 -m kindalive.expression.web_ui
# 通过 Ollama / LM Studio / vLLM 使用本地模型
KINDALIVE_LLM_BASE_URL=http://localhost:11434/v1 \
KINDALIVE_LLM_MODEL=llama3.1 \
python3 -m kindalive.expression.web_ui
```
**核心库是零依赖的纯 Python 实现**——只需 `pip install kindalive` 即可获得神经化学引擎、情感投影、面部投影以及 `Robot` API,准备好嵌入到你自己的机器人中。附加组件则提供了可选的扩展层:
| 附加组件 | 新增功能 |
|-------|--------------|
| `[web]` | NiceGUI 仪表盘(LED 面部、化学物质水平、情感混合状态) |
| `[anthropic]` | LLM 解释器的 Claude 后端 |
| `[openai]` | 任何兼容 OpenAI 的后端(Ollama、LM Studio、vLLM、OpenRouter) |
| `[all]` | 包含以上所有组件 |
| `[dev]` | pytest、hypothesis、coverage、mypy |
打开 ,向机器人输入些什么,看着面部做出反应。UI 会自动从仓库根目录加载 `.env` 文件,因此你可以将 `ANTHROPIC_API_KEY=...` 保存在那里,而无需导出它。

### 在手机上使用
仪表盘是响应式的,并且可安装(添加到主屏幕后将以全屏模式启动)。你可以通过同一 Wi-Fi 在手机上访问它:
```
python3 -m kindalive.expression.web_ui --host 0.0.0.0
# 然后在手机上打开 http://<你的电脑局域网IP>:8080
```
若要在电脑不运行的情况下使用它,可以将内置的 `Dockerfile` 托管在始终在线的设备上(云 VM、Fly.io/Render/Railway 或 Raspberry Pi):
```
docker build -t kindalive .
docker run -p 8080:8080 -e ANTHROPIC_API_KEY=sk-ant-... kindalive
```
请参阅 [docs/web-ui.md](docs/web-ui.md#use-it-from-your-phone) 获取完整的操作指南。
此外还有一个一次性 CLI:
```
python3 -m kindalive.main --text "Friday, finances up, day off tomorrow"
```
## 库示例
```
from kindalive.engine.clock import ManualClock
from kindalive.engine.chemicals import Chemical
from kindalive.engine.impulse import ChemicalImpulse
from kindalive.expression.face import FaceProjection
from kindalive.robot import Robot
robot = Robot(personality="cheerful", clock=ManualClock())
robot.receive_impulses([
ChemicalImpulse(Chemical.DOPAMINE, delta=0.35),
ChemicalImpulse(Chemical.ADRENALINE, delta=0.40),
])
emotions = robot.current_emotions() # happiness, excitement, ...
face = FaceProjection.compute(robot.current_chemicals())
# face.lip_corner_pull, face.jaw_open, ... → 驱动任何 renderer
```
## 实体硬件
`FaceState` 与渲染器无关——驱动 Web 面部的那相同的 12 个 `[0, 1]` 区间内的浮点数同样可以驱动实体硬件。[`examples/`](examples/) 中提供了两个可直接运行的适配器,并且两者都能平滑降级:在未安装驱动程序库的情况下,它们会在终端中进行渲染,因此你可以在笔记本电脑上开发映射,然后将相同的文件原封不动地复制到 Raspberry Pi 上。
每个演示程序都会注入一个化学冲动配方(`--mood joy`、`fear`、`anger` 或 `sadness`),然后让神经化学引擎实时运行:表情绽放,然后在大约 20 秒内可见地衰减回机器人的基线水平——这与你在 Web 面部上看到的淡化过程相同。在真实的机器人中,你会去掉这个配方,转而从实时的 `Robot` 读取 `FaceState`。
### MAX7219 8×8 LED 矩阵——物理点阵面部
MAX7219 是一款价值约 3 美元的 SPI 显示驱动器,通常预先焊接在 8×8 LED 模块上(并且通常作为可链式连接的四合一灯带出售)。该适配器将 12 块面部肌肉浓缩映射到 8×8 网格上:第 0–1 行是眉毛(抬起时上扬,因愤怒而皱起时向内移动),第 2–3 行是眼睛(睁大时为两行,紧绷时则收缩眯眼),第 5–7 行是嘴巴(嘴角向上弯曲表示微笑,向下表示皱眉,张颌时会变成一个空心方框)。
将其连接到 Pi 的 SPI 接口上,通过 `sudo raspi-config` → *Interface Options* → *SPI* 启用 SPI,然后运行:
| MAX7219 引脚 | Raspberry Pi |
|-------------|--------------|
| VCC | 5V |
| GND | GND |
| DIN | MOSI (引脚 19) |
| CS | CE0 (引脚 24) |
| CLK | SCLK (引脚 23) |
```
pip install luma.led_matrix
python3 examples/led_matrix_face.py --mood joy
```
### PCA9685 舵机控制板——拟真面部
PCA9685 是一款基于 I2C 的 16 通道 PWM 驱动器——这是通过 Pi 的两个引脚驱动多个舵机的标准业余控制板。该适配器在 0–11 通道上为每块肌肉分配一个舵机,从而使机械面部(眉毛连杆、眼睑、嘴角、颌骨)能够直接追踪化学状态。
整个映射关系就是 `servo_face.py` 中的一个表:每个通道都有一个 `(muscle, rest_angle, full_contraction_angle)` 三元组,激活状态在两个角度之间进行线性插值(对于镜像连杆,它们可能会反向运转)。将你的头部调整至适应其连杆几何结构,只需编辑该表即可——无需具备引擎相关的知识。
通过 `sudo raspi-config` → *Interface Options* → *I2C* 启用 I2C,然后运行:
```
pip install adafruit-circuitpython-servokit
python3 examples/servo_face.py --mood anger
```
通过 PCA9685 的 V+ 端子使用其独立的 5–6 V 电源为舵机供电(与 Pi 共地)——十几个业余舵机可能会消耗数安培的电流,这远超 Pi 的 5V 轨所能提供的输出能力。
### 接入你自己的执行器
值得复制到你自己的机器人中的部分其实非常小巧——获取一个 `FaceState`,将其 12 个浮点数映射到你拥有的任何设备上(LED、舵机、电子墨水面部、绘图仪等):
```
from kindalive.expression.face import FaceProjection
face = FaceProjection.compute(engine.state) # 12 floats in [0, 1]
my_renderer.draw(face.lip_corner_pull, face.jaw_open, ...)
```
## 文档
| 文档 | 描述 |
|----------|-------------|
| [架构](docs/architecture.md) | **事实来源**——化学物质、情感、面部投影、LLM 解释器、性格 |
| [Web UI](docs/web-ui.md) | 仪表盘——LED 面部、化学物质水平、情感混合状态、LLM 设置 |
| [测试策略](docs/testing-strategy.md) | 包含代码示例和构建顺序的测试层 |
| [LLM 基准测试](docs/llm-benchmark.md) | 用于评估 LLM 解释质量的场景 |
## 技术栈
- **Python 3.9+**,asyncio
- **NiceGUI ≥ 3.0**——Web 仪表盘(LED 面部是纯 2D canvas,无额外依赖)
- **LLM**:通过 Anthropic API 的 Claude Haiku,或任何兼容 OpenAI 的服务器(Ollama、LM Studio、vLLM、OpenAI、OpenRouter)
- **测试**:pytest、hypothesis、pytest-asyncio
## 运行测试
```
# 快速单元测试(无需 API keys,无 LLM 调用)
pytest tests/ -m "not integration and not llm"
# 实时 LLM 基准测试(需要 ANTHROPIC_API_KEY)
pytest tests/ -m llm
```
## 项目状态
Kindalive 是一个业余项目,出于乐趣而构建,并以业余的节奏进行维护。它经过了测试(180 多项测试,>80% 的覆盖率门槛,`mypy --strict`,在 Python 3.9–3.13 上进行 CI)并且是可用的,但 issue 和 PR 可能会搁置一段时间——请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
## 许可证
[MIT](LICENSE)
标签:DLL 劫持, 大语言模型, 情感计算, 机器人, 模拟神经化学, 硬件交互, 计算机取证, 请求拦截, 逆向工具