首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >深入拆解PentAGI:全栈AI自动化渗透测试平台架构解析

深入拆解PentAGI:全栈AI自动化渗透测试平台架构解析

作者头像
Ms08067安全实验室
发布2026-06-24 12:06:37
发布2026-06-24 12:06:37
330
举报

文章来源|MS08067 AI安全应用知识星球

作者:小玉玉

在 AI 驱动的安全测试领域,PentAGI 是一个不容忽视的名字。作为一款用 Go 语言构建的全栈 AI 渗透测试平台,它通过多智能体编排、三层记忆系统、10+ LLM 提供商插件式集成和 Docker 沙箱执行等前沿设计,构建了一套从目标侦察到漏洞利用再到报告生成的全自动安全测试流水线。本文将深入拆解其技术架构,剖析工程实现的关键细节。


系统架构与核心设计

PentAGI(Penetration testing Artificial General Intelligence)的核心理念是用多智能体系统取代单一大模型对话。它不是把 LLM 当成一个智能聊天框,而是构建了一个由 15 个专业 Agent 角色组成的协作网络,每个角色各司其职,通过工具调用和消息传递协同完成渗透测试任务。

系统的执行模型从顶层到底层分为四层:

层级

职责

生命周期

Flow(流程)

一个完整的渗透测试会话或目标

active / completed / failed

Task(任务)

一次分析步骤(如端口扫描)

pending / running / done / failed

SubTask(子任务)

一个具体的可执行单元

queued / running / completed / failed

Agent Chain(代理链)

Agent 协作执行子任务

动态编排,结束后回收

这种分层设计的价值在于:将一次渗透测试分解为可追踪、可审计、可恢复的执行单元,避免了大模型单次对话上下文溢出和难以复现的问题。

在 Go 后端中,这些类型通过 GraphQL Schema 精确定义。下面是从 schema.graphqls(位于 backend/pkg/graph/)中摘录的 Flow、Task、SubTask 类型定义。注意 Subtask 绑定了一个 taskId 外键,而 Task 又通过 flowId 指向所属的 Flow——这种双向关联使得系统可以高效地执行「给定 Flow,查询所有 Task 及其 SubTask」的树形遍历操作:

代码语言:javascript
复制
# 文件位置: backend/pkg/graph/schema.graphqls
# GraphQL 类型定义 —— 核心执行模型的骨架

# ==================== 核心实体 ====================

type Flow {
  id: ID!            # 全局唯一标识
  title: String!     # 用户为本次渗透测试起的名称
  status: StatusType! # 生命周期: active / completed / failed
  terminals: [Terminal!]   # 沙箱终端会话列表
  provider: Provider!      # 绑定的 LLM 提供商
  createdAt: Time!          # 创建时间
  updatedAt: Time!          # 最近一次更新时间
}

type Task {
  id: ID!            # 全局唯一标识
  title: String!     # 任务名称,如"端口扫描"
  status: StatusType! # pending / running / done / failed
  input: String!     # 用户的输入描述(从 Flow 传递过来)
  result: String!    # 执行结果摘要(Agent 链完成后填充)
  flowId: ID!        # 所属 Flow 的外键
  subtasks: [Subtask!]  # 该任务下的所有子任务
  createdAt: Time!
  updatedAt: Time!
}

type Subtask {
  id: ID!            # 全局唯一标识
  status: StatusType! # queued / running / completed / failed
  title: String!     # 子任务标题
  description: String! # 详细描述,包含执行目标和注意事项
  result: String!    # 执行结果,由 Reporter Agent 填充
  taskId: ID!        # 所属 Task 的外键
  createdAt: Time!
  updatedAt: Time!
}

值得注意的是,Subtask 的 description 字段并非简单的标题补充——Generator 和 Refiner Agent 在生成子任务列表时,会将执行策略、目标细节、注意事项都写入该字段,作为后续 Pentester Agent 的执行「剧本」。这样设计的好处是:决策与执行分离——规划阶段生成的剧本完整保存在 Subtask 中,执行阶段无需反复调用 LLM 重新理解目标,大大减少了 token 消耗。

在 Web UI 中,任务管理界面以树形结构清晰展示了 Flow → Task → SubTask 的层级关系。下方截图展示了一个渗透测试 Flow 的内部视图:每个 Task 标题下方关联着多个 SubTask,右侧面板展示了当前任务的详细信息和执行进度。这种可视化的任务拆解方式让测试负责人可以一目了然地掌握全局执行状态:

图1:任务管理界面——Flow 内 Task 与 SubTask 的树形展示

代码语言:javascript
复制
flowchart TB
    subgraph Flow层
        F[Flow 渗透测试会话]
    end

    subgraph Task层
        T1[Task 信息收集]
        T2[Task 漏洞识别]
        T3[Task 利用验证]
        T4[Task 报告生成]
    end

    subgraph SubTask层
        ST1[SubTask 端口扫描]
        ST2[SubTask 服务识别]
        ST3[SubTask CVE匹配]
        ST4[SubTask 漏洞利用]
    end

    subgraph Agent链
        A1[Primary Agent<br/>主协调者]
        A2[Researcher<br/>研究员]
        A3[Pentester<br/>渗透者]
        A4[Reporter<br/>报告员]
    end

    F --> T1
    F --> T2
    F --> T3
    F --> T4
    T1 --> ST1
    T1 --> ST2
    T2 --> ST3
    T3 --> ST4
    ST1 --> A1 --> A2
    ST2 --> A1 --> A3
    ST3 --> A1 --> A3
    ST4 --> A1 --> A4

图2:四层执行模型架构

