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

elksmmx 1fee8268ab Merge branch 'main' into dev_sun 8 tuntia sitten
.claude b3e70cbc7b update: support asking for help by feishu messages 10 tuntia sitten
agent 513e114fb8 Merge branch 'main' into dev_sun 9 tuntia sitten
config 464e9c4a79 更新飞书联系人信息 9 tuntia sitten
docs fd8359ed5d refactor: memory/skill and knowledge config import 14 tuntia sitten
examples 513e114fb8 Merge branch 'main' into dev_sun 9 tuntia sitten
frontend 9ea963ba0b fix message node visualization error 9 tuntia sitten
gateway fd8359ed5d refactor: memory/skill and knowledge config import 14 tuntia sitten
knowhub 6b7b065065 fix: knowhub milvus 9 tuntia sitten
vendor d662097715 refactor: improve project structure 4 viikkoa sitten
.env.template 73d3999a97 fix: knowhub url 13 tuntia sitten
.gitignore 2ecc725a3e fix: knowhub env 4 päivää sitten
.gitmodules 5b3e6c586b feat: opencode tools adapter 1 kuukausi sitten
README.md 39bc2bde7c readme update 12 tuntia sitten
analyze_messages.py 2d135fa150 create:new branch 6 päivää sitten
api_server.py d36eff2209 merged frontend with main 13 tuntia sitten
check_cache_positions.py 2d135fa150 create:new branch 6 päivää sitten
debug_cache.py 2d135fa150 create:new branch 6 päivää sitten
gateway_server.py 301772d835 feat: a2a im gateway 5 päivää sitten
requirements.txt 61a673631b feat: integrate knowhub 4 päivää sitten
test_embeddings.py b988c96812 feat: side branch mode in runner 11 tuntia sitten
test_vector_search.py df9fd5e597 feat: inject_params & milvus in knowhub 14 tuntia sitten

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 访问)