跳到主要内容

11. 案例研究:17 个专注模式横向对比

回到 README | 上一章:10-build-your-own-loop.md | 下一章:12-debugging-and-observability.md

reactloops 目录下当前已注册 17 个专注模式。本章给出横向对比表,并对其中 5 个最有学习价值的 loop 做深度拆解。

11.1 横向对比表

注册名复杂度Hook 用法自定义 action 数覆盖 directly_answerLiteForge 用法流式字段数关键 prompt 文件用途
loop_defaultInitTask 处理 attached data + 意图识别0(共享通用 actions)DeepIntent 调用0persistent_instruction通用 ReAct 入口
loop_intentInitTask + OnPostIteraction2(query_capabilities, finalize_enrichment)否(用 finalize_enrichment 替代)DeepIntent 实现persistent_instruction + reactive_data内部意图识别
loop_smart_qaInitTask7(search_knowledge, web_search 等)否(用 final_answer)persistent_instruction智能问答
loop_knowledge_enhanceOnPostIteraction(finalize fallback)1(search)finalize fallback1persistent_instruction知识库增强
loop_planInitTask + OnPostIteraction8(output_facts, search_knowledge, scan_port 等)否(用 finish_exploration)多个 LiteForge 步骤生成文档/计划多(含 AITag)persistent + plan_from_document + guidance_document任务规划
loop_http_fuzztest极高InitTask + OnPostIteraction9(set_http_request, fuzz_method, fuzz_path 等)初始化 + finalize 多次多(AITag + Stream)persistent + reactive_data + reflection_output_exampleHTTP 安全模糊测试
loop_http_flow_analyzeOnPostIteraction(强制 fallback)4(filter, match, get_detail, output_findings)finalize fallbackpersistent + reactive_dataHTTP 流量分析
loop_code_security_audit极高InitTask + 多阶段多(phase1 + phase2 扫描)多个 phase 内部persistent + 多 phase代码安全审计
loop_syntaxflow_ruleInitTask(LiteForge 抽参数)persistent + reactive_dataSyntaxFlow 规则编写
loop_yaklangcodeInitTask(LiteForge 解析需求)多(grep_yaklang_samples, gen_code 等)多(含 yaklang_code_editor)persistent + reactive_datayak 代码生成
loop_write_python_scriptInitTaskpersistent + reactive_datapython 脚本生成
loop_internet_researchOnPostIteraction(finalize fallback)多(web_search 等)finalize fallbackpersistent互联网调研
loop_dir_exploreInitTask多(filesystem 操作)persistent目录探索
loop_java_decompilerInitTask + OnPostIteraction多(decompile_jar 等)persistentJava 反编译
loop_ai_skill_auditInitTaskpersistentAI 技能审计
loop_report_generatingInitTask(LiteForge 抽报告意图)persistent报告生成
loop_infosec_reconInitTask + OnPostIteraction多(recon 系列)persistent信息安全侦察

复杂度判定

  • 低:< 50 行 init.go,几乎只用默认配置
  • 中:50-150 行 init.go,有几个自定义 action
  • 高:150-300 行 init.go,多 hook + LiteForge
  • 极高:>300 行 init.go 且有专门的子目录(actions、prompts、辅助函数)

11.2 推荐学习顺序

按递增复杂度:

  1. loop_default:理解最简形态
  2. loop_smart_qa:理解 ActionFilter + 自定义 actions
  3. loop_knowledge_enhance:理解 finalize fallback 模式
  4. loop_intent:理解内部 loop + meta 行为
  5. loop_http_flow_analyze:理解多 action + finalize fallback
  6. loop_plan:理解多 LiteForge 编排
  7. loop_http_fuzztest:理解极端定制化(终极目标)

下面给 5 个最值得细看的 loop 做深度拆解。


11.3 深度拆解 1:loop_default

角色

通用入口。当用户输入没有明显的领域意图时,ReAct 默认进这个 loop。

入口

源码 loop_default/init.go。注意它没有自己的 init.go 主 factory,而是在另一个文件(参考 loop_default/ 目录)注册。

init 流程

源码 loop_default/init.go:11-101buildInitTask

学到什么

  • InitTask 是 ReAct 框架最重要的扩展点:在不动主循环的前提下做"引导环境"
  • 能力发现的级联:先快后慢、先便宜后贵
  • loop_default → loop_intent 同栈调用:演示了 reactloops 的组合化

11.4 深度拆解 2:loop_intent

角色

