首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Agentic AI:智能的行动化及其代价

Agentic AI:智能的行动化及其代价

原创
作者头像
用户12502671
发布于 2026-09-26 18:14:56
发布于 2026-09-26 18:14:56
440
举报

一、一个根本性的转变

2026年,AI领域最深刻的转变不是模型又大了多少,而是AI开始从“生成内容”走向“采取行动”。这个转变看似只是能力边界的扩展,实则是一次范式迁移——它改变了AI系统的工程本质、安全边界和评估标准。

生成式AI的错误是文本层面的:一段话不通顺、一张图有瑕疵、一个回答不准确。这些错误可以被忽略、被修正、被重新生成。Agentic AI的错误是现实层面的:删除了不该删的文件、发送了不该发的邮件、执行了不该执行的交易、修改了不该修改的配置。这些错误有后果,有些后果不可逆。

这个区别不是程度上的,而是性质上的。当AI从“回答者”变成“行动者”,工程的核心问题从“能不能做到”变成了“该不该做”和“错了怎么办”。Agentic AI的真正挑战不在于让模型更聪明,而在于让行动可问责、可回滚、可审计。

二、Agent Loop:行动的最小闭环

理解Agentic AI必须从它的核心循环开始。一个Agent本质上是一个循环:感知当前状态,规划下一步动作,执行动作,观察结果,反思并调整。这个循环看起来简单,但每一个环节都隐藏着工程复杂度。

代码语言:javascript
复制
# agent_loop.py — 一个最小化的Agent循环
from dataclasses import dataclass, field
from typing import Any, Callable

@dataclass
class AgentState:
    goal: str
    history: list[dict] = field(default_factory=list)
    memory: dict = field(default_factory=dict)
    step_count: int = 0

class Agent:
    def __init__(self, model, tools: dict[str, Callable], max_steps: int = 20):
        self.model = model
        self.tools = tools
        self.max_steps = max_steps
        self.state: AgentState | None = None

    def run(self, goal: str) -> dict:
        self.state = AgentState(goal=goal)

        while self.state.step_count < self.max_steps:
            # 1. 感知:构建当前上下文
            context = self._build_context()

            # 2. 规划:模型决定下一步
            decision = self.model.decide(
                goal=self.state.goal,
                context=context,
                available_tools=list(self.tools.keys()),
            )

            # 3. 终止条件:模型认为任务完成
            if decision.action == "finish":
                return {"status": "completed", "result": decision.result}

            # 4. 执行:调用工具
            tool_name = decision.action
            if tool_name not in self.tools:
                self.state.history.append({
                    "error": f"Unknown tool: {tool_name}",
                    "step": self.state.step_count,
                })
                self.state.step_count += 1
                continue

            try:
                result = self.tools[tool_name](**decision.params)
                self.state.history.append({
                    "action": tool_name,
                    "params": decision.params,
                    "result": str(result)[:500],
                    "step": self.state.step_count,
                })
            except Exception as e:
                self.state.history.append({
                    "action": tool_name,
                    "error": str(e),
                    "step": self.state.step_count,
                })

            # 5. 反思:检查是否偏离目标
            if self._drifted():
                self.state.memory["correction"] = (
                    f"注意:当前执行已偏离原始目标。原始目标:{self.state.goal}"
                )

            self.state.step_count += 1

        return {"status": "max_steps_reached", "state": self.state}

    def _build_context(self) -> str:
        recent = self.state.history[-5:]
        lines = []
        for h in recent:
            if "error" in h:
                lines.append(f"Step {h['step']}: ERROR — {h['error']}")
            else:
                lines.append(
                    f"Step {h['step']}: {h['action']}({h['params']}) "
                    f"→ {h['result']}"
                )
        if "correction" in self.state.memory:
            lines.append(f"[SYSTEM] {self.state.memory['correction']}")
        return "\n".join(lines)

    def _drifted(self) -> bool:
        # 简化实现:检查最近动作是否与目标语义相关
        if len(self.state.history) < 3:
            return False
        recent = " ".join(
            h.get("action", "") for h in self.state.history[-3:]
        )
        return self.model.semantic_similarity(self.state.goal, recent) < 0.3

