Skip to main content

Lightweight composable multi-agent framework with StateGraph, RAG, Memory, MCP, and structured output

Project description

ClearAgent

轻量、可组合的多智能体框架 —— 基于 OpenAI 原生 API,单包提供图编排、检查点、HITL、RAG、Memory、Multi-agent、MCP、结构化输出、Eval-harness 等能力。

Python 3.10+ PyPI License: CC BY-NC-SA 4.0

✨ 核心能力

编排与执行

  • StateGraph 声明式图构建(节点 / 边 / 条件边 / 字段级 reducer)
  • Checkpointer 自动每节点快照(Memory / JsonFile / Sqlite),kill 进程也能 resume + 时间旅行
  • Human-in-the-Loop interrupt() + resume(value=...) 暂停-续跑,支持同节点多次中断顺序回放
  • Multi-agent 三种范式:supervisor(中心化)/ swarm(去中心化)/ handoff 原语
  • LCEL-lite Runnable + | 管道组合(自研,零 langchain 依赖)

LLM 与工具

  • 多 provider 自动适配:OpenAI 兼容(DeepSeek/Qwen/Kimi/Ollama 等)、Anthropic、Gemini
  • 同步 / 真异步 / 流式 全套接口(AsyncOpenAI / AsyncAnthropic 真异步,不走线程池假异步)
  • 结构化输出 llm.with_structured_output(MyPydanticModel) 一行打通三种 method
  • 工具系统 ToolResponse 协议 + 熔断器 + 权限过滤 + Pydantic 自动 Tool schema 推导
  • 工具并行 run_tools_parallel / arun_tools_parallel 多 tool_calls 并发
  • Resilience Retry / Fallback / 负载均衡装饰器
  • Multimodal vision / audio / file content parts 构造器
  • Prompt caching Anthropic ephemeral helper

数据与记忆

  • 完整 RAG Pipeline 7 大职责(加载 / 分块 / 索引 / 检索 / 重排 / 合并 / 压缩)+ MQE / HyDE 查询扩展
  • 多层 Memory WorkingMemory(短期)+ SemanticMemory(长期 + 内存知识图谱)+ MemoryManager 协调
  • 向量库 QdrantVectorStore + SQLiteDocumentStore
  • 嵌入抽象 Local / DashScope / TFIDF + 工厂回退
  • 文档加载 MarkItDown 50+ 格式(PDF/DOCX/XLSX/图像 OCR/音频转写/HTML/代码/配置)

生态与工程化

  • MCP 协议 Client(吃外部 MCP 工具)+ Server(暴露给 Cursor / Claude Desktop)
  • Skills 系统 知识按需注入,~85% Token 节省
  • 子代理机制 TaskTool 派发隔离子任务,工具权限可精确裁剪
  • Eval-harness Dataset + 4 种 Evaluator(含 LLMAsJudge)+ 并发 Runner + Markdown 报告
  • Callbacks 13 个 hooks(LLM/工具/节点/检索)+ 内置 Logging / Metrics handler
  • TraceLogger JSONL + HTML 双格式 + SFT / DPO 训练数据导出

🚀 快速开始

# 最小安装
pip install clear-agent

# 按需扩展
pip install "clear-agent[retrieval-qdrant,rag]"   # 完整 RAG
pip install "clear-agent[memory]"                  # 多层记忆 + spaCy NER
pip install "clear-agent[anthropic,gemini]"        # 多 provider
pip install "clear-agent[mcp]"                     # MCP 协议

环境变量(参考 .env.example):

LLM_MODEL_ID=gpt-4o
LLM_API_KEY=sk-...
LLM_BASE_URL=https://api.openai.com/v1

1 分钟示例:ReActAgent

from clear_agent import ClearAgentLLM, ReActAgent, ToolRegistry, CalculatorTool

llm = ClearAgentLLM()
registry = ToolRegistry(); registry.register_tool(CalculatorTool())
agent = ReActAgent(name="demo", llm=llm, tool_registry=registry)
print(agent.run("计算 (123 + 456) * 2"))

StateGraph + Checkpoint

from clear_agent import ReActAgent, SqliteCheckpointer
from clear_agent.core.graph import RunConfig

