Skip to main content
AemeathCode 吉祥物

AemeathCode

一个从零手搓的 Coding Agent —— 既是能跑的终端 AI Agent,也是一趟看得见的系统工程学习历程。

Python License: MIT Built with asyncio TUI: Textual MCP CI

简体中文 · English

AemeathCode TUI 启动后的界面

左栏 Status / Sessions / Thinking · 中间 Content 和输入行 · 右栏 Tasks / Changes / MCP / Skills。


它是什么

给它一个目标,它自己规划步骤、读写文件、执行命令、观察结果,循环推进直到做完 —— 全程在终端里看得见。

它由两个进程组成:前台界面和后台常驻的 daemon,中间是一条自己实现的多路复用协议。ReAct 循环、工具注册表、会话记忆、权限审批、上下文压缩、子 agent、MCP 客户端,全部用纯 Python + asyncio 从零写,没有用任何 agent 框架。

这是一个学习与展示型项目。它能真实执行 shell 命令、真实写文件 —— 请在你信任的目录里跑(见安全声明)。


装上,跑起来

支持 Linux / macOS / Windows + WSL2。Windows 原生跑不起来,目前不打算适配。

为什么 Windows 原生不支持

不是没适配好,是几处核心机制本身就依赖 POSIX:

位置 Windows 上的问题
daemon 收 SIGINT / SIGTERM 用的 loop.add_signal_handler,Windows 事件循环没有这个 API
aemeath stop 靠进程组信号收尾,Windows 没有进程组信号这套东西
bash 工具 整个工具是按 POSIX shell 写的,落到 cmd.exe 上语义全变

硬撑着跑起来只会得到一个处处是坑的版本,所以选择明确不支持。Windows 上装个 WSL2 再照下面走:

wsl --install          # 管理员 PowerShell,装完重启,之后所有命令都在 WSL 终端里敲

一键安装启动

command -v uv >/dev/null || curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
uv tool install aemeathcode && aemeath

检测 uv,没有就装,然后装 AemeathCode 并启动。

  • 前置只有 uv 一件,Python 无需下载。已经有 pipx 也行:pipx install aemeathcode
  • 首次启动弹配置向导,问 API Key / Base URL / 模型名。任何 Anthropic Messages API 兼容的端点都行(官方、DeepSeek、自建网关)
  • 命令名 aemeath,包名 aemeathcode —— 升级卸载用包名:uv tool upgrade aemeathcode / uv tool uninstall aemeathcode
  • 退出界面后 daemon 仍在后台常驻(下次秒进),aemeath stop 关掉

显示 harness 概况

/about:版本、模型、会话 ID 与上下文占用

/about —— 版本、模型、会话 ID、上下文占用。


它怎么工作

ReAct 循环

AemeathCode 正在执行一个 run

一个 run 正在跑:中间是工具调用和逐字输出的回答,左边是它的思考,右边是它给自己列的任务。

一个 run 是一段循环:对话发给模型 → 模型返回回答或 tool_use → 执行工具 → tool_result 写回对话 → 再次发给模型,直到不再返回 tool_use。

每个 tool_use 必须在下一轮有对应的 tool_result,数量与顺序都要对上,否则该轮对话被 API 拒绝。执行失败、权限拒绝、参数缺失同样返回 tool_result,内容为错误说明。

内置八类工具:读文件、写文件、跑 shell、列目录、任务增删查改、长期笔记、加载 skill、派子 agent。

动手前它会问你

权限审批:写文件前弹出确认,并显示完整的待写内容

写文件和执行命令在进入工具之前被拦截,daemon 通过同一条连接反向请求前端授权,方向与常规请求相反。授权可选「这次」或「永远」,后者会被记住。

  • 审批面板展示完整的待写内容与完整命令,不截断
  • 被拒绝的调用在 Content 留一行记录

它记得住东西

记忆分三层作用域:

范围 存什么 活多久
一个 run 内 这一轮的思考、工具调用和结果 run 结束
一个 session 内 多轮对话的完整历史 落盘,可以 /resume 回来接着聊
跨 session agent 自己用 note_save 写下的长期笔记、手写的项目记忆 AEMEATH.md 一直在

消息按 run 增量存储,索引负责拼接成完整历史,恢复会话时按索引重建,不读取单一大文件。

上下文满了会自己压