内部意图识别 loop。loop_default 的深度路径会调用它。WithLoopIsHidden(true) 表示前端不暴露。

关键配置

源码 loop_intent/init.go:24-94

reactloops.WithDisableLoopPerception(true)        // 不需要感知层
reactloops.WithAllowRAG(false)
reactloops.WithAllowAIForge(false)
reactloops.WithAllowPlanAndExec(false)
reactloops.WithAllowToolCall(false) // 不允许调真工具
reactloops.WithAllowUserInteract(false) // 不允许问用户
reactloops.WithUseSpeedPriorityAICallback(true) // 用快模型
reactloops.WithMaxIterations(1) // 只跑一轮!
reactloops.WithActionFilter(...) // 只允许 query_capabilities + finalize_enrichment

学到什么

  • 专注模式可以是"一次性"的MaxIterations=1 + 严格 action filter = 只做一件事
  • 关闭多余能力:感知 / RAG / 工具调用都关掉,把 token 全用在意图识别
  • WithLoopIsHidden:前端不显示,但是父 loop 可以调用
  • Speed priority:意图识别要快,质量可接受即可
  • 组合 OnPostIterationHook 强制 finalize:就算 LLM 没主动调 finalize_enrichment,hook 兜底

11.5 深度拆解 3:loop_smart_qa

角色

智能问答。用户提问,系统结合知识库 / 网络 / 文件 / 持久记忆 给答案。

关键配置

源码 loop_smart_qa/init.go:35-95

reactloops.WithAllowRAG(false)              // 通过自己的 search_knowledge action 控制
reactloops.WithAllowAIForge(false)
reactloops.WithAllowPlanAndExec(false)
reactloops.WithAllowToolCall(false) // 关掉通用工具,只用自己注册的
reactloops.WithMaxIterations(5) // 限制 5 轮
reactloops.WithActionFilter(...) // 白名单:search_knowledge, web_search, read_file, find_files, grep_text, search_persistent_memory, final_answer
// 注册 7 个自定义 action
knowledgeSearchAction(r),
webSearchAction(r),
readFileAction(r),
findFilesAction(r),
grepTextAction(r),
memorySearchAction(r),
finalAnswerAction(r),

学到什么

  • 白名单胜过黑名单:明确允许哪些 actions,拒绝其他所有
  • 不用通用工具WithAllowToolCall(false) 然后自己注册定制版(更可控、更易测试)
  • final_answer 替代 directly_answer:自定义命名让 prompt 更直观
  • 5 轮迭代:限制成本,逼 LLM 聚焦

11.6 深度拆解 4:loop_plan

角色

任务规划。生成结构化的多步执行计划,结合知识库 / 文件系统 / 互联网信息 / SMART 思维框架。

关键配置

源码 loop_plan/init.go:72-176

reactloops.WithAllowRAG(false)
reactloops.WithAllowToolCall(false)
reactloops.WithAllowAIForge(false)
reactloops.WithAllowPlanAndExec(false)
// 关键:用 PersistentContextProvider 而不是简单的 Instruction
reactloops.WithPersistentContextProvider(func(loop, nonce) (string, error) {
return utils.RenderTemplate(persistentInstruction, map[string]any{
"Nonce": nonce, "UserInput": ..., "PlanPrompt": planPrompt,
})
})
// AITag 字段:让 LLM 输出 facts 段
reactloops.WithAITagFieldWithAINodeId(PlanFactsAITagName, ..., aicommon.TypeTextMarkdown),
reactloops.WithMaxIterations(PlanMaxIterations), // 4
// 8 个 action:
finishExploration(r), outputFactsAction(r), searchKnowledge(r),
readFileAction(r), findFilesAction(r), grepTextAction(r),
webSearchAction(r), scanPortAction(r), simpleCrawlerAction(r),

关键设计

末轮 action 收紧

isLastIteration := currentIter+1 >= maxIter
if isLastIteration {
for _, name := range infoGatheringActions {
loop.RemoveAction(name)
}
// 强制只能 finish_exploration
}

最后一轮动态删除所有信息收集 action,强制 LLM 收尾。这是 reactloops 的高级用法。

多次 LiteForge 编排

finish_exploration 触发后,OnPostIteraction 会调多个 LiteForge:

  1. generateGuidanceDocument:把 facts + evidence 转成结构化文档
  2. generatePlanFromDocument:再把文档转成可执行计划
  3. 流式输出到不同 NodeId

源码 loop_plan/generate_document_and_plan.go