架构的高度抽象让我们看到了 PentAGI 的整体轮廓,但要真正理解这个平台为何能高效运作,还需要深入其工程底层,逐一拆解支撑这套执行模型的七个关键技术面。接下来,我们从技术栈选型开始,逐步深入到多 Agent 系统、工具编排、记忆体系等核心模块。


核心技术与工程架构

一、技术栈全景

PentAGI 的技术选型体现了对性能和工程化的极致追求:

层级

技术方案

选型理由

后端语言

Go 1.24

高并发、低资源占用、单二进制部署,适合多 Agent 并行

前端框架

React 19 + TypeScript + Vite + SWC

现代 SPA,类型安全,开发体验好

LLM 框架

langchaingo(vxcontrol 分支)

Go 生态的 LangChain 替代,支持流式推理和嵌入

API 协议

GraphQL(gqlgen)+ REST(Gin)+ WebSocket

GraphQL 订阅实现实时 Agent 状态推送

数据库

PostgreSQL + pgvector

关系数据 + 向量语义搜索一体

知识图谱

Neo4j + Graphiti

实体关系追踪,跨会话上下文理解

容器引擎

Docker SDK

隔离执行所有渗透操作

可观测性

Langfuse + OpenTelemetry + Grafana

LLM 调用追踪 + 系统指标全链路监控

登录 PentAGI 后,首先映入眼帘的是如下主界面。左侧为功能导航栏,中央为 Flow 列表面板,每个 Flow 代表一次完整的渗透测试会话。界面的核心交互区域采用了标准的「列表 + 详情」布局,用户可以在侧边栏快速切换不同 Flow,通过右上角的搜索和筛选快速定位目标测试任务:

图3:PentAGI Web 主界面——Flow 列表与导航

有了这些技术作为底座,PentAGI 得以构建其最核心的竞争力——多智能体协作系统。不同于市面上将单个 LLM 包装成一个「万能 Agent」的做法,PentAGI 选择了一条更工程化的路径:将渗透测试中不同阶段的能力拆解为 15 个专业化角色,让它们像人类红队一样分工协作。

二、多智能体系统:15 个专业角色的协作网络

PentAGI 最核心的工程创新在于其专业化多 Agent 架构。系统预定义了 15 个 Agent 角色,通过 cast 消息传递抽象进行通信,每个角色拥有专属的工具权限和系统提示词:

代码语言:javascript
复制
flowchart LR
    subgraph 协调层
        PA[Primary Agent<br/>主引导者]
        AS[Assistant<br/>交互助手]
    end

    subgraph 规划层
        GEN[Generator<br/>任务生成器]
        REF[Refiner<br/>任务优化器]
        ADV[Adviser<br/>顾问]
        PLA[Planner<br/>规划器]
    end

    subgraph 执行层
        PEN[Pentester<br/>渗透执行者]
        COD[Coder<br/>代码编写者]
        SEA[Searcher<br/>信息搜索者]
        ENR[Enricher<br/>上下文丰富者]
        INS[Installer<br/>工具安装者]
    end

    subgraph 记忆与反思层
        MEM[Memorist<br/>记忆管理者]
        REFL[Reflector<br/>反思校验者]
        SUM[Summarizer<br/>摘要生成者]
        TC[Tool Call Fixer<br/>工具调用修复者]
    end

    subgraph 输出层
        REP[Reporter<br/>报告生成者]
    end

    PA --> GEN
    GEN --> REF
    REF --> PEN & COD & SEA
    SEA --> ENR
    PA --> AS
    PEN --> MEM
    COD --> MEM
    MEM --> PA
    PEN & COD --> REFL
    REFL --> TC
    REFL --> SUM
    PA --> REP
    ADV --> PA
    PLA --> GEN

    style PA fill:#1a73e8,stroke:#0d47a1,color:#fff
    style REP fill:#388e3c,stroke:#1b5e20,color:#fff
    style REFL fill:#e65100,stroke:#bf360c,color:#fff

图4:15 个 Agent 角色的协作拓扑

在实际使用中,Agent 的执行过程会以流式消息的形式实时展示在 Web 界面中。下方截图展示了一个 Flow 中 Agent 的推理过程和工具调用记录——左侧是用户输入的测试目标,右侧区域实时流式输出 Agent 的思考过程和执行结果。用户可以看到每个 Agent 的「思考链」(Chain of Thought)、调用的工具名称、以及工具返回的结果,实现了完整的可解释性:

图5:Agent 执行过程实时展示——思考链与工具调用记录

各角色的职责分工清晰明确:

  • Primary Agent:整个 Flow 的总协调者,负责任务分解与 Agent 调度
  • Assistant:面向用户的交互式助手,处理用户的实时问答和指令
  • Generator:从用户输入自动生成子任务计划
  • Refiner:优化和改进子任务,确保覆盖全面
  • Pentester:执行渗透测试操作(扫描、利用、横向移动等)
  • Coder:编写和执行自定义攻击代码
  • Searcher:通过搜索引擎收集情报(Google、DuckDuckGo、Tavily 等 7 个数据源)
  • Enricher:用额外上下文丰富搜索结果,去重和提炼
  • Memorist:管理向量存储和知识库,实现跨会话记忆
  • Reflector:反思和验证执行结果,发现异常和错误
  • Adviser:作为导师,监控执行并提供策略建议
  • Reporter:生成最终的结构化漏洞报告
  • Installer:在沙箱容器中安装额外工具和依赖
  • Summarizer:对长对话链进行摘要压缩,控制上下文窗口
  • Tool Call Fixer:修复失败的 LLM 工具调用,重试或修正参数

这种专业化分工的设计哲学是:让每个 Agent 只做自己最擅长的事,避免单个 Agent 上下文膨胀和能力泛化带来的质量问题。