agent = ReActAgent(name="x", llm=ClearAgentLLM())
graph = agent.as_graph(checkpointer=SqliteCheckpointer("memory/runs.db"))

result = graph.invoke(
    {"messages": [{"role": "user", "content": "..."}], "max_steps": 5},
    config=RunConfig(thread_id="thread-1"),
)
# 进程崩了?任意时间:graph.resume("thread-1") 续跑

Human-in-the-Loop

from clear_agent.core.interrupt import interrupt, GraphPaused

def risky_node(state):
    decision = interrupt({"type": "approval", "message": "Send email?", "draft": state["draft"]})
    if not decision.get("approved"):
        return {"messages": [...]}
    ...

try:
    graph.invoke(state, config=RunConfig(thread_id="t1"))
except GraphPaused as p:
    # 把 p.payload 展示给用户,待决策后:
    graph.resume("t1", value={"approved": True})

结构化输出

from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int

structured = llm.with_structured_output(Person)
p = structured.invoke([{"role": "user", "content": "Alice 是 30 岁的老师"}])
print(p.name, p.age)  # Alice 30

完整 RAG

from clear_agent.retrieval.rag import create_rag_pipeline

rag = create_rag_pipeline(qdrant_url="http://localhost:6333", rag_namespace="my_kb")
rag["add_documents"](["docs/a.pdf", "docs/b.md"])
hits = rag["search"]("如何配置 LLM?", top_k=5)
hits = rag["search_advanced"]("...", enable_mqe=True, enable_hyde=True)

Multi-agent supervisor

from clear_agent.multiagent import build_supervisor_graph, HANDOFF_END

def supervisor(state):
    n = state.get("handoff_count", 0)
    return {"active_agent": ["researcher", "writer", HANDOFF_END][n] if n < 3 else HANDOFF_END}

graph = build_supervisor_graph(supervisor, {"researcher": researcher_fn, "writer": writer_fn})
result = graph.invoke({"messages": []})

Pydantic 自动 Tool schema

from pydantic import BaseModel, Field
from clear_agent.tools.from_pydantic import pydantic_tool

class AddArgs(BaseModel):
    a: int = Field(description="第一个数")
    b: int = Field(description="第二个数")

@pydantic_tool(description="加法")
def add(args: AddArgs) -> int:
    return args.a + args.b

registry.register_tool(add)

Resilience

from clear_agent.core.resilience import retry, with_fallbacks

@retry(max_attempts=3, retry_on=(ConnectionError,), backoff=0.5)
def call_api():
    return llm.invoke(...)

safe_llm = with_fallbacks(primary_llm.invoke, [backup_llm_1.invoke, backup_llm_2.invoke])
response = safe_llm(messages)

更多示例见 examples/ 目录。

📦 项目结构

clear_agent/
├── core/             # Agent 基类 / LLM / Config / 编排基础
│   ├── graph.py            # StateGraph + reducers
│   ├── checkpoint.py       # Memory/JsonFile/Sqlite
│   ├── interrupt.py        # interrupt() + GraphPaused
│   ├── structured.py       # with_structured_output
│   ├── runnable.py         # LCEL-lite Runnable + |
│   ├── callbacks.py        # 13 hooks 协议
│   ├── parallel.py         # 工具并行 helper
│   ├── resilience.py       # Retry / Fallback / 负载均衡
│   └── multimodal.py       # vision / audio + cache_control
├── agents/           # 4 种范式(Simple/ReAct/Reflection/PlanSolve)+ graph builders
├── multiagent/       # supervisor / swarm / handoff
├── mcp/              # MCP client / server / adapter
├── hitl/             # Human-in-the-Loop patterns
├── eval/             # Dataset / Evaluator / Runner
├── retrieval/        # 嵌入 + Qdrant + SQLite + RAG pipeline
│   ├── embeddings.py
│   ├── rag/                # document + pipeline (7 大职责)
│   └── storage/            # SQLite + Qdrant
├── memory/           # WorkingMemory + SemanticMemory + Manager
├── context/          # GSSC 流水线
├── tools/            # 工具系统 + Pydantic 自动推导 + 内置工具
├── observability/    # TraceLogger(JSONL + HTML + SFT/DPO 导出)
└── skills/           # SkillLoader