这个循环的关键设计不在实现细节,而在结构:每一步动作都被记录,每一次错误都被捕获,偏离检测在每一步之后执行。没有这些机制,Agent就是一个随机漫步的模型——它可能碰巧完成任务,也可能在错误的方向上越走越远。

三、工具使用:行动能力的来源与风险

Agentic AI的行动能力来自工具。模型本身只能生成文本,只有通过工具调用,它才能读写文件、发送请求、执行命令、操作数据库。但工具也是风险的主要来源。

一个设计良好的工具接口需要回答几个问题:这个工具在什么条件下可以被调用?调用需要什么权限?调用失败时如何回滚?调用的结果如何被验证?

MCP(Model Context Protocol)在2026年成为工具接入的事实标准,它的核心设计理念是解耦:模型不需要知道工具的实现细节,只需要知道工具的存在和调用方式。但MCP解决的是“如何调用”,不解决“该不该调用”。后者属于Harness的Control层——权限策略和审批机制。

代码语言:javascript
复制
# tool_guard.py — 工具调用的权限检查层
from dataclasses import dataclass
from enum import Enum

class RiskLevel(Enum):
    SAFE = "safe"           # 只读操作,自动批准
    MODERATE = "moderate"   # 有副作用,需要确认
    DANGEROUS = "dangerous" # 不可逆操作,需要显式授权

@dataclass
class ToolPolicy:
    risk: RiskLevel
    allowed_paths: list[str] | None = None
    requires_approval: bool = False
    reversible: bool = True

class ToolGuard:
    def __init__(self):
        self.policies: dict[str, ToolPolicy] = {
            "read_file": ToolPolicy(risk=RiskLevel.SAFE),
            "write_file": ToolPolicy(
                risk=RiskLevel.MODERATE,
                allowed_paths=["src/", "tests/", "docs/"],
                requires_approval=True,
            ),
            "execute_sql": ToolPolicy(
                risk=RiskLevel.DANGEROUS,
                requires_approval=True,
                reversible=False,
            ),
            "delete_file": ToolPolicy(
                risk=RiskLevel.DANGEROUS,
                requires_approval=True,
                reversible=False,
            ),
        }

    def check(self, tool_name: str, params: dict) -> tuple[bool, str]:
        policy = self.policies.get(tool_name)
        if not policy:
            return False, f"Tool '{tool_name}' not registered"

        # 路径检查
        if policy.allowed_paths and "path" in params:
            path = params["path"]
            if not any(path.startswith(p) for p in policy.allowed_paths):
                return False, (
                    f"Path '{path}' outside allowed scope: "
                    f"{policy.allowed_paths}"
                )

        # 审批检查
        if policy.requires_approval and not params.get("_approved"):
            return False, f"Tool '{tool_name}' requires explicit approval"

        # 不可逆操作额外警告
        if not policy.reversible and not params.get("_confirmed_irreversible"):
            return False, (
                f"Tool '{tool_name}' is irreversible. "
                f"Set '_confirmed_irreversible' to proceed."
            )

        return True, ""

这个检查层的价值在于:它把人类的安全判断变成了可执行的代码。当模型请求写入一个不在允许路径内的文件时,系统会在执行前拦截;当模型请求执行一个不可逆的数据库操作时,系统会要求显式确认。这些约束不是写在文档里让模型“尽量遵守”,而是写在代码里强制执行。

四、记忆与长时程任务:真正致命的失败模式

当Agent从“单次任务”进入“项目级持续开发”,失败的性质发生了根本变化。对633,000行代码库、持续数月使用Agent的研究记录了四种致命的记忆失败模式。

