Skip to content

TingdeLiu/miniagent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MiniAgent

一个最小可运行的 AI Agent 框架,面向初学者的学习项目。 用 ~500 行 Python 代码,拆解清楚一个 Agent 到底是怎么跑起来的。

Python LLM License


为什么做这个项目?

市面上的 Agent 框架(LangChain、LlamaIndex、AutoGen…)功能强大但抽象层太厚,初学者很难一眼看清**"一个 Agent 本质上是什么"**。

MiniAgent 的目标:不造轮子、不搞魔法,用最直白的代码把 Agent 的 5 个核心概念讲明白:

核心概念 对应文件 一句话解释
Tool(工具) tools/ Agent 能"动手做"的外部能力(计算、搜索、读写文件…)
Memory(记忆) agent/memory.py 保存对话历史,让 Agent 有"上下文"
Planner(规划) agent/planner.py 把复杂目标拆成有序子任务
Executor(执行) agent/executor.py 把 LLM 输出的 tool_calls 派发给真正的函数
Loop(主循环) agent/loop.py ReAct 循环:Reason → Act → Observe

读完并亲手改一遍这 5 个文件,你就理解了 Agent 的本质。


能做什么?

跑起来后可以和它这样对话:

You> 帮我计算 (12+8)*3 然后写入 result.txt

[Step 1] 调用 LLM...
[Act] 调用工具 calculator({"expression":"(12+8)*3"})
[Observe] 60
[Step 2] 调用 LLM...
[Act] 调用工具 file_io({"action":"write","filename":"result.txt","content":"60"})
[Observe] 已写入 result.txt(2 字符)
[Step 3] 调用 LLM...
[Answer] 已将 (12+8)*3 的结果 60 写入 result.txt。

内置 3 个示例工具:

  • calculator — 安全的数学计算(基于 Python AST,拒绝任意代码执行)
  • search — DuckDuckGo 网页搜索
  • file_io — 本地文件读写 / 追加 / 删除 / 建文件夹 / 移动(带路径穿越防护)

架构一览

┌─────────────────────────────────────────────────────────┐
│                      main.py                            │
│              (入口:交互模式 / 单次任务)                │
└──────────────┬──────────────────────────────────────────┘
               │
     ┌─────────▼──────────┐         ┌───────────────────┐
     │   Planner (可选)    │  拆解   │   goal → steps    │
     │   planner.py       │────────▶│                   │
     └─────────┬──────────┘         └───────────────────┘
               │
     ┌─────────▼───────────────────────────────────────┐
     │             Agent Loop (loop.py)                │
     │                                                  │
     │   ┌──────────┐   ┌──────────┐   ┌───────────┐   │
     │   │  Reason  │──▶│   Act    │──▶│  Observe  │   │
     │   │  (LLM)   │   │(Executor)│   │  (result) │   │
     │   └──────────┘   └────┬─────┘   └─────┬─────┘   │
     │        ▲              │               │          │
     │        └──────────────┴───────────────┘          │
     │                     循环至完成                    │
     └──────────────────┬─────────────┬────────────────┘
                        │             │
               ┌────────▼────┐  ┌─────▼──────┐
               │   Memory    │  │    Tools   │
               │ (messages)  │  │  registry  │
               └─────────────┘  └────────────┘

目录结构

miniagent/
├── main.py                 # 入口:CLI 交互模式
├── config.py               # 配置:LLM 客户端、模型、环境变量
├── agent/
│   ├── loop.py             # ReAct 主循环
│   ├── planner.py          # 任务拆解(可选)
│   ├── executor.py         # 工具调度
│   └── memory.py           # 对话历史 + JSON 持久化
├── tools/
│   ├── registry.py         # 工具注册表
│   ├── calculator.py       # 示例工具:安全计算
│   ├── search.py           # 示例工具:DuckDuckGo
│   └── file_io.py          # 示例工具:文件操作
├── requirements.txt
├── .env.example            # 环境变量模板
├── PLAN.md                 # 原始设计文档
└── README.md               # 本文件

快速开始

1. 环境准备

需要 Python 3.11+ 和一个 OpenAI 兼容的 LLM 服务。有两种选择,任选其一即可:

方式 A:直接调用云端 API(零部署,推荐新手)

