学习Agent,越学越像在重新理解操作系统

  1. 操作系统里:进程与线程 Agent世界:主Agent与sub-Agent
    操作系统里,进程是资源边界,线程是执行单元。同进程的线程共享内存,跨进程则要显式通信。Agent世界完全照搬了这套做法——sub-Agent,多个Agent并行协作,谁能访问谁的状态?共享上下文带来效率,也带来竞争条件。死锁、竞争、一致性

  2. 系统调用 Tool Use
    用户程序想访问硬件,不能直接碰,必须通过系统调用陷入内核,由内核代为执行。Agent想搜网页、跑代码、查数据库,也不能自己动,必须通过Function Calling交给Harness执行。两者的本质完全一样:在权限边界上打一个受控的洞,能力从这个洞里流进来,风险也从这个洞里被隔住。

  3. Cache / 虚拟内存 Context Window
    Context window是Agent最稀缺的资源,贵到每个token都要精打细算。这和CPU Cache的逻辑一模一样:什么放寄存器(当前推理),什么放内存(近期对话),什么换页到磁盘(压缩摘要)?当上下文满了,Agent框架开始做context compression——这就是在做内存分页与交换,只不过换出去的不是字节,是语义。

  4. 文件系统挂载 RAG
    RAG把外部知识库挂进Agent的“文件树”,需要时检索,不需要时不占窗口。这和操作系统挂载外部存储的逻辑完全相同:用廉价的大容量存储补偿昂贵的快速内存,按需加载,用完释放。

  5. 内核 / 调度器 Harness / Orchestrator
    Agent = Model + Harness,Model是计算本身,Harness是操作系统内核:管权限、调度任务、分配资源、处理工具调用的返回。多Agent系统里的Orchestrator就是调度器,决定哪个Agent先跑、跑多久、结果传给谁

​ Agent时代,资源从CPU/内存变成了token/推理时间,“程序”从机器指令变成了自然语言。

RAG

基本信息Retrieval-Augmented Generation,检索增强生成
简要介绍:先从知识库中检索相关文档,再让模型基于这些文档生成回答
能降低幻觉(Hallucination),让回答更贴近事实;还能节省训练成本,无需让模型“死记硬背”海量数据

1
2
3
核心流程:
用户提问 → Query向量化 → 向量库检索 → Top-K相关片段 →
拼接Prompt → LLM生成 → 带引用的答案输出

在提问前,把资料分片,然后把片段丢给embedding模型,给每个片段都产出对应的向量,然后存入向量数据库。
在提问时,用户的问题会丢给embedding模型,然后embedding把生成的向量在向量数据库(chromadb最常用的向量数据库)里面找top-k个与用户问题最接近的某个固定数量的片段,然后把这些片段送给Cross-encoder模型进行重排,重排就相当于又进行了一遍精心筛选。

专业名词