学到什么

  • PersistentContextProvider vs PersistentInstruction:后者是字符串,前者是动态渲染(每轮都跑一次)
  • 末轮强制收尾:LLM 不主动 finish 时,框架强行剥夺它的选项
  • 多 LiteForge 串联:复杂的"工程化生成"用 LiteForge 拆步
  • AITagField 用于结构化 markdown 输出:facts 段比 JSON 字段流更适合 markdown

11.7 深度拆解 5:loop_http_fuzztest(终极复杂度)

角色

HTTP 安全模糊测试。所有 reactloops 扩展点几乎都用上了。

文件结构

loop_http_fuzztest/
├── init.go # 主 factory(120+ 行 With* 组合)
├── action_directly_answer.go # 覆盖默认 directly_answer
├── action_set_http_request.go # 设置目标请求
├── action_patch_http_request.go # 单点细粒度修改
├── action_modify_http_request.go # 整包重写
├── action_fuzz_method.go # method fuzz
├── action_fuzz_path.go # path fuzz
├── action_fuzz_header.go # header fuzz
├── action_fuzz_get_params.go # GET 参数 fuzz
├── action_fuzz_body.go # body fuzz
├── action_fuzz_cookie.go # cookie fuzz
├── action_generate_and_send.go # 自由生成
├── init.go (init_task) # 复杂的初始化
├── finalize.go # 复杂的 finalize
├── session_*.go # 会话持久化
├── http_request_*.go # HTTP 包工具
├── prompts/ # 多个 prompt 文件
└── *_test.go # 测试

关键配置(init.go:35-119)

preset := []reactloops.ReActLoopOption{
reactloops.WithAllowRAG(false),
reactloops.WithAllowToolCall(true),

// 两种 AITag:生成的包 / 修改后的包
reactloops.WithAITagFieldWithAINodeId("GEN_PACKET", ..., aicommon.TypeCodeHTTPRequest),
reactloops.WithAITagFieldWithAINodeId("GEN_MODIFIED_PACKET", ..., aicommon.TypeCodeHTTPRequest),

// 覆盖 directly_answer
reactloops.WithOverrideLoopAction(loopActionDirectlyAnswerHTTPFuzztest),

// 复杂的 InitTask(160+ 行)
reactloops.WithInitTask(buildInitTask(r)),

// 复杂的 finalize
BuildOnPostIterationHook(r),

reactloops.WithMaxIterations(int(r.GetConfig().GetMaxIterationCount())),
reactloops.WithAllowUserInteract(r.GetConfig().GetAllowUserInteraction()),
reactloops.WithPersistentInstruction(instruction),
reactloops.WithReflectionOutputExample(outputExample),

// 复杂的 ReactiveData:20+ 个状态字段渲染
reactloops.WithReactiveDataBuilder(...),

// 9 个自定义 action
setHTTPRequestAction(r), patchHTTPRequestAction(r), modifyHTTPRequestAction(r),
fuzzMethodAction(r), fuzzPathAction(r), fuzzHeaderAction(r),
fuzzGetParamsAction(r), fuzzBodyAction(r), fuzzCookieAction(r),
generateAndSendPacketAction(r),
}

关键设计

InitTask:bootstrap 上下文

源码 loop_http_fuzztest/init.go:128-184(不同于注册的 init.go):

  1. 检查是否已有 HTTP 请求(来自上轮 session)
  2. 没有则用 LiteForge 从用户输入抽取 raw HTTP / URL
  3. 抽取失败时尝试从历史 session 恢复
  4. 都失败 → emit "请提供 HTTP 包" + op.Done() 早退
  5. 成功 → 再用 LiteForge 生成"测试要点 + 灵感提示"流到 quick_plan NodeId

Override directly_answer

源码 loop_http_fuzztest/action_directly_answer.go

ActionVerifier: func(loop, action) error {
// 验证:不能同时用 payload 字段和 FINAL_ANSWER tag
// 验证:必须有内容
}
ActionHandler: func(loop, action, op) {
// 区分内容来源(payload / tag)
// EmitFileArtifact + EmitResultAfterStream
// 持久化会话上下文
// 添加 timeline 元事件
// op.Exit()
}

Finalize:自动总结

源码 loop_http_fuzztest/finalize.go:13-28