不想折腾本地模型?直接用云端 API 最快。本项目兼容任何 OpenAI 格式的服务,常见选项:

服务商 LLM_REMOTE_URL 获取 API Key
OpenAI https://api.openai.com/v1 https://platform.openai.com/api-keys
DeepSeek https://api.deepseek.com/v1 https://platform.deepseek.com/api_keys
阿里百炼(通义千问) https://dashscope.aliyuncs.com/compatible-mode/v1 https://bailian.console.aliyun.com/
月之暗面(Kimi) https://api.moonshot.cn/v1 https://platform.moonshot.cn/console/api-keys
智谱(GLM) https://open.bigmodel.cn/api/paas/v4/ https://open.bigmodel.cn/usercenter/apikeys
硅基流动 https://api.siliconflow.cn/v1 https://cloud.siliconflow.cn/account/ak

申请到 key 后,跳到 步骤 3 按"云端 API 配置"填写 .env 即可。

方式 B:本地部署 Ollama(离线、免费、隐私好)

想完全跑在自己机器上?用 Ollama 一条命令拉模型:

# 1. 安装 Ollama(按官网指引:https://ollama.com/download)
# 2. 拉取 Qwen3 模型(8B 约 5GB,需要 ≥16GB 内存;低配机器可换 qwen3:4b / qwen3:1.7b)
ollama pull qwen3:8b

# 3. 启动 Ollama(默认监听 http://localhost:11434)
ollama serve

💡 小参数模型(≤7B)的 function calling 能力较弱,可能会忽略工具"硬答"。 如果发现 Agent 不调工具,优先换更大的模型或走方式 A。

2. 克隆并安装依赖

git clone https://github.com/<your-username>/miniagent.git
cd miniagent

# 创建虚拟环境(推荐)
python -m venv .venv
# Windows:  .venv\Scripts\activate
# Linux/Mac: source .venv/bin/activate

pip install -r requirements.txt

3. 配置环境变量

# Linux / macOS / Git Bash
cp .env.example .env

# Windows cmd / PowerShell
copy .env.example .env

然后按下方两种方式之一编辑 .env

方式 A:云端 API(以 DeepSeek 为例,其他服务商同理)

LLM_MODE=remote
LLM_REMOTE_URL=https://api.deepseek.com/v1
LLM_API_KEY=sk-你的真实key
LLM_MODEL=deepseek-chat

方式 B:本机 Ollama

LLM_MODE=local
LLM_LOCAL_URL=http://localhost:11434/v1
LLM_API_KEY=ollama
LLM_MODEL=qwen3:8b

4. 运行

# 交互模式
python main.py

# 单次任务(执行完进入交互模式)
python main.py "帮我计算 (12+8)*3 然后写入 result.txt"

交互模式中可用命令:

命令 作用
exit 退出
clear 清空对话历史

配置项(.env)

变量 默认值 说明
LLM_MODE local local(本机 Ollama)或 remote(远程服务器)
LLM_LOCAL_URL http://localhost:11434/v1 本地 Ollama 地址
LLM_REMOTE_URL 远程 LLM 服务地址(LLM_MODE=remote 时生效)
LLM_MODEL qwen3:8b 模型名称
LLM_API_KEY ollama Ollama 不校验,占位即可;远程加了鉴权则填真实 key
MAX_STEPS 10 ReAct 最大轮数(防死循环),必须是正整数
MEMORY_PATH memory.json 对话历史持久化路径,留空则不持久化
USE_PLANNER false 是否启用 Planner 预先拆解任务
FILE_BASE_DIR 项目根目录 file_io 工具允许操作的根目录(防路径穿越)
LLM_THINK_MODE auto Qwen Thinking Mode 开关:auto(按模型名判断)/on/off。非 Qwen 模型务必保持 autoon

核心概念解释

ReAct 循环是什么?

ReAct = Reasoning + Acting。一个 Agent 每一轮都在做三件事:

  1. Reason — LLM 读取对话上下文,决定"下一步做什么"
  2. Act — 如果 LLM 决定用工具,就真的调用那个 Python 函数
  3. Observe — 把工具返回结果塞回对话,让 LLM "看到"

循环直到 LLM 说"我说完了"(finish_reason == "stop" 且没有 tool_calls),或达到 MAX_STEPS