在代码层面,所有 Agent 类型以枚举形式定义在 GraphQL Schema 中。下面的代码来自 schema.graphqls,它同时也是 gqlgen 代码生成器的输入——Go 后端的 AgentType 常量和前端的 TypeScript 类型都是从这个 Schema 自动生成的,保证了前后端类型的一致性:

代码语言:javascript
复制
# 文件位置: backend/pkg/graph/schema.graphqls
# Agent 角色枚举 —— 系统所有预定义角色的精确清单

enum AgentType {
  primary_agent    # 主协调者: 负责任务分解与 Agent 调度
  reporter         # 报告生成者: 结构化输出测试报告
  generator        # 任务生成者: 从用户输入生成子任务计划
  refiner          # 任务优化者: 优化子任务覆盖面和质量
  reflector        # 反思校验者: 验证执行结果,发现异常
  enricher         # 上下文丰富者: 提炼和丰富搜索结果
  adviser          # 导师顾问: 监控执行并提供策略建议
  coder            # 代码编写者: 编写自定义攻击代码
  memorist         # 记忆管理者: 管理向量存储和知识库
  searcher         # 信息搜索者: 多引擎情报收集
  installer        # 工具安装者: 在沙箱中安装额外工具
  pentester        # 渗透执行者: 执行扫描/利用/横向移动
  summarizer       # 摘要生成者: 压缩长对话链控制上下文
  tool_call_fixer  # 工具调用修复者: 修正失败的 LLM 工具调用
  assistant        # 交互助手: 处理用户的实时问答
}

而在 Go 后端中,这个枚举会被编译为对应的常量,并挂载在 AllAgentType 切片上供注册和校验使用。代码位于 graph/model/models_gen.go(自动生成文件),以字符串常量形式保存,确保 Agent 类型在序列化和反序列化时不会出错:

代码语言:javascript
复制
// 文件位置: backend/pkg/graph/model/models_gen.go
// AgentType 字符串常量 —— 由 gqlgen 从 GraphQL Schema 自动生成

type AgentType string

const (
    AgentTypePrimaryAgent  AgentType = "primary_agent"
    AgentTypeReporter      AgentType = "reporter"
    AgentTypeGenerator     AgentType = "generator"
    AgentTypeRefiner       AgentType = "refiner"
    AgentTypeReflector     AgentType = "reflector"
    AgentTypeEnricher      AgentType = "enricher"
    AgentTypeAdviser       AgentType = "adviser"
    AgentTypeCoder         AgentType = "coder"
    AgentTypeMemorist      AgentType = "memorist"
    AgentTypeSearcher      AgentType = "searcher"
    AgentTypeInstaller     AgentType = "installer"
    AgentTypePentester     AgentType = "pentester"
    AgentTypeSummarizer    AgentType = "summarizer"
    AgentTypeToolCallFixer AgentType = "tool_call_fixer"
    AgentTypeAssistant     AgentType = "assistant"
)

// AllAgentType 用于枚举校验和遍历
var AllAgentType = []AgentType{
    AgentTypePrimaryAgent,
    AgentTypeReporter,
    // ... 省略其他常量
}

然而,Agent 再强大也无法凭空执行操作。它们需要一套「双手」来触碰目标系统、收集情报、执行命令——这正是工具调用体系的价值所在。接下来我们看看 PentAGI 如何通过 40+ 个注册工具为每个 Agent 赋予行动能力。

三、工具调用编排:40+ 工具的统一注册表

Agent 本身不直接执行任何操作,而是通过工具调用(Tool Calling / Function Calling)来触发系统能力。PentAGI 维护了一个统一的工具注册表,将所有工具按类型划分:

工具类别

工具列表

用途

屏障工具

done, ask

标记子任务完成 / 向用户提问

Agent 委托

coder, pentester, memorist, search

将子任务委托给其他 Agent

结果存储

code_result, hack_result, search_result

将执行结果持久化

环境工具

terminal, file, browser

执行系统命令、文件操作、浏览器操作

网络搜索

Google, DuckDuckGo, Tavily, Traversaal, Perplexity, Searxng, Sploitus

多源情报收集

向量搜索

search_in_memory, search_guide, search_answer, search_code

从记忆库和知识库中检索

向量存储

store_guide, store_answer, store_code

将新知识写入记忆库

每个工具都由 FlowToolsExecutor 根据当前 Agent 角色进行权限包装,确保不同角色的 Agent 只能调用其权限范围内的工具。

在代码实现层面,工具注册表位于 pkg/tools/registry.go。每个工具通过 FunctionDefinition 结构来定义,包含工具名称、用途描述和参数 Schema。参数 Schema 由 Go 结构体通过 jsonschema.Reflector 自动反射生成,LMM 在调用工具时直接获得结构化的 JSON 参数契约,而非自由文本。下面是注册表的核心片段,展示了从屏障工具 done 到搜索引擎 sploitus 的完整定义:

代码语言:javascript
复制
// 文件位置: backend/pkg/tools/registry.go
// 工具注册表 —— 所有工具以 FunctionDefinition 格式统一注册
// 每个注册条目包含: 名称、用途描述、JSON Schema 参数

