从“岗位为中心”到“任务为中心”:企业级Agent Hub的架构演进

一、为什么"岗位中心"的架构撑不起Agent规模化

岗位中心的架构逻辑是:一个岗位对应一个Agent实例,Agent的能力、权限、知识库都绑定在这个岗位上。

这个模式在单Agent试点阶段够用。但当企业部署的Agent数量从几个增长到几十个、上百个时,三个问题集中暴露:

第一,能力重复建设。 财务Agent和HR Agent都需要"文档解析"能力,但各自建了一套。新增一个"合同审核Agent"时,又要再建一遍。

第二,权限无法随任务收敛。 一个Agent绑定在"财务专员"岗位上,就拥有了财务岗位的全部权限。但当它执行一个只需要"读应收账款"的任务时,仍然拥有"写付款记录"的权限------权限范围大于任务需要。

第三,任务跨Agent时无法编排。 一个"月度结账"任务需要财务Agent取数、审计Agent校验、报表Agent生成。三个Agent各自独立,没有统一的编排层,任务流转靠人工协调。

Agent Hub要解决的,就是把"能力、权限、编排"从岗位实例中解耦出来,围绕任务重新组织。

二、整体架构:四层Agent Hub

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                      任务接入层                                  │
│   用户指令 / 定时触发 / 事件触发 / 系统API                       │
│   任务解析 → 生成任务DAG → 分配trace_id                          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      能力注册中心                                │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ Agent注册    │  │ 技能注册     │  │ 连接器注册   │          │
│  │ 身份/能力描述│  │ 技能/参数    │  │ API/屏幕操作 │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      任务编排层                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ DAG调度      │  │ 状态管理     │  │ 异常恢复     │          │
│  │ 依赖/并行    │  │ 持久化/断点  │  │ 重试/降级    │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    权限与审计层                                  │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ 任务级权限   │  │ 字段级RBAC   │  │ 全链路审计   │          │
│  │ 随任务收敛   │  │ 数据范围隔离 │  │ 谁/什么/何时 │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
└─────────────────────────────────────────────────────────────────┘

核心设计原则:Agent是能力的载体,任务才是调度的单位。 Agent不绑定固定岗位,而是按任务被动态编排、按任务获得权限、按任务释放权限。

三、能力注册:Agent和技能的解耦

Agent Hub的第一件事,是让Agent的能力"可发现、可组合"。

3.1 Agent注册

每个Agent注册时声明自己的能力描述,而不是岗位名称。

python 复制代码
from dataclasses import dataclass, field
from typing import List

@dataclass
class AgentRegistration:
    """Agent注册信息:声明能力,不绑定岗位"""
    agent_id: str
    name: str
    capabilities: List[str]       # 能力标签:如["data_query", "report_gen"]
    skill_ids: List[str]          # 可加载的技能
    max_concurrency: int = 5      # 最大并发任务数
    supported_scenes: List[str] = field(default_factory=list)

class AgentRegistry:
    """Agent能力注册中心"""
    
    def __init__(self):
        self.agents = {}
    
    def register(self, reg: AgentRegistration):
        self.agents[reg.agent_id] = reg
    
    def find_by_capability(self, capability: str) -> List[AgentRegistration]:
        """按能力查找可用Agent"""
        return [
            a for a in self.agents.values()
            if capability in a.capabilities
        ]

3.2 技能注册

技能是比Agent更细的能力单元。一个技能可以被多个Agent加载。

python 复制代码
@dataclass
class SkillRegistration:
    """技能注册:可被多个Agent复用的能力单元"""
    skill_id: str
    name: str
    required_permissions: List[str]   # 执行该技能所需权限
    data_scope: dict                  # 数据范围要求
    handler: callable

class SkillRegistry:
    """技能注册中心"""
    
    def __init__(self):
        self.skills = {}
    
    def register(self, skill: SkillRegistration):
        self.skills[skill.skill_id] = skill
    
    def get(self, skill_id: str) -> SkillRegistration:
        return self.skills.get(skill_id)

解耦的价值:新增一个"合同审核Agent"时,不需要重写文档解析、OCR、条款比对等能力,直接加载已注册的技能即可。

四、任务编排:DAG调度与状态管理

Agent Hub的核心是任务编排层。它接收任务请求,生成DAG,调度Agent执行,管理执行状态。

python 复制代码
from enum import Enum
from dataclasses import dataclass, field
from typing import List, Optional
import asyncio