BM25:TF饱和”:SQL”出现 3 次就差不多够了,出现 10 次也不额外加分(防堆砌
长度归一化: 长文档命中关键词可能是巧合,短文档命中反而更可能是”真相关”
IDF 稀有度: “SQL”只在 10% 的文章里出现→很珍贵;”的”在 99% 的文章里出现→不值钱
单一向量检索可能漏掉关键词精确匹配的内容,就同时用BM25做关键词召回,向量做语义召回
RRF排序融合就是解决多路知识的问题,可以设计返回知识的权重

我的项目的RAG系统:首先走的是轻量化关键词,按照漏洞类型分类,然后打tag用BM25(关键词检索)召回,RRF解决那几个不懂的知识库来源的权重问题。

实战RAG示例
先初始化模型和Embedding(常用计算方法余弦相似度(最常用)、点积、L2距离),
FAISS是 Facebook 开源的向量相似度搜索库,适合本地开发测试,数据存储在内存中
生产环境使用 Pinecone、Milvus、Chroma、Weaviate 等专业向量数据库,支持持久化和分布式
RAG的对话记忆
有两种记忆,rag核心解决知识的来源,memory解决了上文说了啥

类型 作用 存储内容 生命周期
Vector Memory (RAG 核心) 语义检索 文档 chunk 的 embedding 静态知识库,更新需重嵌入
Conversation Memory (对话增强) 多轮上下文 用户/助手原始对话消息 按 session 隔离,可持久化

rag核心的记忆的场景,比如说用户追问,几个问题不相同但是高度相似,就可以拼接历史精准检索
LangChain 新范式:RunnableWithMessageHistory,简单理解就是把「你刚才说过什么」自动拼到「你现在问什么」前面,一起送给大模型。
使用的是一个Runnable 接口,通过拦截调用,通过 session_id 区分不同用户

RAG投毒

在大模型从外部知识库中检索相关信息是,在很多个节点都可以投毒

1
2
3
[外部数据源] → [摄入/清洗] → [向量库] → [检索] → [Prompt组装] → [LLM生成] → [用户]
↑ ↑ ↑ ↑ ↑ ↑
投毒点1 投毒点2 投毒点3 投毒点4 投毒点5 投毒点6

外部数据源可以借鉴之前315曝光的大模型投毒(生成式引擎优化GEO投毒),发布一些虚假的产品信息,让大模型在抓取公开源的时候混入这些错误的虚假信息,影响ai的正确回复
语义投毒:主要的手法就是在知识源里面看似权威 + 语义稠密 + 与目标query高相关」的虚假知识,为什么有效:RAG 检索依赖语义相似度,投毒内容若与 query 向量距离更近,会优先召回
指令注入型投毒:

Agent基本原理和问题

Agent非常擅长模式复制。代码库里有什么模式,它就忠实地复制并放大——包括坏模式和架构漂移。这意味着不加约束的 Agent 会以惊人的速度积累技术债务。

697

范式 核心问题 优化对象 交互模式
提示词工程 怎么把话说清楚 Prompt 的措辞、格式、示例,让模型听懂意图,更好的执行任务 一问一答
上下文工程 怎么给 AI 喂信息 文档、代码片段、历史对话,确保模型在合适的时机拿到正确且必要的事实信息 信息注入 → 生成
驾驭工程 怎么让 Agent 可靠工作 约束、反馈回路、控制系统,长链路任务中的持续正确、偏差纠正、故障恢复 人类掌舵,Agent 执行

Agent Loop

Agent Loop 是所有 Agent 范式共享的运行引擎,其本质是一个 while 循环:每一次迭代完成”LLM 推理 → 工具调用 → 上下文更新”的完整链路,直至任务终止。
大概的流程,开始,加载系统提示词和可用工具列表和用户的初始请求。判断是否达到终止条件,接着就开始Agent Loop的核心迭代:读取上下文,LLM推理决策,分析状态,决定下一步行动。执行行动,捕获执行的结果,追加上下文,然后又回到判断是否达成终止的条件(为防止模型陷入死循环,须设置强制中断条件,如最大迭代轮次上限)
记忆系统就可以理解为一个Context Engineering,Prompt Engineering只是单轮交互、静态输入,能引导模型更好的输出目标的内容,但是Context Engineering是在多轮/长文本/动态环境中,管理上下文信息流以优化模型行为,作用在多轮对话、RAG、Agent、长文档理解,「哪些上下文该保留/压缩/丢弃,何时注入

ReAct

是一个AI agent目前主流的开发范式
将“思维链(CoT)推理”与“外部环境交互行动”相结合,弥补单纯 LLM 缺乏实时信息和容易产生幻觉的缺陷。通过交织推理和行动,ReAct 使模型生成更可靠、可追踪的任务解决轨迹,提高解释性和准确性

  • 优势:显著减少幻觉(引入外部真实数据验证)、提升复杂任务的成功率、具备极高的可解释性与可调试性(完整的推理轨迹清晰可见)。
  • 局限性:多轮循环迭代会导致系统整体响应延迟增加,同时其表现高度依赖所集成的外部工具和 Skills 的质量与稳定性

从底层来看,驱动 Agent Loop 运转的核心是一套动态组装的 Prompt:

Prompt Engineering

对于基于大语言模型开发应用(如智能客服、写作助手、代码生成工具)的开发者来说,提示词工程是核心环节:它是模型的配置接口:通过精心设计的提示词(常称为 系统提示),可以定义 AI 助手的角色、行为准则和知识范围。
影响应用效果和成本:好的提示词能用更短的交互、更低的 API 调用成本,获得更优的结果
让prompt效果更好的方法: 给ai一个设定好的角色,约束ai的输出边幅或者工作范围,把复杂的任务拆解成一个一个步骤。
要首先结合项目的背景写好System Prompt

区分数据和提示词

用xml标签分离数据和指令,指令在标签外,数据在标签内

Harness Engineering

本质上是为 AI 系统搭建一个“可控运行和测试的框架,大模型和 Agent 的行为是不确定的,而且涉及多步推理和工具调用,如果没有一个统一的 harness.
驾驭工程,简单说就是构建约束机制、反馈回路、工作流控制和持续改进循环
四个核心组件:
Pasted image 20260413164359.png
上下文工程,按需检索 · 活文档机制,比如skills,还有AGENTS.md,AGENTS.md 是 AI 智能体进入代码仓库时看到的第一份指南。但这不是一本静态的 1000 页说明书——上下文是稀缺资源,过多的指导反而会挤掉任务、代码和相关文档的空间,更好的做法是:提供一个稳定、小巧的入口点,然后教 Agent 根据当前任务按需检索和拉取更多的上下文
熵管理(Entropy Management)——垃圾回收

A2A 协议

通信协议(Agent-to-Agent)

Transformer 架构简析

想象你要写一篇关于太阳系的文章:

  • 通读资料:你会先看很多相关的书籍和网页。
  • 抓住重点:你会注意到太阳、行星、轨道、引力这些词频繁出现且相互关联。
  • 组织语言:根据你想表达的重点(比如介绍火星),你会选择性地运用之前看到的关于火星大小、颜色、位置等信息,并组织成通顺的句子。

Transformer 的工作方式与此类似,它的核心流程分为三个阶段:

  1. 输入处理:你的话被拆分成词或字(Token),并转换成计算机能理解的数字(向量)。
  2. **理解上下文(核心):自注意力机制(Self-Attention)开始工作。它让模型在处理句子中每一个词时,都能权衡句子中所有其他词的重要性。这个过程是并行的,速度极快。
  3. 生成与循环:模型基于对所有词的理解,计算出概率分布,预测下一个最可能出现的词。选中并输出这个词后,将其作为新的输入,重复整个过程,直到生成完整回答。
    img

LangGraph和langchain

一个Agent基本的组成就是
LLM 推理引擎
任务规划层 任务拆解和规划,树状搜索优化
记忆系统 短期记忆直接利用模型上下文,长期记忆向量库,RAG
工具调用Function Calling MCP 一些工具API

参考文章:奇安信攻防社区-基于LangGraph的自主网络攻防(CTF)智能体

LangGraph三大核心:Graph(图)
Graph 是整个工作流的蓝图,定义了 Agent 的完整逻辑结构。它由节点(Nodes)和边(Edges)组成
节点: 节点是普通的 Python 函数,接收当前 State,返回更新后的 State,职责:执行业务逻辑(LLM 调用、工具执行、数据清洗、API 请求等)
边(edge):定义节点间的跳转关系,不参与任何数据处理

State(状态)
State 是贯穿整个图的共享数据结构。每个节点可以读取和更新 State,更新后的 State 会传递给下一个节点。
相当于是一个全局状态或者可以理解成一个全局上下文对象,一个记录信息的字典

1
2
3
4
class GraphState(TypedDict):
"""图状态数据结构,类型为字典"""
messages: Annotated[list, add_messages] # 设置消息列表,并添加归纳函数
node_name: str

Node
每个Node都是“无状态”的纯函数,它只干一件事:从State拿到数据,处理(调大模型),这里会返回ai_message,就是一个功能函数

Edge
边,但我更愿意理解成是路由或者是控制流,上面提到的无状态的node节点,要使用Edge连接起来,串成一个完整的工作 ,起始和结束为:start和end

Compile

1
2
# 4.编译图为Runnable可运行组件
graph = graph_builder.compile()

这个就是编译功能
将刚刚构建好的组件编译成一个可执行的对象(Runnable),它会检查你的逻辑是否有环、是否有没连上的孤岛节点

简单演示完整调用流程:
添加节点和边

1
2
3
4
5
6
7
8
# 2.添加节点
graph_builder.add_node("llm", chatbot)# 给chatbot命名为llm
graph_builder.add_node("tool_executor", tool_executor)

# 3.添加边,注意并不是按代码顺序执行的
graph_builder.add_edge(START, "llm")
graph_builder.add_edge("tool_executor", "llm")
graph_builder.add_conditional_edges("llm", route)

首先开始,state的内容是:messages = 用户输入的问题
此时LLM可以看到消息列表和绑定的工具(name、description、args_schema)
决定是:直接回答(只返回content),或调用工具(返回 content + tool_calls),模型想调用工具的话就会带上tool_calls,底层的system prompt可能是

你是一个助手。你拥有以下工具可用: 工具名:google_serper,描述:一个谷歌搜索API,参数格式:{‘query’: ‘string’}。 **如果用户的问题你需要查资料,请务必输出格式为 <tool_call>{...}</tool_call> 的内容,不要说废话

关于实际的工具调用的问题,模型只要看到类似搜索的问题,就预测出一段符合JSON格式的代码块

1
2
3
模型输出:{"name": "google_serper", "args": {"query": "xxxx大学 xxxx"}}

库的处理:LangChain的底层会用正则表达式或者特殊的 Parser(解析器)把这段字符串抠出来,封装成我们看到的tool_calls对象

LangChain 是一个用于构建 LLM 应用的开源框架,支持链式调用、记忆管理和工具集成

APG

Agent Pattern Graph

  • 安全专家自然语言表达经验 -> AI 梳理成 APG -> APG Runtime 解释执行 APG

APG 是一种基于 YAML 声明式语法定义的有向无环图 (DAG)(后续可能酌情增加环的概念,以支持循环、递归和图复用),用于描述一个代码安全审计或者渗透测试流程,也可以描述任意通用领域 SOP。由一系列节点和边组成,其中节点定义 Agent 的操作任务和预期产出,边定义流程的动态路由条件。APG Runtime 负责解释运行APG
示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
name: 办公网网站风险测试  
agent: PydanticAI

context:
target_url: "" # 网站URL,APG的输入
auth_status: "" # n2 节点产出的鉴权状态 (SSO, Custom, None)
bypass_result: "" # n4 节点产出的绕过结果 (Success/Fail)
vulnerability_report: "" # n6 节点产出的漏洞信息或无漏洞报告

nodes:
- id: n2
type: start
name: 访问目标,检测身份认证
inputs:
- target_url
content: |
行为: 访问目标网站 {{target_url}} 首页, 获取响应和请求记录。
判断是否存在 SSO 统一身份认证,以及是否存在自定义认证。如果直接可访问功能界面,没有跳转和登录,则认为“无任何鉴权”。
将鉴权状态总结输出到 'auth_status' 变量中(可选值:SSO, Custom, None)。
工具建议: browser_navigate, browser_network_requests
outputs:
- auth_status
- id: n3
type: end
name: 放弃测试 (SSO)
content: |
目标 {{target_url}} 存在 SSO 强制认证,安全性较高,放弃测试。
outputs: []
- id: n4
type: action
name: 自定义鉴权绕过
content: |
目标 {{target_url}} 存在自定义鉴权。
行为: 通过爆破、前端鉴权绕过等方式尝试绕过自定义鉴权,进入后台功能界面。爆破前可以使用 admin/admin 和 user/user 这种弱口令组合。
将绕过尝试的结果总结输出到 'bypass_result' 变量中(可选值:Success, Fail)。
工具建议: browser_navigate, browser_type, browser_click
outputs:

Dify 和 n8n 这类工具是通用业务流程的自动化,它们的核心是连接不同的 API 和服务, APG 的目标是固化人类专家的思维路径,它是为驱动 AI Agent 进行复杂攻防推理而设计的。APG 的节点不是一个原子 API 调用,而是给 Agent 的一个高层任务指令(比如:“尝试绕过自定义鉴权”),
我们要解决的问题是:如何让 Claude Code 严格按照专家经验定义的流程执行。自然语言描述的 Prompt 天生缺乏对执行路径的强制约束,Agent 可能会”理解”你的意图,但无法保证完全按照预期的步骤和分支逻辑执行。这就是为什么我们需要 APG——一种结构化的、可验证的意图表达方式。

工具调用

使用 @tool 装饰器可以将任何 Python 函数转为 LLM 可调用的工具。LangChain 会自动将函数名和 docstring 传递给模型,让模型知道何时以及如何使用这个工具。
在工程落地中,Tool 的定义,要让 Agent 准确理解并调用外部工具,业界目前依赖两大核心标准协议:底层数据格式标准(OpenAI Schema)应用通信接入标准(MCP)
OpenAI Schema的核心机制是基于 JSON Schema 的接口定义,LLM 在推理时只消费这部分 JSON Schema 来理解工具的功能边界,从而决定”是否调用”以及”如何填充参数

Function Calling

json
{ “type”: “function”, “function”: { “name”: “query_slow_sql”, “description”: “查询指定微服务在特定时间段内的慢 SQL 日志。当需要排查服务响应慢、数据库查询超时或 CPU 异常飙升时调用。若用户询问的是网络或内存问题,请勿调用此工具。”, “parameters”: { “type”: “object”, “properties”: { “service_name”: { “type”: “string”, “description”: “待查询的服务名称,例如:user-service、order-service” }, “time_range”: { “type”: “string”, “description”: “查询时间范围,格式为 HH:MM-HH:MM,例如:09:00-09:30” }, “threshold_ms”: { “type”: “integer”, “description”: “慢 SQL 判定阈值(毫秒),默认为 1000,即超过 1 秒的查询视为慢 SQL” } }, “required”: [“service_name”, “time_range”] } } }


https://javaguide.cn/ai/agent/agent-basis.html

1
2
这个传统的工具调用,将多个原子工具在代码层封装为高阶工具,对外暴露单一的 JSON Schema。LLM 只能看到函数签名和参数描述,但是现在,用==skill==举例,llm只读取一部分,直到真正确定调用的时候才将完整的内容注入上下文。
通信接入层(==MCP==):相当于是工具起了一个server,外部系统通过这个server让LLM来调用工具,MCP Server 在向外暴露工具时,内部依然使用 JSON Schema 来描述每个工具的参数规范。也就是说,JSON Schema 是底层的数据格式基础,MCP 是在其之上构建的通信协议层

JSON Schema 只做一件事:
描述工具调用接口

MCP 做四件事

  1. 工具管理 (Tools)
  2. 资源管理 (Resources)
  3. 提示词管理 (Prompts)
  4. 内容流式传输

skills投毒

当 Skill 是 Markdown 并被渲染成 HTML 时,HTML 注释会在页面上不可见;但系统若把原始文本原封不动喂给模型 ,这些不可见内容仍会进入上下文,从而形成“人看不见、模型看得见”的指令盲区

针对移动端的自动化渗透流程

移动端的测试,认证、授权和数据读取逻辑,往往分散在页面配置、初始化 HTML、框架加载器和组件脚本中。如果直接黑盒测试,比如让ai接一个bp的mcp,很容易在大量页面和接口里失焦,所以应该先从静态层面入手。注意的点,避免 AI 在证据不足时过度推断,可以用skill负责约束分析边界,要求先有代码证据、再做最小化验证。大部分的逻辑还需要低人工介入

面试内容

  1. 非确定性:同样的 Prompt,下次生成的代码结构可能完全不同。
  2. 上下文遗忘:项目一旦变大,AI 记不住之前的逻辑,开始胡乱修改已有功能(Regression)
  3. 隐性债务:为了快速获得“Good Vibe”,AI 可能会引入极其拙劣的实现方式,而在不做深度 Review 时很难发现
  4. 利用好Spec,定义总体目标,规范,然后细分到小的plan,开始执行,测试通过才算任务完成。
    思考与执行分离,复杂任务不可能在单个上下文窗口内完成,需要 Orchestrator + Worker 分层架构,状态持久化到外部存储|

提示词注入

这是一个github copilot的rce
CVE-2025-53773:诱导ai修改.vscode/settings.json,加入”chat.tools.autoApprove”: true
会禁用所有用户确认 ,自动执行 shell命令(calc.exe/Calculator)。
后面修复之后,似乎只校验了文件名,插件对敏感文件路径检查时,使用的模式匹配仅考虑了小写字符,但是window平台文件路径不区分大小写,所以用大小写绕过
rce的利用方法也有变化,核心是这一行配置

php.validate.executablePath”: “c:\windows\system32\calc.exe

1
2
这行是给 Vs Code 的 PHP 扩展 用的配置项,VS Code 里有个 PHP 扩展(或者内置的验证机制)
它会在你编辑/保存 PHP 文件时,自动调用配置里的 php 可执行文件,去帮你做语法检查

这是默认的php解释器
php.validate.executablePath”:”c:\php\php.exe

可以用sql注入来类比,在llm中攻击的对象变成了大语言模型的”理解逻辑”,造成这个问题的就是数据和指令共享同一个上下文窗口。
提示词注入不是一个可以通过”说教”来修复的Bug。它是当前Transformer架构的固有特性——数据与指令在同一上下文中被无差别处理。真正的防御必须来自架构层面的隔离,而非仅仅依赖措辞,便于理解就是系统提示词和用户的输出都混在一个上下文,又不能控制模型的响应,所以用系统提示来防御没用
越狱攻击:
Pasted image 20260418091508.png

参考文章:LLM提示词注入攻防全解析:真实事故案例与防御实践 | SmallYoung

防御思路

具体的一个方向的防护措施还要根据实际使用场景来选择
seo投毒
公开数据的投毒:限制信息的获取来源,然后如果是那种大规模的投毒,可以哈希去重一下,如果相同的内容不同的域名,就是有问题。

提示词注入
Spotlighting:给数据贴标签
核心思路是通过格式化标记帮助模型区分”指令”和”数据”(指令就是系统提示词,数据就是用户的输入)

Dual-LLM模式:权限分离的架构设计
将LLM系统分为两个权限层级,外部内容(网页、邮件、文档)只能进入非特权LLM,该LLM没有任何工具访问权限,非特权LLM的输出以结构化引用而非原始文本的方式传递给特权LLM,特权LLM只接受来自受信任来源(用户直接输入)的指令
比如
何时选择Dual-LLM架构?

  • ✅ AI Agent需要访问外部工具或互联网
  • ✅ 系统需要处理不受信任的用户上传内容
  • ✅ 安全合规要求高的金融/医疗场景
  • ❌ 简单的单轮对话问答系统(过度设计)
  • ❌ 延迟敏感的实时应用(双LLM调用增加延迟)

一些需要思考的问题

怎么给 agent 拆任务它的完成度最高?哪些薄弱环节需要用 Skill 去强化?Agent 的执行流程和运行环境怎么设计?怎么让多个 agent 并行跑且不互相冲突?这些问题没有开箱即用的标准答案,取决于你的具体工作任务、场景,以及你对 agent 能力边界的理解。本质上,你是在和一种全新的协作对象磨合,找到最高效的配合方式。
关于CTF的解题智能体,claudecode这种Coding Agent本质已经超越了一个“模型接口”,它是一个完成度极高的工程型智能体

  • 成熟、稳定的 Prompt 结构;
  • 自动化的工具调度与执行循环;
  • 近乎无感的上下文管理机制;
  • 对代码、文件系统、命令行的原生理解力

看来要想写成一个完全体的Agent架构,就不能在这两个之中一个做出选择,应该分层发挥框架的特点,目前想到的是将工业化的 Agent(如 Claude Code)封装成一个“超级工具”,但是具体如何实现和规划层的langraph来交互,还是没想到解决方法。

上层:战略与编排层

  • 核心职责:决策、规划、审计、沉淀。这是 Agent 的“大脑”和“灵魂”。
  • 技术实现:使用 LangChain / LangGraph 等框架,显式地定义业务逻辑、状态机、记忆结构和风控规则。
  • 控制权:完全掌握在我们自己手中。

下层:能力与执行层

  • 核心职责:高效、稳定地完成具体任务。这是 Agent 强有力的“双手”。
  • 技术实现:将工业化的 Agent(如 Claude Code)封装成一个“超级工具”。
  • 控制权:我们将具体的执行过程“外包”出去,只关心输入和输出。

但是模型的更新换代和能力提升实在太快,正在逐渐吸收框架约 80% 的功能(智能体定义、消息路由、任务生命周期。但是还是要按照它现在的能力给他配上最好的轮子。

p神的对aiagent工作流的看法
但经过测试他发现,如果用此时的大模型来挖洞,挖出来大量是误报的问题,特别是对于大型项目分析起来还是很吃力,团队内部其实在做的完全是另一件事—使用AI来处理和运营传统SAST工具生产的漏洞
SAST工具是静态应用程序安全测试(Static Application Security Testing)工具的简称,它是一种白盒测试方法,通过在不执行程序的情况下分析源代码、字节码或二进制文件来识别安全漏洞
只是让大模型审核我们传统SAST产出的漏洞报告,那就完全不一样了,大模型只需要跟着漏洞报告中说到的数据流进行分析就可以了,

LLM最擅长的领域是 攻击手法有限、信息收集路径有限、决策空间天然收敛,这本质上就是一个 Harness,非常适合 LLM 的探索模式
回到一面面试官问的安卓渗透agent的问题,但是安卓渗透并不是天然决策空间收敛,他只是比真实业务环境的web更可控,突发的情况更少,工程的型态明显有不同
安卓渗透中输入给LLM的对象是一个apk,本质:程序分析问题(静态 + 动态),加上一些动态的抓包,而不是像web那样抓包放包有明确的response。
强依赖工具,预处理层,静态分析,比如jadx(反编译),收集基本的框架信息。在后面的代码分析部分可能需要阅读大量的代码或者反汇编之后的内容,类似于代码审计的场景,所以可以设计一个plan层(摘要层),解决代码审计大量长任务和长上下文的方法,就是强结构化,多阶段分解,先用规划层和筛选层过滤出可疑的代码部分,再让最后的执行agent来具体分析,语义判断
安卓渗透agent的渗透路径相对有限,但复杂,比如混淆,加壳

ChainReactor的agent思考

倾向于先实现一个通用场景的agent:意图理解、任务编排、状态管理、错误恢复、工具调度
安全只是其中一个小场景,首先具备通用能力,才会具备强大的安全能力,为CTF特定场景造轮子的话,真实的渗透场景能力就会大大降低
传统多 Agent 架构问题不在于数量,在于分工设计,之前的那个ctf解题agent的那种通识skill可以直接去掉了,但是poc和payload是必要的。

AI无法识别错误并更改方向
Agent 会在同一个坑里挖十分钟——人看一眼就知道该换方向了,但 Agent 没有”一眼”这个概念。正常场景下 HITL(Human-in-the-Loop)是正解:人介入一下,成本清零

工程到底是不是负优化

在yhy的第一版安全agent中,Orchestrator 调度子 Agent,Browser Agent 操作 Chrome,C2 Agent 做后渗透,Reverse Agent 做逆向。架构搞得挺复杂的。前几天做了个测试,用 Claude Code CLI 加一个 Playwright 浏览器插件,没有任何安全专用的 skills。测试的是 WIZ 云安全挑战赛的题目
就用了cc这个CLI,什么安全知识库都没有,CHYing Agent 做了那么多——子 Agent 调度、MCP 隔离、上下文管理、RAG 检索——虽然使用 GLM5 半个小时也能做出来,之前某个版本 10 分钟做出来所以要想清楚一个问题,大多数人的工程优化很可能都是负优化,也还有一个原因,这些东西可能是适配去年第一届比赛时的模型水平的。那时候模型能力不够,需要你用工程手段去补。而现在模型进化太快了,很多我精心设计的”辅助逻辑”,对现在的模型来说反而是负优化——它自己本来能做到,你的框架反而在添乱,淚笑的想法就是不从头设计agent,而是调度 Codex、Claude Code 这些通用 Agent 来干活。底座用别人的,自己设计的是流程和调度策略。
需要想清楚的一个问题是,模型能力的变强,加上这些工程机别的coding agent,会不会已经让专门设计一个垂直类 Agent 的价值变得很低了,我们需要的是一个通用的agent。
调度就是要设计流程,用通用 Agent 做底座,重点放在:哪个环节用哪个模型、怎么在模型之间传递信息、什么时候需要人介入。DeepSeek 便宜但够用,Claude 贵但判断力强,人的价值在于知道什么时候该问什么。
我需要改变之前的一个想法,基于cc或者codex来做执行层的话,外部接入一个顾问的框架来和cc本体的agent是有问题的,事实证明这样的效果并不好,实际上如果要对claudecode的执行约束就只能通过hook和prompt,这个方式的约束力是非常不足的


访问 · 访客 · 运行