// registryDefinitions 存储所有已注册的工具定义
// LLM 通过 function calling 机制调用这些工具,参数由反射自动生成 Schema
var registryDefinitions = map[string]llms.FunctionDefinition{
    // 终端执行工具 —— 在 Docker 沙箱中执行任意命令
    TerminalToolName: {
        Name: TerminalToolName, // 常量值: "terminal"
        Description: "Calls a terminal command in blocking mode. " +
            "Use timeout=0 or a negative value to apply the configured server default timeout. " +
            "Explicit positive values are accepted up to 10800 seconds (3 hours); " +
            "values outside this range are replaced by the server default. " +
            "Only one command can be executed at a time",
        Parameters: reflector.Reflect(&TerminalAction{}),
        // ^ 自动反射 TerminalAction 结构体为 JSON Schema
    },
    // 文件操作工具 —— 读写容器内的文件
    FileToolName: {
        Name:        FileToolName, // 常量值: "file"
        Description: "Modifies or reads local files",
        Parameters:  reflector.Reflect(&FileAction{}),
    },
    // 浏览器工具 —— 在隔离的 scraper 容器中打开网页
    BrowserToolName: {
        Name:        BrowserToolName, // 常量值: "browser"
        Description: "Opens a browser to look for additional information from the web site",
        Parameters:  reflector.Reflect(&Browser{}),
    },
    // Google 搜索引擎 —— 快速查询,返回短内容
    GoogleToolName: {
        Name: GoogleToolName, // 常量值: "google"
        Description: "Search in the google search engine, it's a fast query and the shortest content " +
            "to check some information or collect public links by short query",
        Parameters: reflector.Reflect(&SearchAction{}),
    },
    // Sploitus 漏洞利用聚合器 —— 搜索公开的 PoC 和漏洞利用代码
    SploitusToolName: {
        Name: SploitusToolName, // 常量值: "sploitus"
        Description: "Search the Sploitus exploit aggregator (https://sploitus.com) " +
            "for public exploits, proof-of-concept code, and offensive security tools. " +
            "Sploitus indexes ExploitDB, Packet Storm, GitHub Security Advisories, " +
            "and many other sources. Use this tool to find exploit code and PoCs " +
            "for specific software, services, CVEs, or vulnerability classes.",
        Parameters: reflector.Reflect(&SploitusAction{}),
    },
    // done 屏障工具 —— 标记子任务完成,终止当前 Agent 链
    FinalyToolName: {
        Name:        FinalyToolName, // 常量值: "done"
        Description: "If you need to finish the task with success or failure, use this tool",
        Parameters:  reflector.Reflect(&Done{}),
    },
    // ... 其他工具的注册在此省略
}

// 工具类型映射 —— 将每个工具名称归类,用于权限控制
var toolsTypeMapping = map[string]ToolType{
    FinalyToolName:            BarrierToolType,        // 屏障类
    AskUserToolName:           BarrierToolType,        // 屏障类
    CoderToolName:             AgentToolType,          // Agent 委托类
    PentesterToolName:         AgentToolType,          // Agent 委托类
    TerminalToolName:          EnvironmentToolType,    // 环境操作类
    FileToolName:              EnvironmentToolType,    // 环境操作类
    BrowserToolName:           SearchNetworkToolType,  // 网络搜索类
    GoogleToolName:            SearchNetworkToolType,  // 网络搜索类
    // ... 其他工具的映射
}

除了工具的注册,PentAGI 还维护了另外两个重要的辅助列表:allowedSummarizingToolsResultallowedStoringInMemoryTools。前者指定哪些工具的执行结果需要被摘要压缩(如终端输出和浏览器页面,因为它们的输出可能非常大),后者指定哪些工具的结果需要自动存入长期记忆向量数据库(终端命令、文件操作、搜索和 Agent 执行的结果),从而实现自动化的知识沉淀

代码语言:javascript
复制
// 文件位置: backend/pkg/tools/registry.go
// 允许摘要压缩结果的工具 —— 这些工具的输出可能非常大,需要压缩
var allowedSummarizingToolsResult = []string{
    TerminalToolName, // 终端命令输出可能需要摘要
    BrowserToolName,  // 浏览器页面内容可能需要摘要
}

// 允许自动存入记忆的工具 —— 这些工具的执行结果对长期学习有价值
var allowedStoringInMemoryTools = []string{
    TerminalToolName,     // 终端的命令和输出
    FileToolName,         // 文件读写内容
    SearchToolName,       // 搜索请求和结果
    GoogleToolName,       // Google 搜索结果
    TavilyToolName,       // Tavily 搜索结果
    SploitusToolName,     // Sploitus 漏洞搜索结果
    PentesterToolName,    // 渗透测试结果
    CoderToolName,        // 代码执行结果
    AdviceToolName,       // 顾问建议
    // ... 其他工具
}

这种设计将工具的「执行」与「知识管理」解耦——Agent 只需专注于使用工具完成任务,系统在后台自动完成结果压缩和知识入库,Agent 无需关心这些横切关注点。

工具调用让 Agent 能够「动手」,但一个更深层的问题随之而来:渗透测试往往持续数小时甚至数天,Agent 如何在长时间的任务执行中保持对目标环境的持续认知?如何在多个会话之间复用之前学到的经验?这正是 PentAGI 与其 AI 记忆系统需要解决的下一个关键问题。

四、三层记忆系统:让 AI 不再「失忆」

渗透测试通常跨天、跨多轮对话。PentAGI 设计了完整的记忆体系来解决 AI 的「失忆」问题:

代码语言:javascript
复制
flowchart TB
    subgraph 长期记忆
        VS[(向量存储<br/>pgvector 嵌入)]
        KB[知识库<br/>领域专业知识]
        TK[工具知识<br/>使用模式与经验]
    end

    subgraph 工作记忆
        CTX[当前上下文<br/>任务状态]
        GOAL[活跃目标<br/>当前目标]
        STATE[系统状态<br/>资源状态]
    end

    subgraph 情景记忆
        PAST[历史操作<br/>命令记录]
        RES[操作结果<br/>执行产出]
        PATT[成功模式<br/>最佳实践]
    end

    CTX -->|查询| VS
    VS -->|检索| CTX
    GOAL -->|咨询| KB
    KB -->|指导| GOAL
    STATE -->|记录| PAST
    PAST -->|学习| PATT
    PATT -->|存储| VS
    TK -->|通知| STATE
    RES -->|更新| TK
    VS -->|增强| KB
    KB -->|索引| VS

    style VS fill:#e1bee7,stroke:#7b1fa2,color:#000
    style CTX fill:#bbdefb,stroke:#1565c0,color:#000
    style PAST fill:#c8e6c9,stroke:#2e7d32,color:#000

图6:三层记忆系统架构

  • 长期记忆:嵌入向量存储 + 知识图谱,持久化跨会话的知识沉淀
  • 工作记忆:当前 Flow 的上下文和目标状态,随会话结束释放
  • 情景记忆:历史操作和结果记录,形成成功模式供未来参考

配合 Chain Summarization(链摘要系统),系统能在上下文窗口接近极限时,自动对历史对话进行智能摘要压缩,保留关键信息的同时控制 token 消耗。

有了记忆系统保障长周期认知的连续性,PentAGI 还需要解决另一个在实际运行中更棘手的问题:长时间自主执行时,Agent 会不会跑偏?会不会陷入死循环?会不会因为一次错误的工具调用就破坏整个测试流程?为了应对这些风险,PentAGI 构建了一套从硬限制到智能规划的四层监督体系。

五、Agent 监督系统:保障执行质量的多层防护

PentAGI 设计了四层 Agent 监督机制,确保长时间自动测试的稳定性和结果质量:

代码语言:javascript
复制
flowchart TB
    subgraph 第一层 工具调用硬限制
        HARD[硬限制<br/>MAX_GENERAL=100<br/>MAX_LIMITED=20]
    end

    subgraph 第二层 Reflector 反思校验
        REFLECT[Reflector<br/>3次失败自动介入<br/>引导正确工具调用]
    end

    subgraph 第三层 Execution Monitor 执行监控
        MON[模式检测<br/>相同工具≥5次提醒<br/>进度分析<br/>替代策略推荐]
    end

    subgraph 第四层 Intelligent Task Planning 智能规划
        PLAN[Planner<br/>自动分解3-7步骤<br/>上下文感知<br/>范围管控]
    end

    AGENT[Agent 执行] --> HARD
    HARD -->|接近上限| REFLECT
    REFLECT -->|异常模式| MON
    MON -->|复杂任务| PLAN
    PLAN -->|规划指导| AGENT

    style HARD fill:#ffcdd2,stroke:#c62828,color:#000
    style REFLECT fill:#fff3e0,stroke:#e65100,color:#000
    style MON fill:#fff9c4,stroke:#f9a825,color:#000
    style PLAN fill:#e8f5e9,stroke:#2e7d32,color:#000

图7:四层监督防护体系

要理解这些机制如何在代码层面协同工作,最直接的方式是看核心执行函数 performAgentChain。这个函数位于 pkg/providers/performer.go,是整个多 Agent 系统的「引擎」——它控制着 Agent 执行的迭代循环、工具调用分发、Reflector 介入和链摘要压缩。下面是其核心逻辑的注释版:

代码语言:javascript
复制
// 文件位置: backend/pkg/providers/performer.go
// Agent 链执行引擎 —— 控制 Agent 与 LLM 之间的迭代对话循环
// 每次迭代: Agent 发送消息 → LLM 响应(文本+工具调用) → 执行工具 → 处理结果

