支持永久记忆、持续学习、探索性解决复杂问题的Agent框架。

guantao 8e542fcb41 fix: properly serialize Milvus search results to avoid KeyError 14 часов назад
.claude b3e70cbc7b update: support asking for help by feishu messages 18 часов назад
agent ad04223898 Merge remote-tracking branch 'refs/remotes/origin/main' 17 часов назад
config 464e9c4a79 更新飞书联系人信息 16 часов назад
docs fd8359ed5d refactor: memory/skill and knowledge config import 21 часов назад
examples 9ea963ba0b fix message node visualization error 17 часов назад
frontend 9ea963ba0b fix message node visualization error 17 часов назад
gateway fd8359ed5d refactor: memory/skill and knowledge config import 21 часов назад
knowhub 8e542fcb41 fix: properly serialize Milvus search results to avoid KeyError 14 часов назад
vendor d662097715 refactor: improve project structure 4 недель назад
.env.template 73d3999a97 fix: knowhub url 21 часов назад
.gitignore 40a5a77318 migrate: move knowhub data to milvus 15 часов назад
.gitmodules 5b3e6c586b feat: opencode tools adapter 1 месяц назад
README.md 39bc2bde7c readme update 20 часов назад
api_server.py d36eff2209 merged frontend with main 20 часов назад
gateway_server.py 301772d835 feat: a2a im gateway 5 дней назад
migrate_knowledge.py 1b10d0f3b2 feat: add tag_keys array field for efficient tag filtering 15 часов назад
requirements.txt 61a673631b feat: integrate knowhub 4 дней назад

README.md

Reson Agent

可扩展的 Agent 框架。支持多步工具调用、计划管理、子 Agent 协作、回溯重跑和上下文压缩。

Quick Start

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。

参数 Schema 生成

框架从函数签名和 docstring 自动生成 OpenAI Tool Schema,无需手写 JSON:

  • 参数类型:从类型注解推断(str/int/float/bool/list/dict,支持 OptionalLiteralList[T]
  • 参数描述:从 Google 风格 docstring 的 Args: 段提取
  • 必填/可选:有默认值的参数为可选,否则为必填
  • 工具描述:优先使用 @tool(description=...) 参数,其次取 docstring 首行
  • uidcontext 参数由框架自动注入,不会出现在 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

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/skill/skills/)始终自动加载,skills_dir 的内容额外追加。

知识管理系统(Knowledge Management)

知识管理系统通过提取、存储、注入三个环节,让 Agent 积累和复用结构化知识。

核心流程

1. 提取(Extract)

  • 触发时机
    • 压缩时提取:消息量超阈值触发压缩时,在 Level 1 过滤前用完整 history 反思
    • 完成时提取:Agent 运行完成后(不代表任务完成,可能中途退出等待人工评估)
  • 提取方式:调用 LLM 对执行过程进行反思,提取可复用的知识
  • 自定义 Prompt:可通过配置自定义反思 prompt,空则使用默认(见 agent/core/prompts/knowledge.py

2. 存储(Store)

  • 存储位置:KnowHub 服务(默认 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(加密内容)
    • 支持代码片段、API 凭证、cookies 等多种资源类型

3. 注入(Inject)

  • 触发时机:Agent 切换当前工作的 Goal 时自动触发
  • 检索策略:基于 Goal 描述和上下文,从知识库检索相关知识
  • 注入方式:将检索到的知识注入到 Agent 的上下文中

配置

知识管理配置通过 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 参数

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 参数

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",
    }

API Server

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
├── skill/          # Skills(技能系统)
└── llm/            # LLM Provider 适配

详细架构文档:docs/README.md

交互式 CLI(Interactive CLI)

框架提供交互式控制器,支持实时监控、手动干预和经验总结。

使用方式

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 停止执行 安全停止并保存当前的执行状态

交互菜单功能

进入暂停模式后,系统提供以下操作:

  1. 插入干预消息:直接向 Agent 下达新指令
  2. 触发经验总结 (Reflect):强制 Agent 对当前过程进行反思
  3. 查看 GoalTree:可视化当前任务的拆解结构和完成进度
  4. 上下文压缩 (Compact):手动精简对话历史

项目配置示例

完整的项目配置示例见 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

配置说明

  • 直接使用框架的 RunConfigKnowledgeConfig,不需要自定义配置类
  • 基础设施配置(skills_dir, trace_store_path 等)用简单变量定义
  • 使用 agent.utils.setup_logging() 配置日志

任务可视化与调试

框架在运行期间会生成唯一的 trace_id

  • 本地日志:所有的执行细节、工具调用和 Goal 状态均持久化在 .trace/ 目录下。
  • Web 可视化
  1. 启动服务器:python api_server.py
  2. 启动前端:

    cd frontend/react-template
    yarn
    yarn dev
    
  3. 访问控制台:http://localhost:3000

  4. 在前端界面中切换任务,即直观追踪 Agent 的思考链路。

  5. 因为该可视化读取的是根目录下的.trace文件,建议运行项目时,可以在根目录下用命令行运行python examples/[project_name]/run.py,使运行得到的trace存放在根目录

提示:目前前端可视化只供观看本地运行过的trace结果,新任务运行等功能正在开发中,运行可在命令行中执行

绿色节点为整体的goal(目标),蓝色节点为子goal(目标),灰色节点为基础信息节点。点击蓝色边/绿色边会折叠节点,点击节点会在右侧显示详情。


示例项目结构

可以参考其他文件夹中的结构:

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 错误引导流量。
  • Browser 模式:支持 cloud (远程) 和 local (本地) 模式切换。

运行结果存储

运行过程中,会自动存储以下内容:

  • 运行轨迹:根目录下 .trace/ 文件夹下的实际运行路径结果
  • 知识库:KnowHub 服务中保存的知识条目(通过 API 访问)