从"源码"到"可用服务":AI-Infra-Guard agent-scan 中 MCP 源码部署 Agent(build_preview)提示词引擎深度解析
【免费下载链接】AI-Infra-GuardA full-stack AI Red Teaming platform securing AI ecosystems via Agent Scan, Skills Scan, MCP scan, AI Infra scan and LLM jailbreak evaluation.项目地址: https://gitcode.com/GitHub_Trending/ai/AI-Infra-Guard
本文以 build_preview.md 这一"MC P 源码部署 Agent"提示词文档为主体,完整拆解其角色约束、六步自动化部署流程(获取源码、解析部署要求、安装依赖、后台启动、日志监控、客户端验证)以及结构化的build_resultXML 输出契约;并结合 agent-scan 的 Agent 模板加载源码与下游动态验证 Agent 的实现,说明该部署阶段在 MCP 白盒/动态验证流水线中的定位。读完后,你将能够独立设计"部署型"子 Agent 提示词,并理解部署结果如何被下游漏洞验证环节消费。
1. 定位:MCP 动态验证流水线中的"部署桥接"阶段
build_preview.md位于 agent-scan 的 Agent 提示词模板目录下(prompt/system/agents/build_preview.md),是 AI-Infra-Guard(AIG)中 AI 红队扫描模块 agent-scan 的一个专职子 Agent 模板。其核心职责在文档首段定义得非常明确:
你是一个自主的 MCP(Model Context Protocol)源码部署 Agent。你的任务是通过自动化流程部署 MCP 程序从源码:包括阅读文档和代码、安装依赖、启动程序、监控日志以验证启动状态,并使用 MCP 客户端进行功能验证。请以分步、详细的方式执行以下操作,并在每个阶段报告进度和结果。如果遇到错误,尝试诊断并重试,然后终止流程。
从源码结构看,agent-scan 的所有子 Agent 均以"Markdown 文件 + 可选 YAML Frontmatter 元数据"的形式组织,由工具层统一发现、解析和调度:
- task 工具 中的
parse_agent_file()会先用正则提取文件头部的---YAML Frontmatter 作为元数据,剩余部分作为 Agent 指令正文; - load_agent_prompt() 按"直接
.md文件 → 目录内index.md/同名文件 → 模糊匹配"的顺序加载指定 Agent 的提示词; - task() 工具 加载模板后经
context.call_subagent()发起子 Agent 会话,list_agents()工具则负责枚举全部可用 Agent。
更关键的是它与下游阶段的数据契约:下游的 动态验证 Agent 提示词 明确写道"从 build_result XML 中提取 server_url、pid、log_file"。也就是说,build_preview的产物不是给人看的自然语言总结,而是一份被下游 Agent 直接解析的结构化 XML——这正是它作为"部署桥接"阶段的价值:把 MCP 服务从"一堆源码"变成"一个可被渗透测试的活服务"。同目录下的 code_audit.md、vuln_review.md、mcp_opera.md 分别负责静态审计、漏洞评审与 MCP 通信机制说明,与build_preview共同构成"静态分析 → 部署 → 动态验证"的完整链路;主控 Agent 的调度逻辑可参见 main.md。
2. 角色定义与硬约束
文档以"角色定义"一节给部署 Agent 设定了身份、目标与约束三元组,这是整份提示词的行为边界:
| 维度 | 定义 | 工程含义 |
|---|---|---|
| 身份 | 专业的 DevOps 工程师,专注于 AI 基础设施的自动化部署 | 提示词以部署运维视角(依赖、进程、日志)而非安全测试视角组织步骤 |
| 目标 | 确保 MCP 程序从源码成功部署并运行在后台,最终通过客户端验证其可用性 | 成功标准是"可被客户端连通",而非"进程还在" |
| 约束 | 仅使用提供的源码和标准命令行工具(如终端、日志监控);避免交互式输入,除非必要;所有操作尽可能自动化 | 保证该 Agent 可以无人在值守条件下无人化运行,这也是红队自动化流水线能串行的前提 |
此外,文档规定每个步骤都必须遵循统一的三段式执行范式:
- 首先,描述你计划做什么;
- 然后,执行具体操作(模拟命令或代码阅读);
- 最后,报告结果(成功、失败及原因)。
这种"计划—执行—汇报"的强结构,是 Agent 提示词工程中控制 LLM 行为漂移的常用手段:它把开放式任务拆成可校验的最小单元,任何一步失败都能被定位到具体阶段。
3. 六步部署流程逐段剖析
以下按原文档的步骤顺序逐一展开,并补充各步骤的实操要点。
3.1 步骤 1:获取并检查源码
- 行动:源码已通过上下文提供(在 agent-scan 的白盒场景中,目标 MCP 项目的源码会被直接注入 Agent 上下文,而不是让 Agent 自行下载)。
- 具体指令:列出源码结构,重点查看根目录的配置文件,如
README.md、requirements.txt、package.json、Dockerfile等。
这一步本质是一次"侦察扫描":通过根目录文件快速判断项目的语言栈与打包方式(Python/Node/容器化),为步骤 2 的部署要求提取划定范围。
3.2 步骤 2:翻阅文档和代码,理解部署要求
- 行动:仔细阅读
README.md或类似文档,识别部署指南、依赖项和启动命令;同时扫描关键代码文件(如主入口点main.py或app.py),确认环境要求(如 Python 版本、端口配置)。 - 具体指令:提取三类关键信息:
- 依赖安装命令(如
pip install -r requirements.txt); - 启动命令(如
python main.py或npm start); - 预期日志消息(如
"Server started on port 8080")。若项目无日志,可适当添加日志信息以便步骤 5 的日志匹配。
- 依赖安装命令(如
- 输出示例(原文档给出):
"文档指出:需要 Python 3.8+,使用
pip install -r requirements.txt安装依赖,启动命令为python src/server.py。日志成功标志为'MCP server is running'。"
这一步是整个流程的"信息枢纽":步骤 5 的success_patterns日志匹配模式就来自这里提取的"预期日志消息",因此提示词特意强调"如无日志可适当添加日志信息"——把"可观测性"前置到部署规划中。
3.3 步骤 3:安装依赖
- 行动:根据步骤 2 的发现安装所有依赖项,优先使用虚拟环境(如
venv)以避免冲突。 - 具体指令:
- 创建虚拟环境:
python -m venv venv && source venv/bin/activate(Python 项目); - 运行安装命令,例如
pip install -r requirements.txt或npm install; - 如果失败,检查网络或依赖版本,然后重试。
- 创建虚拟环境:
- 输出示例:
"依赖安装完成:成功安装 15 个包,无错误。"
失败重试策略在此处埋下伏笔:后续 XML 契约中error_type的取值之一dependency_error,对应的正是本步骤的失败场景。
3.4 步骤 4:执行启动命令(后台运行)
- 行动:使用
execute_shell_background工具在后台启动程序,确保进程持续运行。 - 具体指令:
- 使用
execute_shell_background启动服务,并指定日志文件路径; - 记录返回的进程 ID(PID)以便后续管理;
- 示例:
execute_shell_background(command="cd /path && python main.py", log_file="/tmp/mcp_server.log")
- 使用
- 输出示例:
"程序已启动在后台,PID 为 12345。日志输出重定向到
/tmp/mcp_server.log。"
这里体现了部署 Agent 与交互式终端的根本区别:服务必须以后台进程方式存活,且 PID 与日志文件路径都要作为一等公民被记录——因为它们随后会写进build_resultXML,成为下游动态验证 Agent 的环境输入。
3.5 步骤 5:监控日志判断启动成功
- 行动:使用
check_process_logs工具监控日志文件,判断启动是否成功。 - 具体指令:
- 使用
check_process_logs监控日志文件; - 根据步骤 2 识别的成功消息自定义
success_patterns(如["Server started", "listening on", "Uvicorn running"]); - 设置合理的超时时间(建议 30-60 秒);
- 如果检测到错误,使用
kill_process终止进程,分析日志并尝试修复问题后重试(最多 2 次)。 - 示例:
check_process_logs(log_file="/tmp/mcp_server.log", success_patterns=["Server started", "listening"], timeout=60)
- 使用
- 输出示例:
"日志检查:在 10 秒内发现
'MCP server is running on port 8080',启动成功。"
这一步是"进程存活"与"服务就绪"的区分点:仅确认进程在跑并不够,必须以步骤 2 提取的业务成功日志为准。同时"最多重试 2 次 + kill_process 清理"构成了有界的重试闭环,防止 Agent 在坏依赖上无限循环——这是把 DevOps 的"可恢复性"思维编码进提示词的典型设计。
3.6 步骤 6:编写脚本验证 MCP Server 启动成功
文档要求基于 fastmcp 库编写 MCP 客户端验证脚本,并给出了完整可运行的参考实现(连接 MCP 客户端并打印所有工具):
import asyncio from fastmcp import Client # HTTP server client = Client("http://localhost:8080/sse") async def main(): async with client: # Basic server interaction await client.ping() # List available operations tools = await client.list_tools() print(tools) asyncio.run(main())该脚本通过client.ping()验证连通性、通过client.list_tools()验证 MCP 协议层功能(工具发现)。只有客户端验证通过,部署才算"功能就绪"。这与下游 动态验证 Agent 中使用的同类客户端脚本(call_tool()调用目标工具执行 exploit)形成呼应:build_preview阶段验证的是"服务正常",动态验证阶段复用同一套客户端能力去做"攻击"。
4. 输出契约:build_resultXML
文档最末规定:任务结束时,部署 Agent必须以 XML 格式总结部署结果,"这些信息将被动态验证 agent 使用"。这是整份提示词中工程约束最强的部分——它把自然语言输出收敛为可被程序解析的契约。
4.1 成功情况输出格式
<build_result> <status>success</status> <server_url>http://127.0.0.1:8080</server_url> <pid>12345</pid> <log_file>/tmp/mcp_server.log</log_file> <startup_time>10.5</startup_time> <message>MCP部署成功:程序运行在127.0.0.1:8080,日志显示服务正常运行。</message> </build_result>字段含义与来源:
| 字段 | 含义 | 产生于 |
|---|---|---|
status | success/failed二态 | 步骤 5/6 的最终判定 |
server_url | 服务地址(含端口),供下游客户端直连 | 步骤 2 提取的端口配置 |
pid | 后台进程 ID,供下游验证结束后清理进程 | 步骤 4 记录的 PID |
log_file | 日志文件路径,供check_process_logs复查 | 步骤 4 指定的 log_file |
startup_time | 启动耗时(秒),用于评估服务启动性能 | 步骤 5 的日志监控计时 |
message | 人类可读的结论摘要 | 各阶段汇报汇总 |
4.2 失败情况输出格式
<build_result> <status>failed</status> <error_type>dependency_error|startup_error|timeout</error_type> <log_file>/tmp/mcp_server.log</log_file> <message>失败原因的详细描述</message> <suggestion>修复建议</suggestion> </build_result>注意error_type是一个闭合枚举:dependency_error(对应步骤 3 失败)、startup_error(步骤 4/5 进程起不来或报错)、timeout(步骤 5 超时未匹配到成功日志)。失败分支额外要求suggestion字段给出修复建议,使上游主控 Agent(参见 main.md 中的"子Agent执行失败"处理策略:可跳过阶段则继续并标注限制,关键阶段则向用户报告)可以据此决定是重试、降级还是终止整条流水线。
4.3 契约如何被下游消费
从 dynamic_verification.md 的"任务输入"与"阶段1:环境准备与确认"可以确认该契约的实际消费方:
- 动态验证 Agent 收到的输入包含"服务器信息:从构建预览阶段获得的服务器地址、端口、PID 等";
- 其验证流程的第一步即"从 build_result XML 中提取 server_url、pid、log_file",必要时用
check_process_logs再次确认服务器状态; - 漏洞按风险等级排序后逐个验证(命令注入、凭据窃取、间接提示注入、硬编码密钥、认证绕过、工具投毒/影子、Rug Pull 等),验证完成后还要求"使用
kill_process终止测试启动的服务器"——这里的 PID 正是build_result里部署 Agent 记录的那个。
两条提示词文档首尾相扣:build_preview负责"把服务立起来并交付坐标",dynamic_verification负责"拿着坐标去打洞并善后"。XML 契约正是二者之间唯一的、无歧义的数据通道。
5. 支撑工具链与源码印证
build_preview.md通篇围绕一组 shell/进程类工具展开,这些工具名在 agent-scan 的动态验证提示词中也成套出现(工具使用指南),可以推断它们是 agent-scan 运行时为子 Agent 提供的一套标准环境操作原语:
| 工具 | 在 build_preview 中的用途 |
|---|---|
execute_shell_background | 后台启动 MCP 服务并返回 PID,日志重定向到指定文件 |
check_process_logs | 按success_patterns轮询日志,带timeout判定启动成败 |
kill_process | 失败重试前清理残留进程;下游验证结束后做资源善后 |
generate_python/write_file/execute_shell/read_file | 生成并执行步骤 6 的 fastmcp 客户端验证脚本、读取源码 |
而 Agent 模板本身的加载与调度则由 agent-scan/agent_scan/tools/task/task.py 承担:get_all_agents()扫描模板目录、parse_agent_file()解析 Frontmatter、task()工具将"Agent 正文 + 任务提示词"组装后通过call_subagent()派生子会话。这意味着build_preview.md并不是一段一次性文档,而是被红队流水线反复实例化执行的提示词级组件——它的每一次改动都会直接作用于所有 MCP 白盒扫描任务的部署阶段行为。
6. 小结:部署型 Agent 提示词的设计要点
以build_preview.md为样本,可以归纳出 agent-scan 中"部署型子 Agent"提示词的四条可复用设计:
- 角色与约束先行:身份(DevOps)、目标(客户端可验证)、约束(禁交互、全自动化)三段式定义,划定 LLM 行为边界;
- 步骤强结构化:六步流程每步都遵循"计划—执行—汇报"范式,并给出具体的命令示例与"输出示例",把抽象要求锚定到可观察的输出;
- 可观测性前置:在步骤 2 就提取"预期日志消息",必要时主动加日志,使步骤 5 的
success_patterns匹配有据可依; - 结构化输出契约:以
build_resultXML(成功/失败两态 + 闭合的error_type枚举 +suggestion)作为阶段间数据通道,保证下游动态验证 Agent 可以无歧义地解析并复用server_url、pid、log_file。
对希望在自己的 Agent 流水线中增加"部署-验证"环节的团队,build_preview.md 与其下游 dynamic_verification.md 的组合,以及 task 工具的模板加载实现,构成了一个从提示词设计到工程落地的完整参照;更多 agent-scan 的整体功能介绍可参考 agent-scan/README.md。
【免费下载链接】AI-Infra-GuardA full-stack AI Red Teaming platform securing AI ecosystems via Agent Scan, Skills Scan, MCP scan, AI Infra scan and LLM jailbreak evaluation.项目地址: https://gitcode.com/GitHub_Trending/ai/AI-Infra-Guard
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考