支持永久记忆、持续学习、探索性解决复杂问题的Agent框架。
|
|
2 órája | |
|---|---|---|
| .claude | 4 napja | |
| agent | 2 órája | |
| config | 2 hete | |
| docs | 3 napja | |
| examples | 2 órája | |
| frontend | 3 órája | |
| gateway | 3 napja | |
| knowhub | 3 órája | |
| vendor | 4 hete | |
| .gitignore | 3 napja | |
| .gitmodules | 1 hónapja | |
| README.md | 3 órája | |
| api_server.py | 2 órája | |
| gateway_server.py | 4 napja | |
| requirements.txt | 4 napja | |
| test_vector_search.py | 3 órája |
可扩展的 Agent 框架。支持多步工具调用、计划管理、子 Agent 协作、回溯重跑和上下文压缩。
pip install -r requirements.txt
# 配置 LLM API Key
cp .env.example .env # 编辑填入 API Key
import asyncio
from agent import AgentRunner, RunConfig
from agent.trace import FileSystemTraceStore
from agent.llm import create_openrouter_llm_call
runner = AgentRunner(
trace_store=FileSystemTraceStore(base_path=".trace"),
llm_call=create_openrouter_llm_call(model="anthropic/claude-sonnet-4.5"),
)
async def main():
async for item in runner.run(
messages=[{"role": "user", "content": "列出当前目录的文件"}],
config=RunConfig(model="anthropic/claude-sonnet-4.5"),
):
print(item)
asyncio.run(main())
用 @tool 装饰器注册。RunConfig(tools=None)(默认)时所有已注册工具自动对 LLM 可用,无需额外配置。
from agent import tool, ToolResult
@tool(description="查询产品库存")
async def check_inventory(product_id: str, warehouse: str = "default") -> ToolResult:
"""查询指定仓库的产品库存
Args:
product_id: 产品唯一标识符
warehouse: 仓库编码,默认为主仓库
"""
stock = await query_db(product_id, warehouse)
return ToolResult(output=f"库存: {stock}")
# 确保此模块在 runner.run() 之前被 import
注意: @tool 通过副作用注册到全局 registry,必须确保定义工具的模块在调用 runner.run() 前被 import。
框架从函数签名和 docstring 自动生成 OpenAI Tool Schema,无需手写 JSON:
str/int/float/bool/list/dict,支持 Optional、Literal、List[T])Args: 段提取@tool(description=...) 参数,其次取 docstring 首行uid 和 context 参数由框架自动注入,不会出现在 Schema 中上面的 check_inventory 会生成:
{
"type": "function",
"function": {
"name": "check_inventory",
"description": "查询产品库存",
"parameters": {
"type": "object",
"properties": {
"product_id": {"type": "string", "description": "产品唯一标识符"},
"warehouse": {"type": "string", "description": "仓库编码,默认为主仓库", "default": "default"}
},
"required": ["product_id"]
}
}
}
# 只启用指定工具(在内置工具基础上追加)
config = RunConfig(tools=["check_inventory", "another_tool"])
Skills 是 Markdown 文件,提供领域知识,注入到 system prompt。
my_project/
└── skills/
└── my_domain.md
---
name: my-domain-skill
description: 领域专属知识
---
## Guidelines
- 规则 1
- 规则 2
runner = AgentRunner(
llm_call=...,
trace_store=...,
skills_dir="./skills", # 指向你的 skills 目录
)
内置 skills(agent/memory/skills/)始终自动加载,skills_dir 的内容额外追加。
知识管理系统通过提取、存储、注入三个环节,让 Agent 积累和复用结构化知识。
1. 提取(Extract)
agent/core/prompts/knowledge.py)2. 存储(Store)
http://localhost:8765)title: 知识标题content: 知识内容type: 知识类型(strategy/tool/pattern/pitfall 等)tags: 标签(键值对,用于分类和检索)scopes: 作用域(如 org:cybertogether)owner: 所有者(默认从 git config user.email 获取)resource_ids: 关联资源 ID 列表(代码片段、凭证、cookies 等)resource_ids 字段)body(公开内容)和 secure_body(加密内容)3. 注入(Inject)
知识管理配置通过 RunConfig.knowledge 传递:
from agent.core.runner import KnowledgeConfig, RunConfig
run_config = RunConfig(
model="claude-sonnet-4.5",
temperature=0.3,
max_iterations=1000,
knowledge=KnowledgeConfig(
# 压缩时提取(消息量超阈值触发压缩时,用完整 history 反思)
enable_extraction=True,
reflect_prompt="", # 空则使用默认,见 agent/core/prompts/knowledge.py:REFLECT_PROMPT
# agent运行完成后提取
enable_completion_extraction=True,
completion_reflect_prompt="", # 空则使用默认
# 知识注入(agent切换当前工作的goal时,自动注入相关知识)
enable_injection=True,
# 默认字段(保存/搜索时自动注入)
owner="", # 空则从 git config user.email 获取(隐藏参数,LLM 不可见)
default_tags={"project": "my_project"}, # 与 LLM 传递的 tags 合并
default_scopes=["org:cybertogether"], # 与 LLM 传递的 scopes 合并
default_search_types=["strategy", "tool"],
default_search_owner="" # 空则不过滤
)
)
参数注入规则(通过框架 inject_params 机制实现,详见 agent/docs/tools.md):
owner:隐藏参数,LLM 不可见,框架自动注入(mode: default)tags:LLM 可追加新 key,框架默认 key 不可被覆盖(mode: merge)scopes:LLM 可追加,与框架默认值合并去重(mode: merge)框架提供以下内置工具用于知识管理:
knowledge_save: 保存知识到知识库knowledge_search: 搜索知识库knowledge_get: 获取指定知识详情resource_save: 保存资源(代码、凭证等)resource_get: 获取资源内容这些工具会自动注入配置的默认字段(owner, tags, scopes 等)。
AgentRunner(
llm_call, # 必需:LLM 调用函数
trace_store=None, # Trace 持久化(推荐 FileSystemTraceStore)
tool_registry=None, # 工具注册表(默认:全局 registry)
skills_dir=None, # 自定义 skills 目录
utility_llm_call=None, # 轻量 LLM(生成任务标题等)
debug=False, # 调试模式
)
RunConfig(
model="gpt-4o", # 模型标识
temperature=0.3,
max_iterations=200, # Agent loop 最大轮数
tools=None, # None=全部已注册工具,List[str]=内置+指定工具
system_prompt=None, # None=从 skills 自动构建
agent_type="default", # 预设类型:default / explore / analyst
trace_id=None, # 续跑/回溯时传入已有 trace ID
after_sequence=None, # 从哪条消息后续跑(message sequence)
knowledge=KnowledgeConfig(), # 知识管理配置
)
system_prompt=None, # None=从 skills 自动构建
agent_type="default", # 预设类型:default / explore / analyst
trace_id=None, # 续跑/回溯时传入已有 trace ID
after_sequence=None, # 从哪条消息后续跑(message sequence)
)
## LLM Providers
框架内置两个 provider:
```python
from agent.llm import create_openrouter_llm_call, create_gemini_llm_call
# OpenRouter(支持多种模型)
llm = create_openrouter_llm_call(model="anthropic/claude-sonnet-4.5")
# Google Gemini
llm = create_gemini_llm_call(model="gemini-2.5-flash")
自定义 provider 只需实现签名:
async def my_llm_call(messages, model, tools, temperature, **kwargs) -> dict:
# 调用你的 LLM
return {
"content": "...",
"tool_calls": [...] or None,
"prompt_tokens": 100,
"completion_tokens": 50,
"cost": 0.001,
"finish_reason": "stop",
}
python api_server.py
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/traces |
列出 Traces |
| GET | /api/traces/{id} |
Trace 详情 |
| GET | /api/traces/{id}/messages |
消息列表 |
| POST | /api/traces |
新建并执行 |
| POST | /api/traces/{id}/run |
续跑/回溯 |
| POST | /api/traces/{id}/stop |
停止 |
| WS | /api/traces/{id}/watch |
实时事件 |
需在 api_server.py 中配置 Runner 才能启用 POST 端点。
agent/
├── core/ # AgentRunner + 预设
├── tools/ # 工具系统(registry + 内置工具)
├── trace/ # 执行追踪 + 计划(GoalTree)+ API
├── memory/ # Skills + Experiences
└── llm/ # LLM Provider 适配
详细架构文档:docs/README.md
框架提供交互式控制器,支持实时监控、手动干预和经验总结。
from agent.cli import InteractiveController
# 创建交互控制器
interactive = InteractiveController(
runner=runner,
store=store,
enable_stdin_check=True # 启用标准输入检查
)
# 在执行循环中检查用户输入
async for item in runner.run(messages=messages, config=config):
cmd = interactive.check_stdin()
if cmd == 'pause':
await runner.stop(trace_id)
menu_result = await interactive.show_menu(trace_id, current_sequence)
# 处理菜单结果...
elif cmd == 'quit':
await runner.stop(trace_id)
break
在执行过程中,可以通过命令行实时控制:
| 按键 | 动作 | 说明 |
|---|---|---|
p / pause |
暂停执行 | 立即挂起 Agent 循环,进入交互菜单 |
q / quit |
停止执行 | 安全停止并保存当前的执行状态 |
进入暂停模式后,系统提供以下操作:
完整的项目配置示例见 examples/research/config.py:
from agent.core.runner import KnowledgeConfig, RunConfig
from agent.utils import setup_logging
# Agent 运行配置
RUN_CONFIG = RunConfig(
model="claude-sonnet-4.5",
temperature=0.3,
max_iterations=1000,
name="Research Agent",
knowledge=KnowledgeConfig(
enable_extraction=True,
enable_completion_extraction=True,
enable_injection=True,
owner="", # 空则从 git config 获取
default_tags={"project": "research"},
default_scopes=["org:cybertogether"],
default_search_types=["strategy", "tool"],
)
)
# 基础设施配置
SKILLS_DIR = "./skills"
TRACE_STORE_PATH = ".trace"
DEBUG = True
LOG_LEVEL = "INFO"
LOG_FILE = None # 可设置为文件路径
# 在 run.py 中使用
setup_logging(level=LOG_LEVEL, file=LOG_FILE)
runner = AgentRunner(
trace_store=FileSystemTraceStore(base_path=TRACE_STORE_PATH),
llm_call=create_openrouter_llm_call(model=f"anthropic/{RUN_CONFIG.model}"),
skills_dir=SKILLS_DIR,
debug=DEBUG
)
async for item in runner.run(messages=messages, config=RUN_CONFIG):
# 处理执行结果
pass
配置说明:
RunConfig 和 KnowledgeConfig,不需要自定义配置类agent.utils.setup_logging() 配置日志框架在运行期间会生成唯一的 trace_id。
.trace/ 目录下。python api_server.py启动前端:
cd frontend/react-template
yarn
yarn dev
访问控制台:http://localhost:3000
在前端界面中切换任务,即直观追踪 Agent 的思考链路。
可以参考其他文件夹中的结构:
examples/[your_example]/
├── input/ # (可选)输入数据
├── output_1/ # (可选)输出目录
├── skills/ # (可选)领域专属 Skill (.md)
├── tool/ # (可选)自定义工具
├── presets.json # (可选)预定义的子 Agent 配置
├── config.py # (推荐)项目配置
├── [task].prompt # (必须)任务 System Prompt 和 User Prompt
└── run.py # (必须)交互式运行入口
针对 Clash Verge / TUN 模式等网络环境,本项目已内置代理自动避让逻辑:
no_proxy 配置防止 httpx 错误引导流量。cloud (远程) 和 local (本地) 模式切换。运行过程中,会自动存储以下内容:
.trace/ 文件夹下的实际运行路径结果