历史逼近 token 预算时自动压缩:较早的轮次经一次独立的辅助 LLM 调用概括为摘要,最近若干轮逐字保留。压缩只作用于内存中的工作副本,磁盘上的原始记录不变,resume 得到的仍是完整历史。

能力边界可以往外扩

  • 子 agent —— 子任务在隔离上下文中执行,只回传结果,中间过程不进入主对话;可指定角色(profiles)
  • Skills —— 按需加载的操作手册,常驻的只有简介,调用 use_skill 时才载入正文
  • MCP —— 作为客户端连接外部 server,其工具注册进同一张 ToolRegistry,在模型侧与内置工具无区别

自定义 skill、项目记忆、MCP 配置怎么写,见 examples/。


S0 → S7:它是怎么长出来的

八个阶段推出来的,每个阶段解决一个明确的工程问题:

阶段 解决的工程问题 关键机制
S0 两个进程怎么可靠通信 守护进程、TCP 粘包与分帧、NDJSON、JSON-RPC 2.0、asyncio 并发、优雅关闭
S1 怎么让它自己用工具干活 ReAct 循环、工具注册表、领域类型 / 防腐层、发布订阅事件、依赖注入
S2 一根连接怎么同时跑请求和事件流 多路复用、Future 请求/响应配对、后台作业、pub/sub-over-network、状态与逻辑分离
S3 从只读观察者到会写会跑会规划 异步子进程、路径安全、任务系统、Trace 可观测性、装饰器 / 包装器模式
S4 怎么跨轮次 / 跨会话记住东西 记忆三层作用域、增量存储 + 索引、指针模型、tool_use/tool_result 配对铁律、进程组信号
S5 危险操作怎么在动手前拦下来 反向 RPC(daemon 问客户端)、三态 policy、记住已批、fail-closed、多态替换条件分支
S6 上下文满了怎么办 token 预算判定、自动压缩、辅助 LLM 通道、工作副本与持久副本分家
S7 怎么扩展能力边界 子 agent(隔离上下文)、角色 profiles、按需加载的 skills、MCP 客户端(stdio JSON-RPC 握手)

对应 git tag stage-0 … stage-7,可按顺序 checkout 阅读。


架构

两个进程,一条连接

界面和大脑是两个独立进程,中间只有一条 TCP 连接,上面同时跑三种流量。

两个进程,一条 TCP 连接:前端 ↔ 连接 ↔ daemon ↔ 外部 MCP server

三种流量:

流量 方向 什么时候用
请求 / 响应 前端 → daemon → 前端 发起一个 run、列会话、查 token 用量
事件流 daemon → 前端(单向推) 模型逐字吐、工具开始 / 结束、触发压缩
反向审批 daemon → 前端 → daemon 要写文件、要跑命令,停下来等你点同意

反向审批的方向与前两种相反,daemon 是发起方。三者共用同一条连接、同一套信封格式、同一个读循环,靠信封类型区分。

一个 run 在 daemon 里走过哪里

一个 run 在 daemon 里的路径:Runner → AgentLoop,循环调用 LLMProvider 与 ToolRegistry

图上两条回边就是循环:tool_use 从模型回到 loop,tool_result 从工具回到 loop。走向由 stop_reason 决定:tool_use 进入下一轮,end_turn 正常结束;max_tokens、refusal、未知值和 max_steps 耗尽都中止并记为失败。

源码在 src/aemeathcode/:

层 位置 职责
协议 bus/、transport/ 信封分帧、多路复用、事件广播、反向审批管道
编排 core/runner.py、core/context.py 后台 run 调度、per-run 执行上下文
Agent agent/loop.py、agent/tools/、agent/llm/ ReAct 循环、工具注册表、LLM 防腐层
能力 core/permissions/、core/compact/、core/session/、core/memory/、core/trace/ 权限、压缩、会话/记忆、可观测性
扩展 core/subagent(工具内)、core/agents/、core/skills/、core/mcp/ 子 agent、角色、技能、MCP 客户端
前端 cli/、tui/ 命令行 / Textual TUI

参考

CLI 命令速查

run / chat / watch / tui 在连接前都会自动确保 daemon 在跑(没有就后台拉起),不用手动开 core。

