Runtime 组件设计文档¶
定位
Runtime 是 Agent 的“执行循环”,负责调度 Profile / Planning / Action / Memory / Reflection 各个组件,驱动 Agent 从用户请求到最终回复的全过程。
1. 设计目标¶
- 统一调度:将 Planner 产出的计划依次执行。
- 工具调用:调用 MCPRegistry 中注册的工具,获取执行结果。
- 容错处理:在工具出错或计划无效时提供兜底策略(如 fallback reply)。
- 可扩展性:支持日志记录、事件追踪、记忆写入、反思更新。
- 简单易用:调用
agent.step(dialog)
即可完成一次完整的感知 → 规划 → 执行 → 反馈流程。
2. 数据流¶
graph TD
U[用户请求] -->|dialog| R(Runtime)
R --> P(Planner)
P --> Plan
Plan --> R
R -->|for step in plan| A(Action via MCPRegistry)
A --> Obs[Observation]
Obs --> R
R --> Refl[Reflection]
Refl --> Mem[Memory]
R -->|最终回复| U2[用户]
3. 核心类¶
runtime/agent.py
from typing import List, Dict
from sage.libs.agents.planning.schema import Plan, PlanStep
from sage.libs.agents.action.mcp_registry import MCPRegistry
class AgentRuntime:
def __init__(self, profile, planner, registry: MCPRegistry, memory=None, reflector=None, llm=None):
self.profile = profile
self.planner = planner
self.registry = registry
self.memory = memory
self.reflector = reflector
self.llm = llm
def step(self, dialog: List[dict]) -> dict:
# 1) Profile prompt
profile_prompt = self.profile.render_system_prompt()
# 2) 生成计划
plan: Plan = self.planner.plan(profile_prompt, dialog[-1]["content"], self.registry.describe())
results = []
reply = None
for step in plan.steps:
if step.type == "tool":
try:
obs = self.registry.call(step.name, step.arguments)
results.append({"tool": step.name, "output": obs})
except Exception as e:
results.append({"tool": step.name, "error": str(e)})
elif step.type == "reply":
reply = {"role": "assistant", "content": step.text}
# 3) Reflection + Memory
if self.reflector:
self.reflector.reflect(results, self.memory)
if self.memory:
self.memory.write(str(results))
# 4) 返回最终回复
return reply or {"role": "assistant", "content": "(no valid reply)"}
4. 使用示例¶
from sage.libs.agents.profile.profile import BaseProfile
from sage.libs.agents.planning.llm_planner import LLMPlanner
from sage.libs.agents.action.mcp_registry import MCPRegistry
from sage.libs.rag.generator import OpenAIGenerator
# 1) Profile
profile = BaseProfile(name="ResearchAgent", role="planner", language="zh")
# 2) Generator + Planner
gen = OpenAIGenerator({"method":"openai","model_name":"gpt-4o-mini","base_url":"http://localhost:8000/v1","api_key":"sk-..."})
planner = LLMPlanner(generator=gen)
# 3) 工具注册
reg = MCPRegistry()
reg.register(Calculator())
reg.register(ArxivSearcher())
# 4) Runtime
agent = AgentRuntime(profile, planner, reg)
# 5) 单轮对话
dialog = [{"role": "user", "content": "帮我查 arXiv 上的 LLM agents 综述,并计算 21*2+5"}]
resp = agent.step(dialog)
print(resp)
5. 扩展方向¶
- 多轮循环:在
step()
内支持PLAN → ACT → OBSERVE → REPLAN
的循环,而不是一次性计划。 - 事件总线:在执行过程中生成结构化事件流(可存储为 JSONL,用于调试/复现)。
- 错误处理:对工具报错时自动触发 replanning,而不是简单记录错误。
- 并发执行:当 Planner 产出可并行的工具调用时,Runtime 可并行调度。