♻️ refactor(core): 重构 AI 编排框架与记忆及 RAG 子系统 (#2149)

* ♻️ refactor(core): 重构 AI 编排框架与记忆及 RAG 子系统

- 【重构】重构 `BaseRunnable` 并引入统一的 `RunIntent` 意图载体,规范 Agent、Team 和 Workflow 的执行流
- 【解耦】将中期记忆槽和长期向量记忆从 `MemoryConfig` 中解耦,转为独立的能力组件与工具箱进行管理
- 【记忆】移除 `MemoryReader` 和 `MemoryWriter`,统一封装为 `SessionMemoryContext` 会话记忆门面
- 【RAG】重构检索器与存储后端接口,统一采用 `QueryRequest` 进行多维度联合检索,并引入 `InMemoryScorer` 提升打分性能
- 【事件】优化 `EventBus` 异步事件分发机制,引入队列机制确保事件按序处理,避免并发竞态问题
- 【依赖注入】移除 `memory` 注入项,优化 `DependencyInjector` 的签名解析缓存以提升性能

* 🚨 auto fix by pre-commit hooks

---------

Co-authored-by: webjoin111 <455457521@qq.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Rumio
2026-07-14 16:48:33 +08:00
committed by GitHub
co-authored by webjoin111 pre-commit-ci[bot]
parent 922d092650
commit 52f7dbdedf
66 changed files with 2131 additions and 2353 deletions
+32 -52
View File
@@ -1,18 +1,18 @@
from abc import ABC, abstractmethod
from collections.abc import Awaitable, Callable, Mapping, Sequence
import inspect
from collections.abc import Callable, Mapping, Sequence
import re
from typing import Any, cast
from nonebot.utils import is_coroutine_callable
from zhenxun.services.ai.core.messages import AgentMessage
from zhenxun.services.ai.core.templates import PromptTemplate
from zhenxun.services.ai.run import AgentTask, RunContext
from zhenxun.services.ai.flow.agent.agent import Agent, ToolSource
from zhenxun.services.ai.flow.agent.models import AgentConfig
from zhenxun.services.ai.flow.core.base import BaseRunnable
from zhenxun.services.ai.run import RunContext, RunIntent
from zhenxun.services.ai.run.di import DependencyInjector
from zhenxun.services.ai.utils.logger import log_team as logger
from .models import RouteDecision, Transition
from .capabilities import TeamRoutingCapability
from .models import RouteDecision, TeamRuntimeConfig, Transition
class BaseRouter(ABC):
@@ -23,7 +23,7 @@ class BaseRouter(ABC):
self,
context: RunContext,
history: Sequence[AgentMessage],
prompt: str | AgentTask | None = None,
intent: RunIntent,
) -> RouteDecision | None:
"""核心路由方法"""
pass
@@ -32,7 +32,9 @@ class BaseRouter(ABC):
class FunctionRouter(BaseRouter):
"""基于纯函数的极速路由器"""
def __init__(self, selector_func: Callable[..., Any], target: str | None = None):
def __init__(
self, selector_func: Callable[..., str | bool | None], target: str | None = None
):
"""
初始化基于函数的极速路由器。
@@ -47,27 +49,21 @@ class FunctionRouter(BaseRouter):
self,
context: RunContext,
history: Sequence[AgentMessage],
prompt: str | AgentTask | None = None,
intent: RunIntent,
) -> RouteDecision | None:
sig = inspect.signature(self.selector_func)
call_kwargs = {"prompt": prompt, "context": context, "history": history}
if isinstance(prompt, AgentTask):
call_kwargs["agent_task"] = prompt
call_kwargs["task"] = prompt
kwargs_resolved = await DependencyInjector.resolve_all(
sig, call_kwargs, context
)
filtered_kwargs = {
k: v for k, v in kwargs_resolved.items() if k in sig.parameters
call_kwargs = {
"intent": intent,
"prompt": intent.original_input,
"context": context,
"history": history,
}
if intent.task_obj:
call_kwargs["agent_task"] = intent.task_obj
call_kwargs["task"] = intent.task_obj
if is_coroutine_callable(self.selector_func):
_async_func = cast(Callable[..., Awaitable[Any]], self.selector_func)
selected_target = await _async_func(**filtered_kwargs)
else:
_sync_func = cast(Callable[..., Any], self.selector_func)
selected_target = _sync_func(**filtered_kwargs)
selected_target = await DependencyInjector.invoke(
self.selector_func, call_kwargs, context
)
if isinstance(selected_target, bool):
if selected_target and self.target:
@@ -97,13 +93,9 @@ class RegexRouter(BaseRouter):
self,
context: RunContext,
history: Sequence[AgentMessage],
prompt: str | AgentTask | None = None,
intent: RunIntent,
) -> RouteDecision | None:
text_to_match = (
prompt.description
if isinstance(prompt, AgentTask)
else (prompt or context.run.user_input or "")
)
text_to_match = intent.text or context.run.user_input or ""
if self.pattern.search(text_to_match):
logger.debug(f"命中正则极速路由 -> {self.target}")
@@ -127,10 +119,10 @@ class ChainRouter(BaseRouter):
self,
context: RunContext,
history: Sequence[AgentMessage],
prompt: str | AgentTask | None = None,
intent: RunIntent,
) -> RouteDecision | None:
for router in self.routers:
decision = await router.route(context, history, prompt)
decision = await router.route(context, history, intent)
if decision is not None:
return decision
return None
@@ -142,11 +134,11 @@ class LLMRouter(BaseRouter):
def __init__(
self,
team_name: str,
members: list[Any],
members: list[BaseRunnable],
leader_model: str | None = None,
leader_tools: list[Any] | None = None,
leader_tools: list[ToolSource] | None = None,
state_flow: Mapping[str, Sequence[Transition | str]] | Callable | None = None,
runtime_config: Any = None,
runtime_config: TeamRuntimeConfig | None = None,
custom_prompt: str | None = None,
allowed_transitions: list[Transition] | None = None,
max_handoffs: int = 3,
@@ -179,13 +171,8 @@ class LLMRouter(BaseRouter):
self,
context: RunContext,
history: Sequence[AgentMessage],
prompt: str | AgentTask | None = None,
intent: RunIntent,
) -> RouteDecision | None:
from zhenxun.services.ai.flow.agent.agent import Agent
from zhenxun.services.ai.flow.agent.models import AgentConfig
from .capabilities import TeamRoutingCapability
default_system_prompt = """## 角色与目标
你是一个高级任务路由器 (所在团队: {{ team_name }})。
请根据用户的输入意图,立刻调用相应的移交工具 (transfer_to_...)
@@ -217,13 +204,6 @@ class LLMRouter(BaseRouter):
)
target_model = self.leader_model
if not target_model:
for m in self.members:
if m_model := getattr(m, "model_name", None) or getattr(
m, "model", None
):
target_model = m_model
break
router_agent = Agent(
name=f"{self.team_name}_Router",
@@ -240,7 +220,7 @@ class LLMRouter(BaseRouter):
logger.debug("🤖 [LLMRouter] 启动 LLM 思考路由决策...")
res = await router_agent.run(
prompt=prompt,
prompt=intent.original_input,
context=sub_context,
config=AgentConfig(message_history=history),
)