skills/               # 18 个内置 Skill 包(pdf/docx/xlsx/ASR/TTS/VLM/web-search…)
docs/                 # 用户指南
examples/             # 演示
tests/                # 740+ pytest 测试

📚 文档

🛠️ 本地开发与调试

1. 克隆与环境

git clone https://github.com/Perlou/clear-agent.git
cd clear-agent

python3.10 -m venv .venv && source .venv/bin/activate     # 推荐 3.10/3.11/3.12
pip install --upgrade pip

装依赖三选一:

# A. 一键装齐(runtime + 轻量 extras + 全 dev/test 工具)—— 贡献者推荐
pip install -r requirements.txt
pip install -e .                       # editable 安装本包

# B. editable + 自选 extras(更精细)
pip install -e ".[mcp,retrieval-qdrant,memory,anthropic,gemini,dev]"

# C. 仅装最小核心(不跑测试 / 不写 RAG)
pip install -e .
# RAG(拉 sentence-transformers + torch ~2GB,按需)
pip install "clear-agent[rag]"

# 配置 .env
cp .env.example .env  # 填 LLM_MODEL_ID / LLM_API_KEY / LLM_BASE_URL

📌 pip install -e . 后任何位置都能 from clear_agent import ...,且改 clear_agent/ 源码即时生效,无需重装。 📌 requirements.txt 是给贡献者一键装齐的;终端用户 pip install clear-agent 走 PyPI 不需要它。

2. 在 examples/ 里调试新 demo

examples/ 下的脚本(如 examples/trip-planner/)默认就用本仓库的源码:

# 单文件 demo
python examples/async_agent_demo.py

# 子项目 demo(trip-planner 等需要后端 / 前端)
cd examples/trip-planner/backend
pip install fastapi 'uvicorn[standard]' pydantic-settings python-dotenv uv
python run.py

如果想验证「外部用户 pip install clear-agent 后是否能跑」,把整个子目录复制出去用 requirements.txt 重装即可(trip-planner 已带)。

3. 测试

pytest                                # 全量
pytest tests/test_graph_basics.py -v  # 单文件
pytest -k structured -v               # 关键字过滤
pytest -m "not integration" -q        # 跳过需真 API 的集成测试

首次跑测试常见坑:

现象 原因 解决
Using SOCKS proxy, but socksio not installed 系统设了 all_proxy=socks5://... 已包含在 requirements.txthttpx[socks];或 unset all_proxy http_proxy https_proxy
async def functions are not natively supported 缺 pytest-asyncio 已包含在 requirements.txt
真实 LLM 测试 401 / 超时 .env 没配 / endpoint 不通 pytest -m "not integration" 跑单测,再单独修
*_when_*_missing 这类反向测试失败 装了对应可选依赖 这是测试桩问题,不影响实际功能

4. 代码风格 / 类型检查

black clear_agent tests && isort clear_agent tests   # 格式化
mypy clear_agent                                      # 严格类型

提交前可选挂 pre-commit:pip install pre-commit && pre-commit install

5. 调试技巧

最小复现环境变量:

export PYTHONBREAKPOINT=ipdb.set_trace      # 让 breakpoint() 进 ipdb
export CLEAR_AGENT_LOG_LEVEL=DEBUG          # 打开 framework 内部日志
pytest tests/test_xxx.py::test_yyy -v -s    # -s 不吞 print/输入

只跑挂掉的那一个:

pytest --lf -x                              # last-failed + 第一个失败就停
pytest tests/test_xxx.py -k "name and not slow" --pdb   # 失败处自动进 pdb

调试 LLM 真实调用 + 工具循环:

import logging; logging.basicConfig(level=logging.DEBUG)
from clear_agent.observability.trace_logger import TraceLogger
TraceLogger().enable()                      # 每一步落 JSONL + HTML 时间线

追踪 MCP 子进程:MCPClient.connect_stdio(...)env={"DEBUG": "1", ...},子进程的 stderr 会原样透出到父进程。

📦 发布到 PyPI

scripts/release.sh 是一键发布脚本,按 11 个 Phase 顺序执行;任何一个 Phase 失败都会停下并给出可恢复的提示。

脚本流程

