refactor(core): decouple actors and remove workflow templates (#67)

Removes the deprecated `workflow_template` concept entirely across both backend API routers, internal logic handling within the `supervisory_node` and `consciousness_node`, and front-end components. Enables `consciousness_node` to work autonomously.

Also refactors core package structure to enforce the "one python package, one Ray Actor" architectural rule. `GlobalWorkflowManager`, `WorkflowRunningEngine`, `PostgresDatabase`, and `WorkerCluster` have been moved to their own top-level decoupled package directories with properly exported `__init__.py` modules. Test suites have been relocated and import paths updated across the system.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: zhaoxi826 <198742034+zhaoxi826@users.noreply.github.com>
This commit is contained in:
2026-05-06 15:05:47 +08:00
committed by GitHub
parent b3ea4cd8d9
commit 209ba45477
97 changed files with 1872 additions and 1498 deletions
@@ -13,4 +13,5 @@
# limitations under the License.
from .consciousness_node import ConsciousnessNode
__all__ = ["ConsciousnessNode"]
@@ -15,8 +15,15 @@
import ray
from typing import Union, overload
from pretor.core.individual.consciousness_node.template import (ConsciousnessNodeDeps, ForSupervisoryNode, ForWorkflow,\
ForWorkflowEngine, ForWorkflowInput, ForSupervisoryInput, ForWorkflowEngineInput)
from pretor.core.individual.consciousness_node.template import (
ConsciousnessNodeDeps,
ForSupervisoryNode,
ForWorkflow,
ForWorkflowEngine,
ForWorkflowInput,
ForSupervisoryInput,
ForWorkflowEngineInput,
)
from pydantic_ai import Agent, RunContext
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine
from pretor.core.global_state_machine.model_provider.base_provider import Provider
@@ -26,14 +33,21 @@ from pretor.adapter.model_adapter.agent_factory import AgentFactory
@ray.remote
class ConsciousnessNode:
"""ConsciousnessNode 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
def __init__(self) -> None:
from pretor.utils.logger import get_logger
self.logger = get_logger('consciousness_node')
self.logger = get_logger("consciousness_node")
self.agent: None | Agent = None
async def create_agent(self, global_state_machine: GlobalStateMachine, provider_title: str, model_id: str, tools_list: list[str] = None) -> None:
async def create_agent(
self,
global_state_machine: GlobalStateMachine,
provider_title: str,
model_id: str,
tools_list: list[str] = None,
) -> None:
"""
create_agent方法,将agent对象装配到ConsciousnessNode的属性内
该方法通过provider_title从global_state_machine中获取provider对象,然后从provider对象中取出供应商形象,装配为pydantic_ai的
@@ -58,32 +72,35 @@ class ConsciousnessNode:
)
output_type = Union[ForSupervisoryNode, ForWorkflow, ForWorkflowEngine]
from pretor.utils.get_tool import load_tools_from_list
provider: Provider = await global_state_machine.get_provider.remote( provider_title)
provider: Provider = await global_state_machine.get_provider.remote(
provider_title
)
agent_factory = AgentFactory()
callables = load_tools_from_list(tools_list)
self.agent = agent_factory.create_agent(provider=provider,
model_id=model_id,
output_type=output_type,
system_prompt=system_prompt,
deps_type=ConsciousnessNodeDeps,
agent_name="consciousness_node",
tools=callables)
self.agent = agent_factory.create_agent(
provider=provider,
model_id=model_id,
output_type=output_type,
system_prompt=system_prompt,
deps_type=ConsciousnessNodeDeps,
agent_name="consciousness_node",
tools=callables,
)
@self.agent.system_prompt
async def dynamic_prompt(ctx: RunContext[ConsciousnessNodeDeps]):
"""执行与 dynamic prompt 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑,确保操作能够在事务上下文中被原子且一致地执行。
Args: ctx (RunContext[ConsciousnessNodeDeps]): 参与 dynamic prompt 逻辑运算或数据构建的上下文依赖对象。
Returns: : 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。 """
Returns: : 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。"""
prompt = system_prompt + "\n\n"
prompt += (
f"=== 当前任务上下文 ===\n"
f"- 当前指令 (Command): {ctx.deps.command}\n"
f"- 原始用户命令 (Original Command): {ctx.deps.original_command}\n"
)
if ctx.deps.workflow_template:
prompt += f"- 选定工作流模板 (Workflow Template): {ctx.deps.workflow_template}\n"
if ctx.deps.available_skills:
prompt += "\n=== 当前可用 Skill Individual ===\n"
prompt += "你可以直接将以下 Skill Individual 安排进工作流的步骤中(设置 node 为 skill_individual,并将 agent_id 设置为对应 Skill Individual 的真实 agent_id,不要用名称!),作为可调用的工具。\n"
@@ -92,30 +109,34 @@ class ConsciousnessNode:
return prompt
async def working(self, payload: Union[ForWorkflowEngineInput, ForWorkflowInput, ForSupervisoryInput]) -> Union[ForWorkflowEngine, ForWorkflow, ForSupervisoryNode, None]:
async def working(
self,
payload: Union[ForWorkflowEngineInput, ForWorkflowInput, ForSupervisoryInput],
) -> Union[ForWorkflowEngine, ForWorkflow, ForSupervisoryNode, None]:
"""执行与 working 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑,确保操作能够在事务上下文中被原子且一致地执行。
Args: payload (Union[ForWorkflowEngineInput, ForWorkflowInput, ForSupervisoryInput]): 从客户端传递过来或由上游组件生成的核心业务数据体,通常需要进一步的清洗和结构化解析。
Returns: (Union[ForWorkflowEngine, ForWorkflow, ForSupervisoryNode, None]): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。 """
Returns: (Union[ForWorkflowEngine, ForWorkflow, ForSupervisoryNode, None]): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。"""
try:
result = await self._run(payload)
if isinstance(result, (ForWorkflowEngine, ForWorkflow, ForSupervisoryNode)):
return result
else:
self.logger.error(f"ConsciousnessNode: 未知或不匹配的返回类型: {type(result)}")
self.logger.error(
f"ConsciousnessNode: 未知或不匹配的返回类型: {type(result)}"
)
return None
except Exception:
self.logger.exception("ConsciousnessNode在执行working时发生严重错误")
return None
@overload
async def _run(self, payload: ForWorkflowEngineInput) -> ForWorkflowEngine:
"""
_run方法
该分支应当在supervisory_node简单处理用户命令后,工作流创建前调用!
Args:
payload: 应当包含workflow_template和event对象
payload: 应当包含原始命令和可用技能等信息
Returns:
ForWorkflowEngine对象,将被放到全局状态机后丢入WorkflowEngine的异步队列
@@ -148,45 +169,53 @@ class ConsciousnessNode:
"""
pass
async def _run(self, payload: Union[ForSupervisoryInput, ForWorkflowInput, ForWorkflowEngineInput]) -> Union[ForSupervisoryNode, ForWorkflow, ForWorkflowEngine]:
async def _run(
self,
payload: Union[ForSupervisoryInput, ForWorkflowInput, ForWorkflowEngineInput],
) -> Union[ForSupervisoryNode, ForWorkflow, ForWorkflowEngine]:
"""执行与 run 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑,确保操作能够在事务上下文中被原子且一致地执行。
Args: payload (Union[ForSupervisoryInput, ForWorkflowInput, ForWorkflowEngineInput]): 从客户端传递过来或由上游组件生成的核心业务数据体,通常需要进一步的清洗和结构化解析。
Returns: (Union[ForSupervisoryNode, ForWorkflow, ForWorkflowEngine]): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。 """
Returns: (Union[ForSupervisoryNode, ForWorkflow, ForWorkflowEngine]): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。"""
try:
self.agent.retries = 3
if isinstance(payload, ForWorkflowEngineInput):
deps = ConsciousnessNodeDeps(
original_command=payload.original_command,
workflow_template=payload.workflow_template,
command="拆解原始命令变成一个工作流",
available_skills=payload.available_skills
command="自主分析并拆解原始命令,生成严密可执行的工作流",
available_skills=payload.available_skills,
)
self.logger.debug("ConsciousnessNode: 开始生成工作流 (原生重试开启)")
prompt = "根据original_command制定严密的可执行workflow"
if payload.workflow_template:
prompt += ",可以学习并参考workflow_template的设计理念"
result = await self.agent.run(prompt, deps=deps)
return result.output
elif isinstance(payload, ForWorkflowInput):
deps = ConsciousnessNodeDeps(
original_command=payload.original_command,
command="完成workflow step中分配给意识节点的特定任务或指导"
command="完成workflow step中分配给意识节点的特定任务或指导",
)
self.logger.debug(
"ConsciousnessNode: 开始处理工作流节点任务 (原生重试开启)"
)
result = await self.agent.run(
f"处理此工作流步骤信息:\n{payload.workflow_step.model_dump_json()}",
deps=deps,
)
self.logger.debug("ConsciousnessNode: 开始处理工作流节点任务 (原生重试开启)")
result = await self.agent.run(f"处理此工作流步骤信息:\n{payload.workflow_step.model_dump_json()}",
deps=deps)
return result.output
elif isinstance(payload, ForSupervisoryInput):
deps = ConsciousnessNodeDeps(
original_command=payload.original_command,
command="对于工作流整体执行结果进行检查,并且生成一份专业的技术性总结报告"
command="对于工作流整体执行结果进行检查,并且生成一份专业的技术性总结报告",
)
self.logger.debug(
"ConsciousnessNode: 开始生成技术总结报告 (原生重试开启)"
)
result = await self.agent.run(
f"基于以下工作流的执行记录,生成技术报告:\n{payload.workflow.model_dump_json()}",
deps=deps,
)
self.logger.debug("ConsciousnessNode: 开始生成技术总结报告 (原生重试开启)")
result = await self.agent.run(f"基于以下工作流的执行记录,生成技术报告:\n{payload.workflow.model_dump_json()}",
deps=deps)
return result.output
except Exception as e:
self.logger.exception(f"ConsciousnessNode 模型生成最终失败: {str(e)}")
@@ -18,60 +18,71 @@ from pretor.utils.agent_model import ResponseModel, DepsModel, InputModel
from pydantic import Field
#意识节点回复类
# 意识节点回复类
class ConsciousnessNodeResponse(ResponseModel):
"""Consciousness response model,是意识节点所有回复类型的父类"""
pass
class ForWorkflowEngine(ConsciousnessNodeResponse):
"""生成workflow并放入WorkflowEngine"""
workflow: PretorWorkflow = Field(..., description="生成好的符合规范的完整工作流对象。")
workflow: PretorWorkflow = Field(
..., description="生成好的符合规范的完整工作流对象。"
)
reasoning: str = Field(..., description="生成此工作流的原因和思路简述。")
class ForWorkflow(ConsciousnessNodeResponse):
"""处理workflow中需要ConsciousnessNode的工作"""
output: str = Field(..., description="对当前工作流步骤的具体处理结果或指导意见。")
class ForSupervisoryNode(ConsciousnessNodeResponse):
"""工作流完成后进行校验并返回给SupervisoryNode"""
output: str = Field(..., description="为监控节点提供的全工作流执行情况的技术性总结报告。")
output: str = Field(
..., description="为监控节点提供的全工作流执行情况的技术性总结报告。"
)
class ConsciousnessNodeDeps(DepsModel):
"""ConsciousnessNodeDeps 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
original_command: str
workflow_template: str | None = None
command: str
available_skills: list[dict] | None = None
class ConsciousnessNodeInput(InputModel):
"""ConsciousnessNodeInput 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
pass
class ForWorkflowEngineInput(ConsciousnessNodeInput):
"""ForWorkflowEngineInput 核心组件类。
这是一个领域数据模型或功能封装类,承载了 ForWorkflowEngineInput 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。 """
workflow_template: str | None = None
这是一个领域数据模型或功能封装类,承载了 ForWorkflowEngineInput 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。"""
original_command: str
available_skills: list[dict] | None = None
class ForWorkflowInput(ConsciousnessNodeInput):
"""ForWorkflowInput 核心组件类。
这是一个领域数据模型或功能封装类,承载了 ForWorkflowInput 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。 """
这是一个领域数据模型或功能封装类,承载了 ForWorkflowInput 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。"""
workflow_step: WorkStep
original_command: str
class ForSupervisoryInput(ConsciousnessNodeInput):
"""ForSupervisoryInput 核心组件类。
这是一个领域数据模型或功能封装类,承载了 ForSupervisoryInput 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。 """
这是一个领域数据模型或功能封装类,承载了 ForSupervisoryInput 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。"""
workflow: PretorWorkflow
original_command: str
@@ -13,4 +13,5 @@
# limitations under the License.
from .control_node import ControlNode
__all__ = ["ControlNode"]
@@ -17,21 +17,31 @@ from pydantic_ai import Agent, RunContext
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine
from pretor.core.global_state_machine.model_provider.base_provider import Provider
from pretor.adapter.model_adapter.agent_factory import AgentFactory
from pretor.core.individual.control_node.template import ForWorkflow, ForWorkflowInput, ControlNodeDeps
from pretor.core.individual.control_node.template import (
ForWorkflow,
ForWorkflowInput,
ControlNodeDeps,
)
@ray.remote
class ControlNode:
"""ControlNode 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
def __init__(self):
from pretor.utils.logger import get_logger
self.logger = get_logger('control_node')
self.logger = get_logger("control_node")
self.agent: Agent | None = None
async def create_agent(self, global_state_machine: GlobalStateMachine, provider_title: str, model_id: str, tools_list: list[str] = None) -> None:
async def create_agent(
self,
global_state_machine: GlobalStateMachine,
provider_title: str,
model_id: str,
tools_list: list[str] = None,
) -> None:
"""
create_agent方法,将agent对象装配到Control的属性内
该方法通过provider_title从global_state_machine中获取provider对象,然后从provider对象中取出供应商形象,装配为pydantic_ai的
@@ -56,23 +66,29 @@ class ControlNode:
)
output_type = ForWorkflow
from pretor.utils.get_tool import load_tools_from_list
provider: Provider = await global_state_machine.get_provider.remote( provider_title)
provider: Provider = await global_state_machine.get_provider.remote(
provider_title
)
agent_factory = AgentFactory()
callables = load_tools_from_list(tools_list)
self.agent = agent_factory.create_agent(provider=provider,
model_id=model_id,
output_type=output_type,
system_prompt=system_prompt,
deps_type=ControlNodeDeps,
agent_name="control_node",
tools=callables)
self.agent = agent_factory.create_agent(
provider=provider,
model_id=model_id,
output_type=output_type,
system_prompt=system_prompt,
deps_type=ControlNodeDeps,
agent_name="control_node",
tools=callables,
)
@self.agent.system_prompt
async def dynamic_prompt(ctx: RunContext[ControlNodeDeps]):
"""执行与 dynamic prompt 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑,确保操作能够在事务上下文中被原子且一致地执行。
Args: ctx (RunContext[ControlNodeDeps]): 参与 dynamic prompt 逻辑运算或数据构建的上下文依赖对象。
Returns: : 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。 """
Returns: : 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。"""
prompt = system_prompt + "\n\n"
prompt += (
f"=== 当前任务步骤上下文 ===\n"
@@ -86,7 +102,7 @@ class ControlNode:
"""执行与 working 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑,确保操作能够在事务上下文中被原子且一致地执行。
Args: payload (ForWorkflowInput): 从客户端传递过来或由上游组件生成的核心业务数据体,通常需要进一步的清洗和结构化解析。
Returns: (str): 处理流程所输出的具体字符串产物,可能是新生成的 ID 序列、格式化好的文本片段或 LLM 推理的回答内容。 """
Returns: (str): 处理流程所输出的具体字符串产物,可能是新生成的 ID 序列、格式化好的文本片段或 LLM 推理的回答内容。"""
try:
result: ForWorkflow = await self._run(payload)
return result
@@ -98,19 +114,21 @@ class ControlNode:
"""执行与 run 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑,确保操作能够在事务上下文中被原子且一致地执行。
Args: payload (ForWorkflowInput): 从客户端传递过来或由上游组件生成的核心业务数据体,通常需要进一步的清洗和结构化解析。
Returns: (ForWorkflow): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。 """
Returns: (ForWorkflow): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。"""
try:
self.agent.retries = 3
deps = ControlNodeDeps(
workflow_step=payload.workflow_step
deps = ControlNodeDeps(workflow_step=payload.workflow_step)
self.logger.debug(
f"ControlNode: 开始执行工作流节点 [{payload.workflow_step.name}] (原生重试开启)"
)
self.logger.debug(f"ControlNode: 开始执行工作流节点 [{payload.workflow_step.name}] (原生重试开启)")
result = await self.agent.run(
f"请根据提供的 workflow_step 上下文,执行此步骤并输出结果。\n详细指令或附加数据:{payload.workflow_step.model_dump_json()}",
deps=deps
deps=deps,
)
return result.output
except Exception as e:
self.logger.exception(f"ControlNode 在执行步骤 [{payload.workflow_step.name}] 时最终失败: {str(e)}")
self.logger.exception(
f"ControlNode 在执行步骤 [{payload.workflow_step.name}] 时最终失败: {str(e)}"
)
raise RuntimeError(f"ControlNode 执行步骤失败: {str(e)}") from e
@@ -17,31 +17,39 @@ from pydantic import Field
from pretor.core.workflow.workflow import WorkStep
from pretor.utils.agent_model import ResponseModel, InputModel, DepsModel
class ControlNodeResponse(ResponseModel):
"""控制节点回复的基类"""
pass
class ControlNodeInput(InputModel):
"""ControlNodeInput 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
pass
class ControlNodeDeps(DepsModel):
"""ControlNodeDeps 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
workflow_step: WorkStep
# In the future, this can be dynamically populated with tools specific to the current task execution
class ForWorkflow(ControlNodeResponse):
"""ForWorkflow 核心组件类。
这是一个领域数据模型或功能封装类,承载了 ForWorkflow 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。 """
output: str = Field(..., description="控制节点执行特定工作流步骤的结果。包含执行细节和输出数据。")
这是一个领域数据模型或功能封装类,承载了 ForWorkflow 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。"""
output: str = Field(
..., description="控制节点执行特定工作流步骤的结果。包含执行细节和输出数据。"
)
class ForWorkflowInput(ControlNodeInput):
"""ForWorkflowInput 核心组件类。
这是一个领域数据模型或功能封装类,承载了 ForWorkflowInput 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。 """
这是一个领域数据模型或功能封装类,承载了 ForWorkflowInput 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。"""
workflow_step: WorkStep
@@ -13,4 +13,5 @@
# limitations under the License.
from .supervisory_node import SupervisoryNode
__all__ = ["SupervisoryNode"]
@@ -19,7 +19,12 @@ from pretor.api.platform.event import PretorEvent
from pretor.adapter.model_adapter.agent_factory import AgentFactory
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine
from pretor.core.global_state_machine.model_provider import Provider
from pretor.core.individual.supervisory_node.template import ForConsciousnessNode, ForUser, SupervisoryNodeDeps, TerminationMessage
from pretor.core.individual.supervisory_node.template import (
ForConsciousnessNode,
ForUser,
SupervisoryNodeDeps,
TerminationMessage,
)
from pydantic_ai import RunContext, Agent
from pretor.utils.ray_hook import ray_actor_hook
@@ -27,14 +32,21 @@ from pretor.utils.ray_hook import ray_actor_hook
@ray.remote
class SupervisoryNode:
"""SupervisoryNode 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
def __init__(self) -> None:
from pretor.utils.logger import get_logger
self.logger = get_logger('supervisory_node')
self.logger = get_logger("supervisory_node")
self.agent: None | Agent = None
async def create_agent(self, global_state_machine: GlobalStateMachine, provider_title: str, model_id: str, tools_list: list[str] = None) -> None:
async def create_agent(
self,
global_state_machine: GlobalStateMachine,
provider_title: str,
model_id: str,
tools_list: list[str] = None,
) -> None:
"""
create_agent方法,将agent对象装配到SupervisoryNode的属性内
该方法通过provider_title从global_state_machine中获取provider对象,然后从provider对象中取出供应商形象,装配为pydantic_ai的Agent实例,
@@ -53,43 +65,47 @@ class SupervisoryNode:
"你的核心职责是进行【意图识别与路由】。请仔细阅读用户的请求:\n"
"1. 如果用户只是进行简单的问候、闲聊或查询非常基础的信息,请直接生成友好的回复,使用 ForUser 格式。\n"
"2. 如果用户提出的是复杂任务(如需要编写代码、多步骤规划、数据处理等),请务必将其判定为需要工作流处理的任务,"
" 并使用 ForConsciousnessNode 格式。若提供的【可用模板列表】中有合适的模板请选用,若都不匹配则 workflow_template 设为 null\n"
" 并使用 ForConsciousnessNode 格式将其移交意识节点处理\n"
"3. 如果你收到的是 TerminationMessage(代表工作流已完成并生成了报告),请将报告内容转化为友好的面向用户的回复,使用 ForUser 格式。\n"
"请保持冷静、专业,并严格遵循上述路由规则。"
)
output_type = Union[ForConsciousnessNode, ForUser]
from pretor.utils.get_tool import load_tools_from_list
provider: Provider = await global_state_machine.get_provider.remote( provider_title)
provider: Provider = await global_state_machine.get_provider.remote(
provider_title
)
agent_factory = AgentFactory()
callables = load_tools_from_list(tools_list)
self.agent = agent_factory.create_agent(provider=provider,
model_id=model_id,
output_type=output_type,
system_prompt=system_prompt,
deps_type=SupervisoryNodeDeps,
agent_name="supervisory_node",
tools=callables)
self.agent = agent_factory.create_agent(
provider=provider,
model_id=model_id,
output_type=output_type,
system_prompt=system_prompt,
deps_type=SupervisoryNodeDeps,
agent_name="supervisory_node",
tools=callables,
)
@self.agent.system_prompt
async def dynamic_prompt(ctx: RunContext[SupervisoryNodeDeps]):
"""执行与 dynamic prompt 相关的核心业务流转操作。
该方法封装了具体的算法策略或状态控制逻辑,确保操作能够在事务上下文中被原子且一致地执行。
Args: ctx (RunContext[SupervisoryNodeDeps]): 参与 dynamic prompt 逻辑运算或数据构建的上下文依赖对象。
Returns: : 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。 """
Returns: : 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。"""
prompt = system_prompt + "\n\n"
prompt += (
f"=== 当前上下文 ===\n"
f"- 平台 (Platform): {ctx.deps.platform}\n"
f"- 用户名 (User): {ctx.deps.user_name}\n"
f"- 当前时间 (Time): {ctx.deps.time}\n"
f"- 可用工作流模板 (Available Templates): {ctx.deps.available_templates}\n"
)
# 修改 system_prompt 变量
prompt += (
"\n\n注意:你必须调用且只能调用一个函数(工具)来输出结果。"
"如果你想直接回复用户,请调用 ForUser;"
"如果你想移交给工作流,请调用 ForConsciousnessNode(若没有合适的模板,workflow_template 填 null"
"如果你想移交给工作流,请调用 ForConsciousnessNode。"
"严禁返回纯文本,必须使用工具格式!"
)
if ctx.deps.error_history:
@@ -113,16 +129,21 @@ class SupervisoryNode:
try:
result = await self._run(payload)
if isinstance(result, ForConsciousnessNode):
self.logger.info(f"SupervisoryNode: 任务已分配给工作流引擎处理,选用模板 [{result.workflow_template}]")
self.logger.info("SupervisoryNode: 任务已分配给工作流引擎处理")
if isinstance(payload, PretorEvent):
payload.context["workflow_template"] = result.workflow_template
try:
global_workflow_manager = ray_actor_hook("global_workflow_manager").global_workflow_manager
global_workflow_manager = ray_actor_hook(
"global_workflow_manager"
).global_workflow_manager
await global_workflow_manager.add_event.remote(payload)
workflow_running_engine = ray_actor_hook("workflow_running_engine").workflow_running_engine
workflow_running_engine = ray_actor_hook(
"workflow_running_engine"
).workflow_running_engine
await workflow_running_engine.put_event.remote(payload)
except Exception as e:
self.logger.error(f"SupervisoryNode: 无法将事件放入 WorkflowRunningEngine: {e}")
self.logger.error(
f"SupervisoryNode: 无法将事件放入 WorkflowRunningEngine: {e}"
)
return "抱歉,任务提交失败,系统内部错误。"
return f"任务已创建,准备创建工作流。原因:{result.reasoning}"
elif isinstance(result, ForUser):
@@ -144,7 +165,7 @@ class SupervisoryNode:
Returns:
ForUser对象,监控节点对于用户进行的简单回答
ForConsciousnessNode对象,监控节点将用户的请求判断为复杂任务,将PretorEvent传递给意识节点,并且给选择好的工作流模板
ForConsciousnessNode对象,监控节点将用户的请求判断为复杂任务,将PretorEvent传递给意识节点
"""
...
@@ -160,7 +181,9 @@ class SupervisoryNode:
"""
...
async def _run(self, payload: Union[PretorEvent, TerminationMessage]) -> Union[ForConsciousnessNode, ForUser]:
async def _run(
self, payload: Union[PretorEvent, TerminationMessage]
) -> Union[ForConsciousnessNode, ForUser]:
"""
_run方法,将payload转化为对llm发送的消息并发送
Args:
@@ -175,23 +198,15 @@ class SupervisoryNode:
message = payload.message
time_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
global_state_machine = ray_actor_hook("global_state_machine").global_state_machine
workflow_template_dict = await global_state_machine.get_all_workflow_templates.remote()
available_templates_str = "\n".join([f"- 名称: {k}, 描述/内容: {v}" for k, v in
workflow_template_dict.items()]) if workflow_template_dict else "暂无注册的工作流模板"
deps = SupervisoryNodeDeps(
platform=platform,
user_name=user_name,
time=time_str,
available_templates=available_templates_str
platform=platform, user_name=user_name, time=time_str
)
self.logger.debug("SupervisoryNode 开始生成 (启用原生 Pydantic-AI 重试)")
prompt_message = message
if isinstance(payload, TerminationMessage):
prompt_message = f"【工作流执行结束报告】\n请将以下技术报告转化为对用户的友好回复:\n{message}"
self.agent.retries = 3
result = await self.agent.run(prompt_message,
deps=deps)
result = await self.agent.run(prompt_message, deps=deps)
return result.output
except Exception as e:
self.logger.exception(f"SupervisoryNode 模型生成或解析最终失败: {str(e)}")
@@ -16,35 +16,46 @@ from pydantic import Field
from pretor.utils.agent_model import ResponseModel, DepsModel
from pydantic import BaseModel
class SupervisoryNodeResponse(ResponseModel):
"""SupervisoryNodeResponse 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
pass
class ForUser(SupervisoryNodeResponse):
"""ForUser 核心组件类。
这是一个领域数据模型或功能封装类,承载了 ForUser 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。 """
context: str = Field(..., description="对用户的回复,应当使用和蔼的语气进行回复。用于直接解答简单问题或返回最终报告。")
这是一个领域数据模型或功能封装类,承载了 ForUser 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。"""
context: str = Field(
...,
description="对用户的回复,应当使用和蔼的语气进行回复。用于直接解答简单问题或返回最终报告。",
)
class ForConsciousnessNode(SupervisoryNodeResponse):
"""ForConsciousnessNode 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
workflow_template: str | None = Field(default=None, description="选择的工作流模板的名称,用于处理复杂任务。若无需模板则为 None。")
reasoning: str = Field(..., description="选择将任务移交意识节点并选用该模板的简短原因。")
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
reasoning: str = Field(..., description="选择将任务移交意识节点的简短原因。")
class TerminationMessage(BaseModel):
"""TerminationMessage 核心组件类。
这是一个领域数据模型或功能封装类,承载了 TerminationMessage 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。 """
这是一个领域数据模型或功能封装类,承载了 TerminationMessage 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。"""
platform: str
user_name: str
message: str
class SupervisoryNodeDeps(DepsModel):
"""SupervisoryNodeDeps 核心组件类。
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。 """
这是一个系统执行节点类,作为多智能体架构中的独立处理单元。它能够接收工作流上下文,根据内置的大模型策略进行意图理解和自主决策,从而驱动特定阶段的任务闭环。"""
platform: str
user_name: str
time: str
retry_count: int = 0
error_history: str = ""
available_templates: str = "默认工作流 (default_workflow)"