// performAgentChain 是 Agent 链的执行主循环
// 参数说明:
//   chainID    - 消息链的唯一标识,用于持久化和日志关联
//   taskID/subtaskID - 当前任务/子任务,用于隔离执行上下文
//   chain      - 当前对话消息链(累积的 LLM 对话历史)
//   executor   - 工具执行器,根据 Agent 角色包装了权限信息
//   summarizer - 链摘要器,在上下文接近 token 限制时自动压缩
func (fp *flowProvider) performAgentChain(
    ctx context.Context,
    optAgentType pconfig.ProviderOptionsType, // Agent 类型(pentester/coder/...)
    chainID int64,
    taskID, subtaskID *int64,
    chain []llms.MessageContent,       // 累积的对话链
    executor tools.ContextToolsExecutor, // 工具执行器
    summarizer csum.Summarizer,         // 链摘要器
) error {
    var (
        wantToStop bool
        // 构建执行监控器,用于检测重复工具调用和进度停滞
        monitor  = fp.buildMonitor()
        // 重复调用检测器,追踪连续相同的工具调用
        detector = &repeatingDetector{}
    )

    // 根据 Agent 类型决定最大工具调用次数
    // 通用 Agent (Assistant/Pentester/Coder) 上限更高
    // 受限 Agent (Searcher/Enricher/Memorist) 上限更低
    var maxCallsLimit int
    switch optAgentType {
    case pconfig.OptionsTypeAssistant, pconfig.OptionsTypePrimaryAgent,
        pconfig.OptionsTypePentester, pconfig.OptionsTypeCoder, pconfig.OptionsTypeInstaller:
        // 通用 Agent: 默认 100 次工具调用
        maxCallsLimit = maxGeneralAgentChainIterations // 常量: 100
    default:
        // 受限 Agent: 默认 20 次工具调用
        maxCallsLimit = maxLimitedAgentChainIterations // 常量: 20
    }

    // ========== 主迭代循环 ==========
    // 每次迭代: 调用 LLM → 处理响应 → 执行工具 → 追加结果到消息链
    for iteration := 0; ; iteration++ {
        // 硬限制: 超过最大迭代次数则报错
        if iteration >= maxCallsLimit {
            return errors.New("agent chain exceeded maximum iterations")
        }

        var result *callResult

        // 当迭代次数接近上限时,自动触发 Reflector 引导 Agent 优雅终止
        if iteration >= maxCallsLimit-maxAgentShutdownIterations {
            // Reflector 告知 Agent 无法继续,要求其调用 done 工具
            result = &callResult{
                content: fmt.Sprintf(
                    "I can't continue this multi-turn chain because " +
                    "I'm too close to the AI agent iteration limit (%d).",
                    maxCallsLimit,
                ),
            }
        } else {
            // 正常调用: 向 LLM 发送当前对话链,获取响应
            result, err = fp.callWithRetries(ctx, optAgentType, chainID,
                taskID, subtaskID, chain, executor, executionContext)
            if err != nil {
                return err
            }
        }

        // 如果 LLM 没有返回任何工具调用(纯文本响应)
        iflen(result.funcCalls) == 0 {
            if optAgentType == pconfig.OptionsTypeAssistant {
                // Assistant 的纯文本响应直接返回给用户
                return fp.processAssistantResult(...)
            } else {
                // 其他 Agent: 通过 Reflector 分析 LLM 为什么没有做决策
                // Reflector 会尝试引导 Agent 正确使用工具
                result, err = fp.performReflector(...)
                if err != nil {
                    return err
                }
            }
        }

        // 将 LLM 的响应(文本+工具调用)追加到对话链
        msg := llms.MessageContent{Role: llms.ChatMessageTypeAI}
        // 保留推理内容(如 Anthropic 的 extended thinking)
        if result.content != "" || !result.thinking.IsEmpty() {
            msg.Parts = append(msg.Parts,
                llms.TextPartWithReasoning(result.content, result.thinking))
        }
        for _, toolCall := range result.funcCalls {
            msg.Parts = append(msg.Parts, toolCall)
        }
        chain = append(chain, msg)

        // ====== 遍历执行所有工具调用 ======
        for idx, toolCall := range result.funcCalls {
            funcName := toolCall.FunctionCall.Name
            // 执行单个工具调用,monitor 和 detector 在其中生效
            response, err := fp.execToolCall(
                ctx, optAgentType, chainID, idx, result,
                monitor, detector, executor, taskID, subtaskID, chain,
            )

            if toolTypeMapping[funcName] != tools.AgentToolType {
                // 非 Agent 委托类工具的调用记录写入 Graphiti 知识图谱
                fp.storeToolExecutionToGraphiti(...)
            }

            // 将工具执行结果作为 Tool 角色的消息追加到对话链
            chain = append(chain, llms.MessageContent{
                Role: llms.ChatMessageTypeTool,
                Parts: []llms.ContentPart{
                    llms.ToolCallResponse{
                        ToolCallID: toolCall.ID,
                        Name:       funcName,
                        Content:    response,
                    },
                },
            })

            // 如果 Agent 调用了屏障工具(done / ask),标记终止
            if executor.IsBarrierFunction(funcName) {
                wantToStop = true
            }
        }

        if wantToStop {
            returnnil// 正常结束 Agent 链
        }

        // 链摘要: 当消息链总长度接近 token 限制时,
        // 自动对历史消息进行智能压缩,保留关键信息
        if summarizer != nil {
            chain, err = summarizer.SummarizeChain(ctx,
                summarizerHandler, chain, fp.tcIDTemplate)
        }
    }
}

这个执行循环的设计体现了几个关键工程决策:

  • 迭代而非递归:用 for 循环而不是递归调用,避免了大模型长时间运行时的栈溢出风险
  • 三层退出路径:正常完成(done 工具)→ Reflector 引导终止(接近上限)→ 硬限制报错(超过上限),确保系统即使在极端情况下也不会无限制运行
  • 工具结果自动追加:每次工具调用的结果都会原样追加到对话链中,LLM 在下一次迭代时就能「看到」自己刚才执行命令的输出,形成感知-行动-观察的闭环

这些机制对小参数模型(< 32B)尤其关键——测试表明在 Qwen3.5-27B-FP8 上启用执行监控和任务规划后,结果质量提升 2 倍,同时显著减少了死循环和冗余劳动。

说了这么多 Agent 的编排和治理,一个自然的追问是:这些 Agent 背后「大脑」到底从何而来?不同的大模型提供商各有千秋,有的擅长推理、有的响应更快、有的适合本地离线部署。PentAGI 的解决之道是打造一套插件式提供商架构,让用户可以根据场景自由选择和组合 LLM 后端。

六、LLM 提供商插件架构

PentAGI 支持 10 个 LLM 提供商的插件式接入,所有提供商统一实现 Provider 接口。这个接口定义在 pkg/providers/provider/provider.go 中,是整个系统 LLM 集成的核心契约。注意所有方法都接受 context.Context 用于超时和取消控制,而 CallWithTools 则是多 Agent 系统中调用频率最高的方法——因为每次 Agent 迭代都会通过它向 LLM 发送当前的对话链和可用工具列表:

代码语言:javascript
复制
// 文件位置: backend/pkg/providers/provider/provider.go
// Provider 接口 —— 所有 LLM 提供商必须实现此接口
// 这是 PentAGI 插件式 LLM 集成架构的核心抽象