Phase 做什么 失败后怎么办
0 工具与环境检查 校验 python / build / twine / git 装缺失工具
1 Git 工作区检查 确认 working tree 干净 git stashgit commit
2 版本号 校验 pyproject.toml 版号未在 PyPI 占用 --bump patch--version X.Y.Z
3 必备文件 检查 README / LICENSE / MANIFEST / py.typed 补齐对应文件
4 全量 pytest 跑所有测试(可 --skip-tests 修代码或确认是环境问题再 --skip-tests
5 清理 + 构建 rm -rf dist build + python -m build 看 build 日志
6 twine check twine check dist/* 检查长描述/元数据 pyproject.toml
7 包内容审查 列 wheel/sdist 内容确认没漏 / 没多 MANIFEST.in[tool.setuptools]
8 干净环境装机验证 临时 venv 装 wheel + 冒烟 import --skip-clean-install 跳过
9 上传 twine upload(pypi / testpypi) 看凭证 / 网络
10 Git tag git tag vX.Y.Z + 可选 git push --tags --skip-tag 跳过

常用姿势

# 1) 干跑:只构建 + 校验,不上传(强烈建议每次发版前先跑一遍)
bash scripts/release.sh --dry-run

# 2) 先发 TestPyPI 验证(推荐流程)
bash scripts/release.sh --test

# 3) 正式发到 PyPI
bash scripts/release.sh                # 交互式
bash scripts/release.sh --yes          # CI 用,全部自动 yes

# 4) 自动 bump 版本号
bash scripts/release.sh --bump patch          # 2.0.0 → 2.0.1
bash scripts/release.sh --bump minor          # 2.0.0 → 2.1.0
bash scripts/release.sh --version 2.0.0rc1    # 显式指定

# 5) 紧急发版组合(不推荐)
bash scripts/release.sh --skip-tests          # 跳测试(环境问题暂时绕过)
bash scripts/release.sh --skip-clean-install  # 跳干净环境验证(提速)
bash scripts/release.sh --skip-tag            # 不打 git tag

完整参数详见 scripts/release.sh 头部注释;端到端 SOP 与版本策略见 docs/pypi-release.md

退出码

0 成功 | 1 通用失败 | 2 参数错误 | 3 环境/工具缺失 | 4 版本检查失败 | 5 测试失败 | 6 构建失败 | 7 上传失败

凭证配置(任选其一)

# 方式 A:环境变量(CI 推荐)
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-AgEIcHlwaS5vcmc...

# 方式 B:~/.pypirc(本地推荐)
cat > ~/.pypirc <<EOF
[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmc...

[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-...
EOF
chmod 600 ~/.pypirc

发版前自查清单

  • pyproject.tomlclear_agent/version.py 版本号一致
  • CHANGELOG / commit history 已整理
  • pytest 全绿(环境问题除外,见上文表格)
  • PyPI 上目标版本号未被占用(脚本会自动检查)
  • 本地 --dry-run 通过
  • 先打 TestPyPI 验证 pip install -i https://test.pypi.org/simple/ clear-agent==X.Y.Z

📄 License

CC BY-NC-SA 4.0 —— 允许学习/研究/分享,禁止商业使用。商用请联系作者 perloukevin@gmail.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clear_agent-2.0.0.tar.gz (4.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clear_agent-2.0.0-py3-none-any.whl (257.4 kB view details)

Uploaded Python 3

File details

Details for the file clear_agent-2.0.0.tar.gz.

File metadata

  • Download URL: clear_agent-2.0.0.tar.gz
  • Upload date:
  • Size: 4.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for clear_agent-2.0.0.tar.gz
Algorithm Hash digest
SHA256 6ea2b2fac2e32d533ddd2cb2bd4f175b41f77f4bc3b4b68e19b0b2c6525eb2ed
MD5 f8dde965fec073e4dc8eaed302319931
BLAKE2b-256 9b932f5cedcc367a08afe4f2bd238fd940af495901f2a561f75dedf194b3dbe6

See more details on using hashes here.

File details

Details for the file clear_agent-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: clear_agent-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 257.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for clear_agent-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4a57b2d89f7c923780da208d7c71e4d8c242c6d4c2ea9e7f5893128597ed9518
MD5 7aae5afdc89ef2a634739f16b2e860ad
BLAKE2b-256 8cafe5ce2bd2e754e7ffd43af4d02ce4ab5a447882de878c38524017f9c97b99

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page