知识丢失是最隐蔽的一种。上下文压缩会“总结掉”长弧线的连接组织——计划幸存下来了,但“为什么做这个计划”丢失了。Agent恢复时语言流畅但微妙地失去了方向感。重复工作紧随其后:Agent反复提议已经构建完成的子系统,即使相关设计文档就在上下文中。上下文退化是第三种——对前两种问题的朴素补救是注入更多检索到的上下文,但这在反方向上同样失败:仅有时相关的注入块训练人类操作者(和Agent)快速略过它们,一旦通道被学习为噪音,它比不存在更糟。静默记忆死亡是第四种——记忆系统本身悄悄退化或死亡,而所有人都继续信任它。

这些失败模式指向一个工程结论:长时程Agent的可靠性不取决于模型的推理能力,而取决于记忆子系统的工程化程度。需要的是带鉴别性失败模式的会话启动健康门、设计为“没有枚举的失败模式能不被记录地通过”的心跳遥测,以及借鉴SRE实践的告警疲劳预算。

代码语言:javascript
复制
# memory_manager.py — 带压缩和健康检查的记忆管理
from dataclasses import dataclass, field
from datetime import datetime
from typing import Any

@dataclass
class MemoryEntry:
    content: str
    importance: float  # 0.0 到 1.0
    timestamp: datetime
    tags: list[str] = field(default_factory=list)
    verified: bool = False

class MemoryManager:
    def __init__(self, max_entries: int = 1000, compression_threshold: int = 800):
        self.entries: list[MemoryEntry] = []
        self.max_entries = max_entries
        self.compression_threshold = compression_threshold
        self.health_log: list[dict] = []

    def add(self, content: str, importance: float = 0.5, tags: list[str] | None = None):
        entry = MemoryEntry(
            content=content,
            importance=importance,
            timestamp=datetime.now(),
            tags=tags or [],
        )
        self.entries.append(entry)
        if len(self.entries) > self.compression_threshold:
            self._compress()

    def _compress(self):
        """压缩记忆:保留高重要性内容,合并低重要性内容"""
        # 按重要性排序,保留前60%
        sorted_entries = sorted(
            self.entries, key=lambda e: e.importance, reverse=True
        )
        keep_count = int(len(sorted_entries) * 0.6)
        kept = sorted_entries[:keep_count]

        # 低重要性内容合并为摘要
        low_importance = sorted_entries[keep_count:]
        if low_importance:
            summary = self._summarize(low_importance)
            kept.append(MemoryEntry(
                content=f"[COMPRESSED] {summary}",
                importance=0.3,
                timestamp=datetime.now(),
                tags=["compressed"],
            ))

        self.entries = kept
        self._health_check()

    def _summarize(self, entries: list[MemoryEntry]) -> str:
        """实际实现中会调用模型生成摘要"""
        return f"合并了 {len(entries)} 条低重要性记忆"

    def _health_check(self):
        """记忆系统健康检查"""
        total = len(self.entries)
        compressed = sum(1 for e in self.entries if "compressed" in e.tags)
        unverified = sum(1 for e in self.entries if not e.verified)

        health = {
            "total_entries": total,
            "compressed_ratio": compressed / max(total, 1),
            "unverified_ratio": unverified / max(total, 1),
            "timestamp": datetime.now().isoformat(),
        }
        self.health_log.append(health)

        # 健康告警:压缩比例过高意味着信息损失严重
        if health["compressed_ratio"] > 0.4:
            health["warning"] = (
                "High compression ratio detected. "
                "Context coherence may be degraded."
            )

    def recall(self, query: str, top_k: int = 5) -> list[MemoryEntry]:
        """检索相关记忆:按重要性和时间衰减排序"""
        now = datetime.now()
        scored = []
        for entry in self.entries:
            # 简化的相关性评分:实际中会用嵌入向量
            relevance = self._relevance(query, entry.content)
            # 时间衰减:越近的记忆权重越高
            age_hours = (now - entry.timestamp).total_seconds() / 3600
            time_decay = 1.0 / (1.0 + age_hours * 0.01)
            score = relevance * entry.importance * time_decay
            scored.append((score, entry))

        scored.sort(key=lambda x: x[0], reverse=True)
        return [entry for _, entry in scored[:top_k]]

    def _relevance(self, query: str, content: str) -> float:
        """简化实现:实际中会用嵌入模型计算语义相似度"""
        query_words = set(query.lower().split())
        content_words = set(content.lower().split())
        if not query_words:
            return 0.0
        return len(query_words & content_words) / len(query_words)