class TaskStatus(Enum):
    PENDING = "pending"
    RUNNING = "running"
    SUCCESS = "success"
    FAILED = "failed"

@dataclass
class TaskNode:
    """任务节点:一个Agent执行一个技能"""
    node_id: str
    agent_id: str
    skill_id: str
    params: dict
    depends_on: List[str] = field(default_factory=list)
    status: TaskStatus = TaskStatus.PENDING
    result: Optional[dict] = None

class TaskOrchestrator:
    """任务编排器:按DAG调度Agent执行"""
    
    def __init__(self, agent_registry, skill_registry, state_store):
        self.agents = agent_registry
        self.skills = skill_registry
        self.state = state_store
    
    async def execute(self, nodes: List[TaskNode], trace_id: str) -> dict:
        results = {}
        ready = [n for n in nodes if not n.depends_on]
        
        while ready:
            # 并行执行所有就绪节点
            batch = ready[:]
            ready = []
            
            tasks = [self._run_node(n, trace_id) for n in batch]
            batch_results = await asyncio.gather(*tasks, return_exceptions=True)
            
            for node, res in zip(batch, batch_results):
                if isinstance(res, Exception):
                    node.status = TaskStatus.FAILED
                    results[node.node_id] = {"error": str(res)}
                else:
                    node.status = TaskStatus.SUCCESS
                    node.result = res
                    results[node.node_id] = res
            
            # 释放依赖,加入下一批
            for n in nodes:
                if n.status != TaskStatus.PENDING:
                    continue
                deps_done = all(
                    self._get_node(nodes, d).status == TaskStatus.SUCCESS
                    for d in n.depends_on
                )
                if deps_done:
                    ready.append(n)
        
        return results
    
    async def _run_node(self, node: TaskNode, trace_id: str) -> dict:
        """执行单个任务节点"""
        skill = self.skills.get(node.skill_id)
        if not skill:
            raise ValueError(f"Skill {node.skill_id} not found")
        
        # 任务级权限校验
        if not self._check_task_permission(node, skill):
            raise PermissionError(f"Agent {node.agent_id} lacks permission")
        
        # 持久化状态,支持断点恢复
        self.state.save(trace_id, node.node_id, {"status": "running"})
        
        result = await skill.handler(**node.params)
        self.state.save(trace_id, node.node_id, {"status": "success", "result": result})
        return result

五、权限收敛:权限跟着任务走,不跟着Agent走

这是Agent Hub和"岗位中心"架构最本质的区别。

岗位中心:Agent绑定岗位,拥有岗位的全部权限,无论执行什么任务。

任务中心:Agent执行任务时,只获得该任务所需的权限;任务结束,权限收回。

python 复制代码
class TaskScopedPermission:
    """任务级权限:按任务动态收敛"""
    
    def __init__(self, permission_store):
        self.store = permission_store
    
    def grant_for_task(self, agent_id: str, task_id: str, 
                       skill: SkillRegistration, user_context: dict):
        """为任务临时授予权限"""
        # 1. 校验Agent是否有该技能的静态授权
        if not self.store.agent_has_skill(agent_id, skill.skill_id):
            raise PermissionError("Agent not authorized for this skill")
        
        # 2. 按任务数据范围收窄权限
        task_scope = {
            "org_id": user_context["org_id"],
            "tables": skill.data_scope.get("tables", []),
            "row_filter": f"org_id = '{user_context['org_id']}'",
            "expires_at": now_ms() + 3600_000  # 任务级权限1小时过期
        }
        
        # 3. 生成临时权限令牌
        token = self.store.create_task_token(
            agent_id=agent_id,
            task_id=task_id,
            scope=task_scope
        )
        return token
    
    def revoke_after_task(self, token: str):
        """任务结束后收回权限"""
        self.store.revoke_token(token)

关键设计:权限的有效期是"任务周期",而不是"Agent生命周期"。Agent在任务A中获得的权限,不能带到任务B。

沈管家AI数字员工在权限设计上采用了字段级RBAC模型,Agent实例拥有独立身份,权限可按任务范围精确配置。其任务引擎在任务创建时注入组织过滤条件,任务结束后权限自动收敛。这种"权限随任务走"的设计,是支撑任务中心架构的工程基础。

六、审计:从"岗位操作日志"到"任务轨迹"

岗位中心的审计是"按Agent记录"------某个Agent在什么时间做了什么。

任务中心的审计是"按任务轨迹记录"------一个任务从发起到完成,经过了哪些Agent、调用了哪些技能、访问了哪些数据、每一步的权限校验结果是什么。