func BuildOnPostIterationHook(invoker aicommon.AIInvokeRuntime) reactloops.ReActLoopOption {
return reactloops.WithOnPostIteraction(func(loop, iteration, task, isDone, reason, op) {
if !isDone { return }
persistLoopHTTPFuzzSessionContext(loop, "post_iteration")

// 已经回答过就不重复
if hasLoopHTTPFuzzFinalAnswerDelivered(loop) ||
hasLoopHTTPFuzzDirectlyAnswered(loop) ||
getLoopHTTPFuzzLastAction(loop) == "directly_answer" {
return
}

// 否则强制生成 fallback 总结
finalContent := generateLoopHTTPFuzzFinalizeSummary(loop, reason)
deliverLoopHTTPFuzzFinalizeSummary(loop, invoker, finalContent)

if reasonErr, ok := reason.(error); ok && strings.Contains(reasonErr.Error(), "max iterations") {
op.IgnoreError()
}
})
}

复杂的 ReactiveData

每轮都把 20+ 个状态字段拉进 prompt:

  • OriginalRequest / OriginalRequestSummary
  • CurrentRequestSummary / PreviousRequestSummary
  • RequestChangeSummary / RequestModificationReason
  • RepresentativeRequest / RepresentativeResponse
  • DiffResult / VerificationResult
  • SecurityKnowledge
  • RecentActionsSummary / TestedPayloadSummary
  • FuzztagReference / PayloadGroupsReference

学到什么

  • 极端定制化的极限:所有 reactloops 扩展点都能用
  • session 持久化:跨 task 状态保留(数据库存储)
  • 多次 LiteForge 编排:init / finalize / 中间状态生成都用
  • AITagField 输出 HTTP 包TypeCodeHTTPRequest 让前端按 HTTP 格式渲染
  • 状态密集型 ReactiveData:每轮 prompt 都包含完整运行时状态
  • Override + Verifier:自定义 directly_answer 加严格校验

11.8 其他 loop 速览

loop_knowledge_enhance

知识库增强。简单的 single-action loop(search)+ 强 finalize fallback。学习 finalize 模式的最佳示例

loop_internet_research

互联网调研。多个 web_search action 组合 + finalize 生成 markdown 报告。

loop_dir_explore

目录探索。filesystem 操作 + 文件树渲染。学习如何处理大量返回数据的最佳示例

loop_code_security_audit

代码安全审计。多 phase 设计:phase1 扫描发现问题 → phase2 验证 → phase3 报告。学习多 phase loop 切换

loop_syntaxflow_rule

SyntaxFlow 规则编写。强 InitTask 用 LiteForge 抽取规则需求。

loop_yaklangcode

yak 代码生成。AITag 输出 yak 代码到专用 editor 节点。学习 code_yaklang ContentType

loop_write_python_script

类似 yaklangcode,但目标是 python。

loop_java_decompiler

Java 反编译。集成 jar 处理工具 + LiteForge 分析结果。

loop_ai_skill_audit

AI 技能审计。检查已有 skill 库的覆盖率。

loop_report_generating

报告生成。集成模板 + 多源数据 + LiteForge 渲染。

loop_infosec_recon

信息安全侦察。集成 nmap / dnslog / 子域名 / 端口扫描等。


11.9 模式总结

从横向对比中提取的几个通用模式

模式 A:白名单 ActionFilter

loop_smart_qa / loop_intent / loop_plan 都用 WithActionFilter 严格白名单。这是控制 loop 范围的最强武器

模式 B:Finalize Fallback

loop_knowledge_enhance / loop_http_fuzztest / loop_http_flow_analyze / loop_internet_research 都有 OnPostIteraction(isDone=true) 强制兜底。

if hasDelivered { return }
useLiteForge to generate report
EmitFileArtifact + EmitResultAfterStream
IgnoreError on max iterations

模式 C:Override directly_answer

复杂 loop(fuzztest / flow_analyze / 多个代码生成 loop)用 WithOverrideLoopAction(customDirectlyAnswer) 实现自定义最终输出语义。

模式 D:InitTask 用 LiteForge

loop_http_fuzztest / loop_syntaxflow_rule / loop_yaklangcode 在 init 阶段用 LiteForge 处理用户输入:抽参数、提取上下文、生成 quick_plan。

模式 E:末轮收紧

loop_plan 在最后一轮删除所有信息收集 action。这是框架级强制收尾的范例。

模式 F:内部 Loop(Hidden)

loop_intentWithLoopIsHidden(true) + MaxIterations=1 + Speed priority。给"内部预处理"的标准做法

模式 G:状态密集 ReactiveData

loop_http_fuzztest 把 20+ 状态字段都注入到每轮 prompt。适合状态密集的工程化任务

11.10 进一步阅读