这个记忆管理器的核心设计决策是:压缩不是简单的截断,而是按重要性分层处理;健康检查不是可选的,而是压缩流程的内置环节;检索不是单纯的相关性排序,而是结合了重要性和时间衰减。这些设计选择直接回应了前面提到的四种失败模式。

五、多智能体协作:从单体到联邦

当任务复杂度超过单个Agent的处理能力时,多智能体协作成为必然。但多Agent系统引入了一个新的工程问题:如何协调多个自主实体的行为,使它们不互相干扰、不产生矛盾、不陷入死锁。

一个有效的多Agent架构通常采用角色分工模式:探索者负责理解问题空间,实现者负责执行具体任务,审查者负责验证结果,仲裁者负责解决冲突。每个角色有独立的上下文和工具集,通过标准化的消息协议通信。

代码语言:javascript
复制
# multi_agent.py — 简化的多智能体协作框架
from dataclasses import dataclass, field
from enum import Enum
from typing import Any

class AgentRole(Enum):
    EXPLORER = "explorer"       # 理解问题,收集信息
    IMPLEMENTER = "implementer" # 执行具体任务
    REVIEWER = "reviewer"       # 验证结果
    ARBITER = "arbiter"         # 解决冲突

@dataclass
class Message:
    sender: str
    role: AgentRole
    content: str
    metadata: dict = field(default_factory=dict)

@dataclass
class SharedContext:
    goal: str
    artifacts: dict[str, Any] = field(default_factory=dict)
    messages: list[Message] = field(default_factory=list)
    conflicts: list[dict] = field(default_factory=list)

class MultiAgentSystem:
    def __init__(self, model, tools: dict[str, Any]):
        self.model = model
        self.tools = tools
        self.context = SharedContext(goal="")

    def run(self, goal: str) -> dict:
        self.context = SharedContext(goal=goal)

        # 阶段1:探索
        exploration = self._run_agent(
            role=AgentRole.EXPLORER,
            prompt=(
                f"分析目标:{goal}。"
                f"识别需要修改的模块、依赖关系和潜在风险。"
                f"不要执行任何修改操作。"
            ),
        )
        self.context.artifacts["exploration"] = exploration

        # 阶段2:实现
        implementation = self._run_agent(
            role=AgentRole.IMPLEMENTER,
            prompt=(
                f"基于以下分析实现功能:\n{exploration}\n"
                f"目标:{goal}"
            ),
        )
        self.context.artifacts["implementation"] = implementation

        # 阶段3:审查
        review = self._run_agent(
            role=AgentRole.REVIEWER,
            prompt=(
                f"审查以下实现是否满足目标:\n{implementation}\n"
                f"原始目标:{goal}\n"
                f"检查:正确性、完整性、潜在副作用。"
            ),
        )
        self.context.artifacts["review"] = review

        # 阶段4:如果有冲突,仲裁
        if self._has_conflict(review):
            arbitration = self._run_agent(
                role=AgentRole.ARBITER,
                prompt=(
                    f"解决以下冲突:\n"
                    f"实现:{implementation}\n"
                    f"审查意见:{review}\n"
                    f"目标:{goal}"
                ),
            )
            self.context.artifacts["arbitration"] = arbitration

        return {
            "status": "completed",
            "artifacts": self.context.artifacts,
            "conflicts_resolved": len(self.context.conflicts),
        }

    def _run_agent(self, role: AgentRole, prompt: str) -> str:
        # 每个角色有独立的系统提示和工具子集
        role_tools = self._tools_for_role(role)
        response = self.model.generate(
            system=self._system_prompt(role),
            prompt=prompt,
            tools=role_tools,
        )
        self.context.messages.append(Message(
            sender=role.value,
            role=role,
            content=response,
        ))
        return response

    def _tools_for_role(self, role: AgentRole) -> list[str]:
        mapping = {
            AgentRole.EXPLORER: ["read_file", "search_code", "list_files"],
            AgentRole.IMPLEMENTER: ["read_file", "write_file", "execute_code"],
            AgentRole.REVIEWER: ["read_file", "search_code", "run_tests"],
            AgentRole.ARBITER: ["read_file", "search_code"],
        }
        return mapping.get(role, [])

    def _system_prompt(self, role: AgentRole) -> str:
        prompts = {
            AgentRole.EXPLORER: (
                "你是探索者。你的职责是理解问题空间,"
                "识别关键模块和依赖。不要修改任何文件。"
            ),
            AgentRole.IMPLEMENTER: (
                "你是实现者。你的职责是执行具体任务。"
                "基于探索者的分析进行实现,不要重新分析整个系统。"
            ),
            AgentRole.REVIEWER: (
                "你是审查者。你的职责是验证结果。"
                "你没有参与实现,所以能从独立视角发现问题。"
            ),
            AgentRole.ARBITER: (
                "你是仲裁者。你的职责是解决冲突。"
                "基于原始目标做出判断,不要偏向任何一方。"
            ),
        }
        return prompts.get(role, "")

    def _has_conflict(self, review: str) -> bool:
        # 简化判断:实际中会用模型评估
        conflict_keywords = ["不满足", "错误", "遗漏", "风险", "冲突"]
        return any(kw in review for kw in conflict_keywords)