python 复制代码
def log_task_trace(trace_id: str, node: TaskNode, 
                   permission_token: str, latency_ms: int):
    """记录任务轨迹:用于审计和复盘"""
    entry = {
        "trace_id": trace_id,
        "node_id": node.node_id,
        "agent_id": node.agent_id,
        "skill_id": node.skill_id,
        "permission_token": hash_token(permission_token),
        "status": node.status.value,
        "latency_ms": latency_ms,
        "timestamp": now_ms()
    }
    audit_store.append(entry)

审计的价值在于:当某个任务出了问题,能追溯到具体是哪个Agent、哪一步、哪个权限校验环节出了错,而不是笼统地归因于"某个岗位的Agent"。

七、工程实践要点

Agent不绑定岗位。 Agent是能力载体,注册时声明能力,不声明岗位。任务需要什么能力,就调度具备该能力的Agent。

技能可复用。 文档解析、OCR、数据查询这些通用能力,注册一次,多个Agent加载。避免重复建设。

权限按任务收敛。 Agent执行任务时获得临时权限,任务结束后收回。权限范围按任务的数据需求收窄,不继承岗位的全量权限。

状态持久化。 每个节点的执行状态实时写入存储,任务失败可从断点恢复,而不是从头重跑。

审计按任务轨迹。 审计记录以trace_id串联,覆盖任务全链路,而不是分散在各个Agent的日志里。

FAQ

Q1:Agent Hub和普通的任务调度系统有什么区别?

A:普通调度系统调度的是"函数"或"容器",Agent Hub调度的是"具备语义理解和工具调用能力的Agent"。它额外处理:Agent能力的动态发现、任务级权限的授予与回收、跨Agent的状态传递。

Q2:Agent Hub会不会成为单点瓶颈?

A:编排层本身可以做水平扩展。任务状态持久化在外部存储,多个编排实例可以并行处理不同任务。关键设计是"编排无状态、状态在存储"。

Q3:任务级权限和岗位级权限,哪个更安全?

A:任务级权限更安全。岗位级权限是"全量授予",Agent在任何时候都拥有岗位的全部权限。任务级权限是"按需授予",Agent只在执行特定任务时获得特定范围的权限,攻击面更小。

Q4:中小企业需要Agent Hub吗?

A:当Agent数量少于5个、任务链路简单时,可以先用简单的编排脚本。当Agent数量增长、任务开始跨Agent时,引入Agent Hub的边际收益会快速上升。

Q5:沈管家AI数字员工在Agent Hub架构中能提供什么支持?

A:沈管家AI数字员工的技能插件架构支持能力按任务加载,字段级RBAC权限模型支持权限按任务范围收敛,任务执行引擎支持DAG编排和断点恢复,全链路审计日志按trace_id追溯。具体配置方式可访问官网了解。


你在设计多Agent系统时,遇到过哪些编排或权限上的挑战?是任务状态难保持、权限边界难收敛,还是审计链路不完整?欢迎在评论区交流你的方案和踩坑经验。

相关推荐
fly-iot1 小时前
【下一个 AI 方向】:中小企业的数字化建设,物联网解决方案思考,使用开源项目快速搭建降低成本。
人工智能·物联网
方芯半导体1 小时前
2026工业机器人控制芯片赛道:竞争格局与关键选型指标深度解析
大数据·人工智能·机器人
阡陌数智1 小时前
Mistral Large 4 深度拆解:细粒度 MoE 架构与安全 Agent 工程实战
安全·架构
科创致远1 小时前
科创致远 ESOP 赋能车间图纸全维管理实战
大数据·人工智能·制造·精益工程
技灵AI2 小时前
AI 口播视频提示词怎么写?让人物讲解和产品展示更自然
人工智能·音视频
小林ixn2 小时前
FastAPI + LangChain 实战:从 0 到 1 打造高性能 AI 后端服务
人工智能·langchain·fastapi
forest_092 小时前
Agent 系列 21|部署、发布与运维:把 Agent 变成一个能上线、能放量、能撤回的服务
人工智能·机器学习·架构·prompt·agi
企业数字化笔记2 小时前
AI视频增强后画质怎么验收?插值基线、伪细节与帧间闪烁的检查方法
人工智能·算法·音视频
十@八九2 小时前
VS Code 接入 AMD Vivado 2026.1 AI 助手:从 VSIX 到 MCP 实战
人工智能·fpga·vs code·vivado·mcp