type Provider interface {
    // 基础信息
    Type() ProviderType       // 返回提供商类型: openai / anthropic / gemini / ...
    Name() ProviderName       // 返回实例名称,支持同一类型多个实例
    Model(opt pconfig.ProviderOptionsType) string// 返回当前使用的模型名称

    // 带提供商前缀的模型名称,用于 LLM API 调用和 Langfuse 日志记录
    ModelWithPrefix(opt pconfig.ProviderOptionsType) string

    // 从 LLM 返回的 usage 元数据中提取 token 消耗信息
    GetUsage(info map[string]any) pconfig.CallUsage

    // 核心调用方法
    Call(ctx context.Context, opt pconfig.ProviderOptionsType,
        prompt string) (string, error)
    // ^ 简单文本调用:将 prompt 发送给 LLM,返回纯文本响应

    CallEx(ctx context.Context, opt pconfig.ProviderOptionsType,
        chain []llms.MessageContent,
        streamCb streaming.Callback,
    ) (*llms.ContentResponse, error)
    // ^ 多轮对话调用:发送完整的消息链,支持流式回调

    CallWithTools(ctx context.Context, opt pconfig.ProviderOptionsType,
        chain []llms.MessageContent,
        tools []llms.Tool,
        streamCb streaming.Callback,
    ) (*llms.ContentResponse, error)
    // ^ 带工具调用的对话 —— 这是多 Agent 系统的核心调用路径
    //   Agent 向 LLM 发送对话历史和可用工具列表,
    //   LLM 返回文本响应 和/或 工具调用请求

    // 配置访问
    GetRawConfig() []byte                        // 原始配置(YAML 格式)
    GetProviderConfig() *pconfig.ProviderConfig   // 解析后的配置

    // 定价信息和模型列表
    GetPriceInfo(opt pconfig.ProviderOptionsType) *pconfig.PriceInfo
    GetModels() pconfig.ModelsConfig

    // 工具调用 ID 模板,每个提供商可能有不同的命名格式
    GetToolCallIDTemplate(ctx context.Context, prompter templates.Prompter) (string, error)
}

提供商

接入方式

典型模型

OpenAI

REST API

GPT-4o / o3-mini

Anthropic

REST API

Claude 4 Sonnet / Opus

Google AI

REST API

Gemini 2.5 Pro

AWS Bedrock

AWS SDK

Claude / Llama 部署

Ollama

本地 HTTP

Llama 3 / Qwen 3.5

DeepSeek

REST API

DeepSeek-V3 / R1

GLM(智谱)

REST API

GLM-4

Kimi(月之暗面)

REST API

Moonshot

Qwen(阿里云)

REST API

Qwen-Max

Custom

OpenAI 兼容

任意兼容端点

此外还支持 OpenRouterDeepInfra 等聚合器,以及国产模型本地部署(参见 vLLM + Qwen3.5-27B-FP8 部署指南)。

至此,Agent 能够思考(LLM)、能够行动(工具)、能够记忆(三层记忆)、能够自我纠偏(监督体系)。但还有一个关键问题悬而未决:当整个系统全速运转时,你怎么知道每一步发生了什么? 如果测试出了问题,如何回溯定位?这正是可观测性体系的职责所在。

七、可观测性体系

PentAGI 构建了完整的两层可观测性:

  • LLM 可观测性(Langfuse):追踪每一次 LLM 调用、工具执行、Agent 决策,支持端到端调试和性能分析
  • 系统可观测性(OpenTelemetry + Grafana Stack):涵盖指标(VictoriaMetrics)、追踪(Jaeger)、日志(Loki),实时监控系统健康状态

每个工具调用和 Agent 执行都通过观测包装器(toolObservationWrapperagentObservationWrappergenerationObservationWrapper)自动埋点,做到可追溯、可审计、可复盘

七项核心技术拆解完毕,PentAGI 的工程全貌已经清晰。但技术从来不是目的——这些设计最终要回答的是:它在真实的安全测试场景中,到底解决了哪些传统方法无法解决的问题?下面我们从行业痛点出发,重新审视 PentAGI 的差异化价值。


差异化能力与行业痛点

二、行业痛点与 PentAGI 的解题思路

行业痛点

传统做法的局限

PentAGI 的差异化

门槛高

每种工具需记忆复杂 CLI 参数,串联多工具更需经验

自然语言驱动 + 多 Agent 编排,用户只需描述目标

质量不稳

同一目标不同测试员覆盖面和结论差异大

15 个专业化 Agent + 四层监督体系,标准化执行路径

失忆问题

长周期测试中对话上下文溢出,跨天测试需从头开始

三层记忆系统 + 链摘要,实现跨会话知识持续积累

难闭环

扫描即走,利用验证、整改推动断裂

Flow/Task/SubTask 全生命周期管理 + 报告自动生成

难审计

AI 执行过程黑盒,结论无法复核

Langfuse + OTel 全链路追踪,每一步可回放可审计

1. 自然语言驱动的渗透测试
  • 痛点:传统渗透高度依赖对 Nmap、Metasploit、Sqlmap 等数十种工具命令及参数的记忆,且工具之间的串联顺序和结果解析需要大量经验积累。
  • 做法:用户只需描述目标,例如「扫描 10.0.0.0/24 网段并尝试利用 MS17-010」,PentAGI 会自动拆解为 Task 和 SubTask,由 Generator 生成计划 → Refiner 优化 → Pentester 执行 → Reporter 输出报告,全流程无需人工干预。
  • 底层支撑:Agent 通过 terminal 工具在隔离的 Docker 沙箱中执行命令,通过 search 工具收集情报,通过 coder 工具编写自定义脚本——所有操作统一走工具调用契约,而非让 LLM 自由生成 Shell 命令。