这个多Agent框架的核心设计原则是:每个角色有独立的系统提示和工具子集,审查者不参与实现,仲裁者不偏向任何一方。这些约束不是“建议”,而是通过工具权限和提示词设计强制执行的。当审查者只能读取文件和运行测试、不能修改代码时,它的独立性就有了工程保障。

六、评估与可观测性:行为轨迹比结果更重要

Agentic AI的评估不能只看任务完成率。一个Agent可能“碰巧”完成了任务,但过程中执行了危险操作、绕过了安全约束、产生了不可维护的代码。行为轨迹的质量,比最终结果更能反映Agent的可靠性。

可观测性需要覆盖几个层面:每一步动作的输入输出、工具调用的成功与失败、上下文窗口的使用情况、偏离检测的触发记录、审批流程的完整日志。这些数据不仅用于事后审计,更用于事中干预——当Agent的行为轨迹显示出危险模式时,系统应该能够实时告警甚至暂停执行。

七、工程边界与伦理底线

Agentic AI不是万能的。它不适合那些后果不可逆且无法审计的场景。金融交易、医疗决策、关键基础设施控制——这些领域需要的是“人类在环”的决策架构,而不是完全自主的Agent。

更根本的边界是:Agentic AI不解决“目标是否正确”的问题。如果目标本身是错的,Agent会忠实地、高效地、持续地执行错误的目标。Agentic AI的价值在于让正确的目标被可靠地执行,而不是替代人类对目标的判断。

结语

Agentic AI的本质不是“更聪明的模型”,而是“能改变世界的智能”。这个转变带来的不是能力的简单延伸,而是工程范式的根本迁移:从生成到行动,从对话到执行,从文本到后果。

当智能开始行动,工程必须学会负责。这个责任体现在每一个工具调用的权限检查里,每一次记忆压缩的健康告警里,每一轮多Agent协作的仲裁逻辑里。Agentic AI的最终考验不是它能否完成任务,而是它能否在完成任务的过程中,始终知道自己不该做什么。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、一个根本性的转变
  • 二、Agent Loop:行动的最小闭环
  • 三、工具使用:行动能力的来源与风险
  • 四、记忆与长时程任务:真正致命的失败模式
  • 五、多智能体协作:从单体到联邦
  • 六、评估与可观测性:行为轨迹比结果更重要
  • 七、工程边界与伦理底线
  • 结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档