命令 作用
aemeath 进入 TUI 工作台(等价于 aemeath tui)
aemeath stop 关闭后台常驻的 daemon
aemeath init 重跑配置向导,写全局配置(daemon 在跑会自动重启使其生效)
aemeath init --local 同上,但只写当前项目的 .aemeath/.env
aemeath mcp add <name> <命令...> 注册一个 MCP server(下次启动 daemon 时连上)
aemeath run "<目标>" 单轮模式:建一个 single-turn 会话跑一发就退
aemeath chat 多轮模式:REPL,复用同一会话连续对话
aemeath watch 观察者:旁观所有正在跑的 run 的事件流
aemeath trace 打印最近一次运行的时间线(LLM / 工具耗时汇总)
aemeath ping 探活:测 daemon 是否在线(不会自动拉起)
aemeath core 手动在前台启动 daemon(想看它的日志时用;平时不用)

TUI 里的快捷键:^↑/^↓ 选会话 · ^u/^d 滚 content · ^j/^k 滚 thinking · ^y 复制最后一条回答 · ^r 复制整个 content · ^q 退出。斜杠命令:/resume /clear /usage /mcp /about /help。

配置:改模型、改 Key、按项目覆盖

首次运行的向导已写好全局配置,aemeath init 可随时重跑。

配置按三级读取,上面的覆盖下面的:

优先级 位置 用途
1(最高) 真正的 shell 环境变量 临时覆盖,如 AEMEATH_PORT=8888 aemeath
2 当前目录的 .aemeath/.env 这个项目专用(换模型 / 换 key)
3(兜底) ~/.config/aemeath/.env 全局:配一次,到处能用

想只给某个项目换模型或 key,三种方式随便挑:

aemeath init --local            # ① 向导写 .aemeath/.env(不带 --local 是写全局)
cp .env.example .aemeath/.env   # ② 从模板抄一份改(全部可用变量都在模板里)
                                # ③ 或者手写 .aemeath/.env,只放要覆盖的那几行

项目级配置读 .aemeath/.env,不是项目根目录的 .env。agent 有 bash 工具、子进程继承环境变量,只读自己的文件才不会把你的 DATABASE_URL 之类卷进去。.aemeath/ 自带一张自我忽略的 .gitignore。

看源码 / 参与开发
git clone https://github.com/Nijikasuki/AemeathCode.git
cd AemeathCode
uv sync
uv run aemeath        # 之后所有命令前加 uv run
uv run pytest -q      # 114 passed

测试覆盖 framing / registry / policy / invocation / broadcaster / EventBus / skills / profiles / context / ReAct loop / budget / MCPTool / task / note / session,外加一条 MCP 端到端集成测试。


安全声明

AemeathCode 会真实执行 shell 命令、读写本地文件。内置的权限审批不能替代下面三条:

  • 在隔离环境(容器 / 沙箱 / 专用目录)里运行,不要指向重要数据
  • 审批时看清命令再批,allow_always 会被记住
  • API Key 放 .aemeath/.env 或 ~/.config/aemeath/.env,不要提交

本项目用于学习与研究,使用者对其行为负责。

License

MIT © 2026 Nijikasuki

实现思路参考了 KamaClaude 的分阶段设计。欢迎开 issue 交流实现细节。


AemeathCode

Metadata

Release files for aemeathcode 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aemeathcode 0.2.2
File Size Uploaded
aemeathcode-0.2.2.tar.gz 153.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aemeathcode 0.2.2
File Interpreter ABI Platform
aemeathcode-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 290.8 kB

Release files / aemeathcode-0.2.2.tar.gz

Download URL aemeathcode-0.2.2.tar.gz
Size 153.8 kB
Tags Source
SHA-256 checksum
How to use checksums
287e45d5501b0ed155163e2d36636aae8db983b052775179791b287252b2de54
BLAKE2b-256 checksum
How to use checksums
5d842093f48ab86ac6343be9dd98e6984e6494aab42c7b7a01ac22fedcd571d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / aemeathcode-0.2.2-py3-none-any.whl

Download URL aemeathcode-0.2.2-py3-none-any.whl
Size 137.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ca8264f5a31e93f13215061bbcd34d4e8f8176f14756796038d4a53098634a1b
BLAKE2b-256 checksum
How to use checksums
d8d67d81805fd606ded59564b031978b5c1808630d34b96fcafeaca1983f4edc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.2.3

2 release files

This release

0.2.2 This release

2 release files

0.2.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page