工具(Tool)是怎么工作的?

每个工具两部分:

  1. Schema(OpenAI function calling 格式)— 告诉 LLM 这个工具怎么用、参数是什么
  2. Handler(Python 函数)— 真正执行逻辑,接收 dict,返回 str

注册工具只要一行:

register_tool(schema_dict, handler_function)

然后 LLM 就能在对话中自动触发它。

Thinking Mode 与 <think>

Qwen3 默认开启 "Thinking Mode",输出里夹带 <think>...</think> 块(模型的内心独白)。 本项目在两处处理它:

  1. 请求时 extra_body={"think": False} 关闭思考(省 token)
  2. 响应时用正则清洗残留的 <think> 块,避免污染上下文

扩展:写一个自己的工具

比如加一个"当前时间"工具,新建 tools/datetime_tool.py

from datetime import datetime
from tools.registry import register_tool


def _handler(args: dict) -> str:
    fmt = args.get("format", "%Y-%m-%d %H:%M:%S")
    return datetime.now().strftime(fmt)


register_tool(
    {
        "type": "function",
        "function": {
            "name": "current_time",
            "description": "返回当前本地时间",
            "parameters": {
                "type": "object",
                "properties": {
                    "format": {
                        "type": "string",
                        "description": "strftime 格式字符串,默认 %Y-%m-%d %H:%M:%S",
                    }
                },
            },
        },
    },
    _handler,
)

然后在 main.py 顶部加一行:

import tools.datetime_tool  # noqa: F401

重启后 Agent 就能用 current_time 工具了。就这么简单。


常见问题

Q: 我没有 Ollama,可以用 OpenAI / DeepSeek / 其他云端 API 吗?

可以。只要是 OpenAI 兼容接口,改 .env 即可:

LLM_MODE=remote
LLM_REMOTE_URL=https://api.deepseek.com/v1
LLM_API_KEY=sk-你的真实key
LLM_MODEL=deepseek-chat
Q: 为什么我的模型经常忽略工具、自己瞎答?

小参数模型(7B 以下)的 function calling 能力较弱。建议:

  • 用 Qwen3:8b 及以上,或 GPT-4o-mini、DeepSeek-V3 等
  • 加强 main.py 里的 SYSTEM_PROMPT,明确"必须使用工具"
  • 开启 USE_PLANNER=true,用 Planner 先把任务拆清楚
Q: Agent 陷入死循环怎么办?

已有 MAX_STEPS 保护(默认 10 轮)。可以在 .env 里调小。

Q: 对话历史会越来越长,怎么办?

Memorymax_messages=50 的窗口裁剪。需要更精细的裁剪策略(例如按 token 数、保留摘要),可在 agent/memory.py_trim() 中扩展。

Q: file_io 工具操作会不会写坏我的系统?

不会。file_io 通过 FILE_BASE_DIR 限制在项目目录内,绝对路径和 ../ 越界都会被拒绝。


学习路线建议

推荐按这个顺序读代码,由浅入深:

  1. tools/calculator.py — 看懂"一个工具长什么样"
  2. tools/registry.py — 工具怎么被注册和查找
  3. agent/memory.py — 对话历史的数据结构
  4. agent/executor.py — LLM 输出是怎么被映射到 Python 函数的
  5. agent/loop.py核心:ReAct 循环的完整实现
  6. agent/planner.py — 锦上添花的任务拆解
  7. main.py — 把上面所有模块串起来

读完这一圈,你已经掌握了现代 Agent 框架的骨架。之后再看 LangChain / AutoGen 的源码,会发现它们本质上就是在这套骨架上加层、加特性。


里程碑

  • M1 — 单工具 ReAct(计算器能跑)
  • M2 — 多步任务(Planner 拆解)
  • M3 — 多工具(search + file_io)
  • M4 — Memory 持久化(重启恢复上下文)
  • M5 — Web UI(Gradio / Streamlit)
  • M6 — 流式输出
  • M7 — 工具并行执行

欢迎 PR!


依赖

openai>=1.30.0        # OpenAI 兼容 API 客户端
python-dotenv>=1.0.0  # .env 文件加载
ddgs>=0.1             # DuckDuckGo 搜索

许可

MIT License.


致谢

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages