pynanoagent 0.1.0.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pynanoagent-0.1.0.dev0/.github/workflows/publish.yml +27 -0
- pynanoagent-0.1.0.dev0/.gitignore +27 -0
- pynanoagent-0.1.0.dev0/LICENSE +21 -0
- pynanoagent-0.1.0.dev0/PKG-INFO +149 -0
- pynanoagent-0.1.0.dev0/README.md +123 -0
- pynanoagent-0.1.0.dev0/docs/DESIGN.md +1200 -0
- pynanoagent-0.1.0.dev0/docs/v0.1-design.md +531 -0
- pynanoagent-0.1.0.dev0/nanoagent/__init__.py +24 -0
- pynanoagent-0.1.0.dev0/nanoagent/api.py +93 -0
- pynanoagent-0.1.0.dev0/nanoagent/cli/__init__.py +1 -0
- pynanoagent-0.1.0.dev0/nanoagent/cli/main.py +65 -0
- pynanoagent-0.1.0.dev0/nanoagent/core/__init__.py +48 -0
- pynanoagent-0.1.0.dev0/nanoagent/core/context.py +58 -0
- pynanoagent-0.1.0.dev0/nanoagent/core/errors.py +14 -0
- pynanoagent-0.1.0.dev0/nanoagent/core/hooks.py +66 -0
- pynanoagent-0.1.0.dev0/nanoagent/core/loop.py +111 -0
- pynanoagent-0.1.0.dev0/nanoagent/core/message.py +46 -0
- pynanoagent-0.1.0.dev0/nanoagent/core/protocols.py +78 -0
- pynanoagent-0.1.0.dev0/nanoagent/core/stop.py +17 -0
- pynanoagent-0.1.0.dev0/nanoagent/llm/__init__.py +13 -0
- pynanoagent-0.1.0.dev0/nanoagent/llm/echo.py +24 -0
- pynanoagent-0.1.0.dev0/nanoagent/llm/openai_compat.py +110 -0
- pynanoagent-0.1.0.dev0/nanoagent/memory/__init__.py +9 -0
- pynanoagent-0.1.0.dev0/nanoagent/memory/backend.py +25 -0
- pynanoagent-0.1.0.dev0/nanoagent/strategies/__init__.py +14 -0
- pynanoagent-0.1.0.dev0/nanoagent/strategies/context.py +25 -0
- pynanoagent-0.1.0.dev0/nanoagent/strategies/permission.py +24 -0
- pynanoagent-0.1.0.dev0/nanoagent/strategies/stop.py +18 -0
- pynanoagent-0.1.0.dev0/nanoagent/tools/__init__.py +11 -0
- pynanoagent-0.1.0.dev0/nanoagent/tools/builtin.py +50 -0
- pynanoagent-0.1.0.dev0/nanoagent/tools/decorator.py +65 -0
- pynanoagent-0.1.0.dev0/nanoagent/tools/registry.py +32 -0
- pynanoagent-0.1.0.dev0/nanoagent/tools/schema.py +74 -0
- pynanoagent-0.1.0.dev0/pyproject.toml +58 -0
- pynanoagent-0.1.0.dev0/tests/test_api.py +62 -0
- pynanoagent-0.1.0.dev0/tests/test_cli.py +21 -0
- pynanoagent-0.1.0.dev0/tests/test_core.py +101 -0
- pynanoagent-0.1.0.dev0/tests/test_llm.py +78 -0
- pynanoagent-0.1.0.dev0/tests/test_loop.py +82 -0
- pynanoagent-0.1.0.dev0/tests/test_memory.py +27 -0
- pynanoagent-0.1.0.dev0/tests/test_strategies.py +49 -0
- pynanoagent-0.1.0.dev0/tests/test_tools.py +144 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# 发布时机:在 GitHub 上 "Releases → Draft a new release" 发布一个 release(建议打 tag v0.1.0.devN)即触发。
|
|
4
|
+
# 用 PyPI Trusted Publishing(OIDC),无需 API token;需在 PyPI 配好 pending/trusted publisher:
|
|
5
|
+
# Project=nanoagent, Owner=eastonsuo, Repo=nanoagent, Workflow=publish.yml, Environment=pypi
|
|
6
|
+
on:
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
|
+
workflow_dispatch: {} # 也允许手动触发(Actions 页点 Run workflow)
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: pypi # 与 PyPI 表单的 Environment name 一致;可在仓库 Settings→Environments 建
|
|
15
|
+
permissions:
|
|
16
|
+
id-token: write # OIDC:Trusted Publishing 凭此换取上传凭证,免 token
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.11"
|
|
22
|
+
- name: Build sdist + wheel
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade build
|
|
25
|
+
python -m build
|
|
26
|
+
- name: Publish to PyPI (trusted publishing)
|
|
27
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 本地文档:交接协议 / 评审记录 / AI 工作指南 —— 不纳入版本控制(不公开)
|
|
2
|
+
_internal/
|
|
3
|
+
CLAUDE.md
|
|
4
|
+
|
|
5
|
+
# Python
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*.egg-info/
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
|
|
15
|
+
# 编辑器 / 系统
|
|
16
|
+
.idea/
|
|
17
|
+
.vscode/
|
|
18
|
+
.DS_Store
|
|
19
|
+
|
|
20
|
+
# 本地启动脚本 / 环境变量(可能含 API key)—— 绝不提交
|
|
21
|
+
start.sh
|
|
22
|
+
.env
|
|
23
|
+
*.local.sh
|
|
24
|
+
|
|
25
|
+
# 构建产物
|
|
26
|
+
dist/
|
|
27
|
+
build/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 索毅 (eastonsuo)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pynanoagent
|
|
3
|
+
Version: 0.1.0.dev0
|
|
4
|
+
Summary: 易于理解、可融入最佳实践、且真正可用的 ReAct 单 agent Python 框架(核心循环 ~30 行)
|
|
5
|
+
Project-URL: Homepage, https://github.com/eastonsuo/nanoagent
|
|
6
|
+
Project-URL: Repository, https://github.com/eastonsuo/nanoagent
|
|
7
|
+
Author: eastonsuo
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: agent,deepseek,llm,openai,react,tool-calling
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Requires-Dist: duckduckgo-search>=6
|
|
13
|
+
Requires-Dist: openai>=1.30
|
|
14
|
+
Requires-Dist: prompt-toolkit>=3
|
|
15
|
+
Requires-Dist: rich>=13
|
|
16
|
+
Requires-Dist: tiktoken>=0.7
|
|
17
|
+
Provides-Extra: anthropic
|
|
18
|
+
Requires-Dist: anthropic>=0.30; extra == 'anthropic'
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: import-linter>=2; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest-cov>=4; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
23
|
+
Provides-Extra: trace
|
|
24
|
+
Requires-Dist: opentelemetry-sdk>=1.20; extra == 'trace'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# nanoagent
|
|
28
|
+
|
|
29
|
+
> 一个核心循环只有约 30 行、却能通过分阶段引入 harness 工程实践演进为真实可用运行时的 **ReAct 单 agent 框架**。既把 agent 的内部机制讲清楚,也让人能基于它构建自己的 agent 应用。
|
|
30
|
+
|
|
31
|
+
> **状态:v0.1 基础版已实现**。核心循环 / 工具系统 / LLM 客户端(OpenAI 兼容,含 DeepSeek)/ in-memory memory / 默认策略 / 命令行入口均已落地,`python -m pytest` 61 passed(全程不联网)。**当前可从源码安装运行**(见[快速开始](#快速开始));PyPI 发布在即,届时 `pip install pynanoagent`(发布名加 `py` 前缀,导入仍 `import nanoagent`)。设计见 [`docs/DESIGN.md`](docs/DESIGN.md)。
|
|
32
|
+
|
|
33
|
+
## 这是什么
|
|
34
|
+
|
|
35
|
+
2026 年的 agent 框架生态有一个结构性空白:**编排类框架**(LangGraph / CrewAI)能让 agent 跑起来,但 context 管理、权限、可观测性往往是后补的,复杂且边界不清;**产品级 agent**(Claude Code / Cursor)harness 成熟却闭源、绑定模型、不可复用。「能让人读懂每一层为什么这样设计、同时又真正可用」的开源框架几乎是空白。
|
|
36
|
+
|
|
37
|
+
nanoagent 要填的就是这个空白,三个关键词缺一不可:
|
|
38
|
+
|
|
39
|
+
- **易于理解**:核心层代码量小、抽象少,能在一两小时读完 `core/loop.py` 并真正理解每一轮在做什么。
|
|
40
|
+
- **融入最佳实践**:context engineering、权限校验、熔断、memory 分层、skill 系统等社区已验证的工程实践,分阶段、有解释地引入。
|
|
41
|
+
- **真正可用**:不停在 toy 阶段——目标是 v0.4 能支撑长任务而不崩溃。
|
|
42
|
+
|
|
43
|
+
## 核心设计原则:Stable Core + Pluggable Strategy
|
|
44
|
+
|
|
45
|
+
整个项目押在一个切分上:把框架切成**核心层**(过去五年没本质变化、未来数年大概率也不变的部分——LLM 调用、循环、工具调度、数据结构)与**策略层**(随最佳实践演化的部分——怎么管上下文、怎么校验权限、怎么熔断)。核心层一旦定稿就不再改动;引入新最佳实践 = 在策略层新增一个实现,核心层不动。
|
|
46
|
+
|
|
47
|
+
下图回答:「nanoagent 由哪几层组成、运行时怎样互相调用?」
|
|
48
|
+
|
|
49
|
+
```mermaid
|
|
50
|
+
flowchart TD
|
|
51
|
+
user["使用者前端<br/>CLI / bot / 编辑器插件"]
|
|
52
|
+
api["顶层 API<br/>Agent / ChatSession"]
|
|
53
|
+
|
|
54
|
+
subgraph core["核心层 · 数年不变"]
|
|
55
|
+
loop["AgentLoop<br/>~30 行 ReAct 循环"]
|
|
56
|
+
data["数据结构 + 契约<br/>Message / Context / Protocol"]
|
|
57
|
+
hooks["Hook 机制<br/>8 个生命周期点"]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
subgraph ext["可替换扩展点"]
|
|
61
|
+
caps["能力实现<br/>LLM / 工具 / Memory"]
|
|
62
|
+
strat["策略层<br/>上下文 / 权限 / 停止"]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
user -->|"调用"| api
|
|
66
|
+
api -->|"组装并运行"| loop
|
|
67
|
+
loop -->|"读写"| data
|
|
68
|
+
loop -->|"直接调用"| caps
|
|
69
|
+
loop -->|"生命周期回调"| hooks
|
|
70
|
+
hooks -.->|"被策略实现并注入"| strat
|
|
71
|
+
|
|
72
|
+
classDef stable fill:#fff0aa
|
|
73
|
+
class loop,data,hooks stable
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**读图要点**:暖黄三块是核心层,数年内不动。注意两种依赖方向的不对称——`AgentLoop` **直接调用**能力实现(LLM / 工具 / Memory 是循环跑起来的必需品,实线),却只**经 Hook 间接触达**策略层(虚线:策略实现某个 Hook 协议、被注入循环的某个生命周期点)。判据很简单:拿掉能力实现层循环就跑不起来,拿掉策略层循环仍能跑(退化成纯 ReAct)。核心层因此既不知道什么是 compaction、也不知道什么是 permission,它只知道「在某个时间点回调一组 hook」——这就是「核心稳定、策略可插拔」能成立的物理机制。
|
|
77
|
+
|
|
78
|
+
## 路线图
|
|
79
|
+
|
|
80
|
+
| 版本 | 范围 | 状态 |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| **v0.1 · Core** | 单 agent + 工具系统 + in-memory memory + 命令行 demo | ✅ 基础版完成(可源码运行,61 单测通过) |
|
|
83
|
+
| v0.2 · Skills + Trace + MCP | Skill 渐进式加载 + OpenTelemetry trace + 文件系统 memory + MCP 工具适配器 | 📋 计划 |
|
|
84
|
+
| v0.3 · Harness | 上下文管理多策略 + 权限系统 + 熔断器 + subagent | 📋 计划 |
|
|
85
|
+
| v0.4 · Eval | 三维度评估框架(独立 repo) | 📋 计划 |
|
|
86
|
+
|
|
87
|
+
## 快速开始
|
|
88
|
+
|
|
89
|
+
当前从源码安装(PyPI 发布后可直接 `pip install pynanoagent`,导入名仍 `nanoagent`):
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
git clone https://github.com/eastonsuo/nanoagent && cd nanoagent
|
|
93
|
+
pip install -e .
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**命令行对话**(需一个 OpenAI 兼容的 key):
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
export OPENAI_API_KEY=sk-... # OpenAI
|
|
100
|
+
nanoagent
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
换 **DeepSeek** 等兼容端点:模型名带前缀即自动识别端点,只需给对应 key(无需手设 base_url):
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
export DEEPSEEK_API_KEY=sk-... # DeepSeek(没有则回落 OPENAI_API_KEY)
|
|
107
|
+
export NANOAGENT_MODEL=deepseek-chat
|
|
108
|
+
nanoagent
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**当库用** —— `@tool` 注册工具,一次性任务用 `Agent.run`、多轮对话用 `Agent(...).session()`:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from nanoagent import Agent, tool
|
|
115
|
+
|
|
116
|
+
@tool
|
|
117
|
+
def word_count(path: str) -> int:
|
|
118
|
+
"""统计文本文件的单词数。"""
|
|
119
|
+
return len(open(path).read().split())
|
|
120
|
+
|
|
121
|
+
agent = Agent("gpt-4o-mini", tools=[word_count])
|
|
122
|
+
print(agent.run("统计 README.md 有多少单词").output) # 一次性,跨 run 无记忆
|
|
123
|
+
|
|
124
|
+
chat = agent.session() # 多轮,记得上文
|
|
125
|
+
chat.send("我叫小明")
|
|
126
|
+
print(chat.send("我叫什么?").output)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## v0.1 已实现
|
|
130
|
+
|
|
131
|
+
| 层 | 模块 | 内容 |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| 核心层 · 数年不变 | `core/` | 数据结构 + 能力/策略契约 + 8 点 Hook + `AgentLoop`(~30 行 ReAct 循环)|
|
|
134
|
+
| 能力实现 | `tools/` `llm/` `memory/` | `@tool` + schema 自动生成;OpenAI 兼容客户端(+ 测试用 echo);in-memory memory |
|
|
135
|
+
| 策略层 · 可插拔 | `strategies/` | 默认 noop / allow-all / max-turns + 把策略包成 Hook |
|
|
136
|
+
| 入口装配 | `api.py` `cli/` | `Agent` / `ChatSession` + 命令行 REPL |
|
|
137
|
+
|
|
138
|
+
- **可读性**:核心层(非 `__init__`)约 390 行,< 500。
|
|
139
|
+
- **测试**:`python -m pytest` → 61 passed,全程不联网、不需 API key(echo 客户端驱动全链路)。
|
|
140
|
+
- **依赖防线**:`core/` 不 import 任何外层目录——「稳定核心」原则的物理保证(设计 §8.1)。
|
|
141
|
+
- **OpenAI 兼容**:OpenAI / DeepSeek / Kimi / vLLM / Ollama,换模型名或端点即可。
|
|
142
|
+
|
|
143
|
+
## 文档
|
|
144
|
+
|
|
145
|
+
- [`docs/DESIGN.md`](docs/DESIGN.md) —— 权威设计文档(14 章):概念与设计哲学、core/harness 解耦、核心数据结构与接口契约、整体架构、v0.1 详细设计、技术选型、与现有框架对比、风险。**实现细节一律以它为准。**
|
|
146
|
+
|
|
147
|
+
## 许可证
|
|
148
|
+
|
|
149
|
+
本项目采用 [MIT License](LICENSE)。
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# nanoagent
|
|
2
|
+
|
|
3
|
+
> 一个核心循环只有约 30 行、却能通过分阶段引入 harness 工程实践演进为真实可用运行时的 **ReAct 单 agent 框架**。既把 agent 的内部机制讲清楚,也让人能基于它构建自己的 agent 应用。
|
|
4
|
+
|
|
5
|
+
> **状态:v0.1 基础版已实现**。核心循环 / 工具系统 / LLM 客户端(OpenAI 兼容,含 DeepSeek)/ in-memory memory / 默认策略 / 命令行入口均已落地,`python -m pytest` 61 passed(全程不联网)。**当前可从源码安装运行**(见[快速开始](#快速开始));PyPI 发布在即,届时 `pip install pynanoagent`(发布名加 `py` 前缀,导入仍 `import nanoagent`)。设计见 [`docs/DESIGN.md`](docs/DESIGN.md)。
|
|
6
|
+
|
|
7
|
+
## 这是什么
|
|
8
|
+
|
|
9
|
+
2026 年的 agent 框架生态有一个结构性空白:**编排类框架**(LangGraph / CrewAI)能让 agent 跑起来,但 context 管理、权限、可观测性往往是后补的,复杂且边界不清;**产品级 agent**(Claude Code / Cursor)harness 成熟却闭源、绑定模型、不可复用。「能让人读懂每一层为什么这样设计、同时又真正可用」的开源框架几乎是空白。
|
|
10
|
+
|
|
11
|
+
nanoagent 要填的就是这个空白,三个关键词缺一不可:
|
|
12
|
+
|
|
13
|
+
- **易于理解**:核心层代码量小、抽象少,能在一两小时读完 `core/loop.py` 并真正理解每一轮在做什么。
|
|
14
|
+
- **融入最佳实践**:context engineering、权限校验、熔断、memory 分层、skill 系统等社区已验证的工程实践,分阶段、有解释地引入。
|
|
15
|
+
- **真正可用**:不停在 toy 阶段——目标是 v0.4 能支撑长任务而不崩溃。
|
|
16
|
+
|
|
17
|
+
## 核心设计原则:Stable Core + Pluggable Strategy
|
|
18
|
+
|
|
19
|
+
整个项目押在一个切分上:把框架切成**核心层**(过去五年没本质变化、未来数年大概率也不变的部分——LLM 调用、循环、工具调度、数据结构)与**策略层**(随最佳实践演化的部分——怎么管上下文、怎么校验权限、怎么熔断)。核心层一旦定稿就不再改动;引入新最佳实践 = 在策略层新增一个实现,核心层不动。
|
|
20
|
+
|
|
21
|
+
下图回答:「nanoagent 由哪几层组成、运行时怎样互相调用?」
|
|
22
|
+
|
|
23
|
+
```mermaid
|
|
24
|
+
flowchart TD
|
|
25
|
+
user["使用者前端<br/>CLI / bot / 编辑器插件"]
|
|
26
|
+
api["顶层 API<br/>Agent / ChatSession"]
|
|
27
|
+
|
|
28
|
+
subgraph core["核心层 · 数年不变"]
|
|
29
|
+
loop["AgentLoop<br/>~30 行 ReAct 循环"]
|
|
30
|
+
data["数据结构 + 契约<br/>Message / Context / Protocol"]
|
|
31
|
+
hooks["Hook 机制<br/>8 个生命周期点"]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
subgraph ext["可替换扩展点"]
|
|
35
|
+
caps["能力实现<br/>LLM / 工具 / Memory"]
|
|
36
|
+
strat["策略层<br/>上下文 / 权限 / 停止"]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
user -->|"调用"| api
|
|
40
|
+
api -->|"组装并运行"| loop
|
|
41
|
+
loop -->|"读写"| data
|
|
42
|
+
loop -->|"直接调用"| caps
|
|
43
|
+
loop -->|"生命周期回调"| hooks
|
|
44
|
+
hooks -.->|"被策略实现并注入"| strat
|
|
45
|
+
|
|
46
|
+
classDef stable fill:#fff0aa
|
|
47
|
+
class loop,data,hooks stable
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**读图要点**:暖黄三块是核心层,数年内不动。注意两种依赖方向的不对称——`AgentLoop` **直接调用**能力实现(LLM / 工具 / Memory 是循环跑起来的必需品,实线),却只**经 Hook 间接触达**策略层(虚线:策略实现某个 Hook 协议、被注入循环的某个生命周期点)。判据很简单:拿掉能力实现层循环就跑不起来,拿掉策略层循环仍能跑(退化成纯 ReAct)。核心层因此既不知道什么是 compaction、也不知道什么是 permission,它只知道「在某个时间点回调一组 hook」——这就是「核心稳定、策略可插拔」能成立的物理机制。
|
|
51
|
+
|
|
52
|
+
## 路线图
|
|
53
|
+
|
|
54
|
+
| 版本 | 范围 | 状态 |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| **v0.1 · Core** | 单 agent + 工具系统 + in-memory memory + 命令行 demo | ✅ 基础版完成(可源码运行,61 单测通过) |
|
|
57
|
+
| v0.2 · Skills + Trace + MCP | Skill 渐进式加载 + OpenTelemetry trace + 文件系统 memory + MCP 工具适配器 | 📋 计划 |
|
|
58
|
+
| v0.3 · Harness | 上下文管理多策略 + 权限系统 + 熔断器 + subagent | 📋 计划 |
|
|
59
|
+
| v0.4 · Eval | 三维度评估框架(独立 repo) | 📋 计划 |
|
|
60
|
+
|
|
61
|
+
## 快速开始
|
|
62
|
+
|
|
63
|
+
当前从源码安装(PyPI 发布后可直接 `pip install pynanoagent`,导入名仍 `nanoagent`):
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/eastonsuo/nanoagent && cd nanoagent
|
|
67
|
+
pip install -e .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**命令行对话**(需一个 OpenAI 兼容的 key):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
export OPENAI_API_KEY=sk-... # OpenAI
|
|
74
|
+
nanoagent
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
换 **DeepSeek** 等兼容端点:模型名带前缀即自动识别端点,只需给对应 key(无需手设 base_url):
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
export DEEPSEEK_API_KEY=sk-... # DeepSeek(没有则回落 OPENAI_API_KEY)
|
|
81
|
+
export NANOAGENT_MODEL=deepseek-chat
|
|
82
|
+
nanoagent
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**当库用** —— `@tool` 注册工具,一次性任务用 `Agent.run`、多轮对话用 `Agent(...).session()`:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from nanoagent import Agent, tool
|
|
89
|
+
|
|
90
|
+
@tool
|
|
91
|
+
def word_count(path: str) -> int:
|
|
92
|
+
"""统计文本文件的单词数。"""
|
|
93
|
+
return len(open(path).read().split())
|
|
94
|
+
|
|
95
|
+
agent = Agent("gpt-4o-mini", tools=[word_count])
|
|
96
|
+
print(agent.run("统计 README.md 有多少单词").output) # 一次性,跨 run 无记忆
|
|
97
|
+
|
|
98
|
+
chat = agent.session() # 多轮,记得上文
|
|
99
|
+
chat.send("我叫小明")
|
|
100
|
+
print(chat.send("我叫什么?").output)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## v0.1 已实现
|
|
104
|
+
|
|
105
|
+
| 层 | 模块 | 内容 |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| 核心层 · 数年不变 | `core/` | 数据结构 + 能力/策略契约 + 8 点 Hook + `AgentLoop`(~30 行 ReAct 循环)|
|
|
108
|
+
| 能力实现 | `tools/` `llm/` `memory/` | `@tool` + schema 自动生成;OpenAI 兼容客户端(+ 测试用 echo);in-memory memory |
|
|
109
|
+
| 策略层 · 可插拔 | `strategies/` | 默认 noop / allow-all / max-turns + 把策略包成 Hook |
|
|
110
|
+
| 入口装配 | `api.py` `cli/` | `Agent` / `ChatSession` + 命令行 REPL |
|
|
111
|
+
|
|
112
|
+
- **可读性**:核心层(非 `__init__`)约 390 行,< 500。
|
|
113
|
+
- **测试**:`python -m pytest` → 61 passed,全程不联网、不需 API key(echo 客户端驱动全链路)。
|
|
114
|
+
- **依赖防线**:`core/` 不 import 任何外层目录——「稳定核心」原则的物理保证(设计 §8.1)。
|
|
115
|
+
- **OpenAI 兼容**:OpenAI / DeepSeek / Kimi / vLLM / Ollama,换模型名或端点即可。
|
|
116
|
+
|
|
117
|
+
## 文档
|
|
118
|
+
|
|
119
|
+
- [`docs/DESIGN.md`](docs/DESIGN.md) —— 权威设计文档(14 章):概念与设计哲学、core/harness 解耦、核心数据结构与接口契约、整体架构、v0.1 详细设计、技术选型、与现有框架对比、风险。**实现细节一律以它为准。**
|
|
120
|
+
|
|
121
|
+
## 许可证
|
|
122
|
+
|
|
123
|
+
本项目采用 [MIT License](LICENSE)。
|