2. 专业化多 Agent 协作保证质量
  • 痛点:通用 AI 安全工具往往只有一个 Agent 处理所有事务——信息收集、漏洞识别、利用验证、报告撰写混在一起,经常出现前面步骤未完成就跳到后面的问题。
  • 做法:每个 Agent 角色绑定专属的 system prompt、工具权限和行为边界。信息收集由 Searcher + Enricher 完成,漏洞利用由 Pentester 执行,知识沉淀由 Memorist 管理,最终由 Reporter 生成结构化报告。
  • 组织价值
    • 可复现:同类目标多次测试结果可对比,支持基线检查
    • 可交接:Flow 结构和历史记录完整保存,新人可无缝接手
    • 可审计:每一步 Agent 调用、工具执行、LLM 交互均在 Langfuse 中有完整记录
3. Docker 沙箱隔离执行
  • 痛点:AI 自动执行渗透测试天然具有高风险——错误的命令可能导致环境破坏或数据丢失。
  • 做法:所有终端命令、文件操作、浏览器访问都在隔离的 Docker 容器中执行。系统默认使用 vxcontrol/kali-linux 镜像,内置 20+ 安全工具(nmap、metasploit、sqlmap 等),并支持自动根据任务类型选择不同的容器镜像。
  • 架构优势:支持两节点部署——主节点运行 Web UI 和编排逻辑,Worker 节点在独立服务器上运行沙箱容器,实现网络隔离和权限分离,适合企业级生产环境。
4. 全生命周期运营
  • 痛点:一次性渗透测试做完即走,漏洞修复后缺乏复测闭环,跨周期项目难以跟踪进展。
  • 做法:Flow 作为持久化实体,包含完整的 Task/SubTask 树、执行历史、工具调用日志和最终报告。支持批量任务队列、多目标并发执行、独立会话与状态跟踪。

以上四大差异化能力——零门槛、标准化、安全隔离、全生命周期——共同回答了「PentAGI 为什么值得关注」。但理论终归要在实践中接受检验。接下来我们看看社区的真实评价、行业对比,以及它在技术先进性之外面临的客观争议。


社区评价与行业观察

三、社区影响力与行业定位

PentAGI 由 vxcontrol 团队开发并于 GitHub 开源,是 Go 语言生态中最受关注的 AI 安全测试项目之一。项目在 GitHub 上拥有可观的 Star 数量,社区通过 Discord 和 Telegram 活跃交流。

技术定位

对比业界的几类 AI 安全产品:

类型

代表项目

与 PentAGI 的差异

通用 Agent 框架

OpenHands / AutoGPT

缺乏安全领域专业工具和知识库,路径长、边界模糊

学术原型

多数 arXiv 论文项目

缺少 Web UI、持久化存储、企业治理能力

商业产品

Pentera / XM Cyber

价格高、闭源、不易定制;PentAGI 开源可控

脚本式自动化

传统 Bash/Python 脚本

无 AI 决策能力,无法适应动态场景

PentAGI 的核心竞争优势在于:用工程化手段解决了 AI 渗透测试「从实验室到生产」的所有关键问题——多 Agent 专业化分工保证质量,三层记忆解决长周期失忆,Docker 沙箱确保安全边界,Langfuse + OTel 实现全链路可观测。

待优化方向

  • 大规模并发场景下的稳定性需要更多生产验证
  • 文档和部署对新手仍有一定门槛
  • 对国产大模型的适配还有优化空间
  • C2 和后渗透功能的存在可能引发合规争议,需要用户自行评估法律边界

综合来看,PentAGI 已在技术完备性和工程化程度上走在了同类开源项目的前列,但「能做」和「做得好」之间仍有距离。从这些已知的争议和短板出发,我们不难看到 AI 渗透测试平台接下来的演进方向。


未来展望与结语

四、AI 渗透测试平台的发展方向

PentAGI 的架构设计为 AI 渗透测试平台的演进提供了有益参考,未来方向包括:

  1. 更智能的任务规划:从当前的结构化子任务分解,进化为动态自适应攻击路径规划
  2. 知识图谱的深度利用:Graphiti + Neo4j 的语义关系追踪可以与 Agent 决策深度耦合,实现真正意义上的「经验传承」
  3. 小模型落地:四层监督体系证明了小模型(< 32B)在精心编排下也能完成复杂渗透任务,这对于离线环境(内网、涉密网)意义重大
  4. 标准化输出:与漏洞管理平台(如 DefectDojo、Archery)的深度集成,打通从发现到修复的最后一公里

五、结语

PentAGI 是 Go 语言 + AI 安全测试领域的一次深度实践。它没有停留在「大模型 + 命令行包装」的浅层阶段,而是从工程架构层面系统性地解决了多 Agent 编排、工具调用治理、长周期记忆和全链路可观测等核心问题。对于致力于将 AI 真正落地到渗透测试场景的团队来说,PentAGI 的架构思路和实现细节都值得仔细拆解和学习。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Ms08067安全实验室 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 系统架构与核心设计
  • 核心技术与工程架构
    • 一、技术栈全景
    • 二、多智能体系统:15 个专业角色的协作网络
    • 三、工具调用编排:40+ 工具的统一注册表
    • 四、三层记忆系统:让 AI 不再「失忆」
    • 五、Agent 监督系统:保障执行质量的多层防护
    • 六、LLM 提供商插件架构
    • 七、可观测性体系
  • 差异化能力与行业痛点
    • 二、行业痛点与 PentAGI 的解题思路
      • 1. 自然语言驱动的渗透测试
      • 2. 专业化多 Agent 协作保证质量
      • 3. Docker 沙箱隔离执行
      • 4. 全生命周期运营
  • 社区评价与行业观察
    • 三、社区影响力与行业定位
  • 未来展望与结语
    • 四、AI 渗透测试平台的发展方向
    • 五、结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档