Files
AIclinicalresearch/docs/03-业务模块/SSA-智能统计分析/07-统计专家配置/提升代码生成与修复成功率的高级策略.md
HaHafeng 52989cd03f feat(ssa): Agent channel UX optimization (Solution B) + Plan-and-Execute architecture design
SSA Agent channel improvements (12 code files, +931/-203 lines):
- Solution B: left/right separation of concerns (gaze guiding + state mutex + time-travel)
- JWT token refresh mechanism (ensureFreshToken) to fix HTTP 401 during pipeline
- Code truncation fix: LLM maxTokens 4000->8000 + CSS max-height 60vh
- Retry streaming code generation with generateCodeStream()
- R Docker structured errors: 20+ pattern matching + format_agent_error + line extraction
- Prompt iron rules: strict output format in CoderAgent System Prompt
- parseCode robustness: XML/Markdown/inference 3-tier matching + length validation
- consoleOutput type defense: handle both array and scalar from R Docker unboxedJSON
- Agent progress bar sync: derive phase from agentExecution.status
- Export report / view code buttons restored for Agent mode
- ExecutingProgress component: real-time timer + dynamic tips + step pulse animation

Architecture design (3 review reports):
- Plan-and-Execute step-by-step execution architecture approved
- Code accumulation strategy (R Docker stays stateless)
- 5 engineering guardrails: XML tags, AST pre-check, defensive prompts, high-fidelity schema, error classification circuit breaker

Docs: update SSA module status v4.1, system status v6.7, deployment changelist
Made-with: Cursor
2026-03-07 22:32:32 +08:00

6.8 KiB
Raw Blame History

架构进阶指南:提升 LLM 代码生成与修复成功率的 10 大高级策略

文档目的: 针对 Agentic Workflow 中大模型写 R 代码容易报错、陷入死循环的问题,提供系统性的解决方案。

核心逻辑: 不要指望大模型“不犯错”,而是要建立一套“让它极难犯错,且一旦犯错能立刻定位”的工程护栏。

🎯 第一部分:提升“首次生成”成功率 (Getting It Right The First Time)

防范于未然永远是成本最低的。为了防止类似 unexpected input中文泄露到代码区这种低级语法错误我们需要在 Prompt 和约束上下狠手:

1. 采用 XML 标签强制物理隔离 (XML Tagging)

  • 痛点:传统的 Markdown 代码块 (r ... ) 很容易被大模型破坏,它经常会在反引号外面或者里面夹杂诸如“好的,根据您的要求...”之类的闲聊。
  • 策略:在 Coder Agent 的 Prompt 中,强制要求它将纯代码包裹在自定义的 XML 标签中。
  • Prompt 示例:“你只能输出纯 R 代码。绝对不要输出任何 Markdown 标记、问候语或解释。你必须且只能将代码放在 <r_code> 和 </r_code> 标签之间。
  • 后端解析Node.js 提取时直接用正则表达式提取 <r_code> 内部的内容,彻底屏蔽外围的所有文字幻觉。

2. 注入“防御性编程”黄金法则 (Defensive Prompting)

  • 痛点LLM 假设数据是完美的,但实际数据常有 NA、类型错误或极端值导致 t.test 等函数直接崩溃。
  • 策略:在 System Prompt 中硬编码医学统计的“防御性 R 编程规范”。
  • Prompt 示例
    “写 R 代码时必须遵守以下防御规则:
    1. 模型计算前,强制剔除涉及变量的 NA 值df <- na.omit(df[, c('X', 'Y')])
    2. 强制类型转换:把分组变量明确转为因子 as.factor(),把数值变量明确转为数值 as.numeric()。
    3. 如果要做回归先检查是否只有1个水平如果只有1个水平直接停止执行。”

3. 强制思维链注释化 (Chain of Thought in Comments)

  • 痛点:如果不让大模型“说话”,直接写代码,它的逻辑往往会混乱(缺乏思维链的推演)。
  • 策略:允许它思考,但强制它把思考过程写在 R 代码的注释里
  • Prompt 示例:“在写具体代码前,请先使用 R 语言的注释符号 # 逐行写下你的分析步骤和推演过程。确保每一行中文的前面都有 #。”

4. 数据字典的高保真注入 (High-Fidelity Schema Injection)

  • 痛点LLM 写错列名(大小写错误、多加了下划线)。
  • 策略:不仅仅给 LLM 传入列名数组,最好把每一列的 Class (如 numeric, character) 和前 3 行的具体数值Head作为 Context 传给 Coder Agent。看到真实的数值长相LLM 选错变量类型和拼错列名的概率会断崖式下降。

🛠️ 第二部分:提升“代码修复”成功率 (Making Self-Healing Work)

一旦出错,如何让 Fixer Agent 一次性改对而不是陷入“修了A错误引发B错误”的死循环

5. R 端报错的“降维翻译” (Enhancing Error Traceback)

  • 痛点R 的默认报错极度晦涩(如 Error in eval(expr, envir) : object 'X' not found不告诉你是哪一行代码报的错。Fixer Agent 拿到这种错误就像盲人摸象。
  • 策略:在 R Docker 的 plumber.R 外壳中,使用 rlang 包捕获异常,将完整的调用栈和具体的出错行号抛给 Node.js。
  • R 代码改造
    tryCatch({
    eval(parse(text = input_code))
    }, error = function(e) {
    # 提取具体的报错信息和可能的行号
    error_msg <- conditionMessage(e)
    # 将此结构化错误返回给 Node.js
    stop(paste("[R_EXEC_ERROR]", error_msg))
    })

6. Fixer Agent 的“上下文重置” (Context Reset)

  • 痛点:如果把错误信息直接 Append 到之前的长对话记录里让模型修改,模型会受之前历史信息的干扰,产生“注意力偏移”。
  • 策略Fixer Agent 必须是一个拥有全新 Context 的独立会话
  • 输入构造:它只需要接收 3 个东西:
    1. <original_code>...原始代码...</original_code>
    2. <error_log>...R引擎的精确报错...</error_log>
    3. <data_schema>...列名和类型...</data_schema>
  • 干净的上下文能让大模型将 100% 的注意力集中在“找 Bug”上。

7. 引入 AST (抽象语法树) 静态检查 (Fail Fast)

  • 策略:在 Node.js 把修复后的代码发给 R 之前(或者在 R 引擎运行 eval 之前),先执行纯粹的语法检查。
  • R 端实现:使用 parse(text = code)。如果代码连括号都没闭合、引号没闭合parse 会立刻报错根本不需要进入漫长的数据加载和计算环节。这能将修复反馈循环Feedback Loop的延迟从几秒缩短到几毫秒。

8. 强制输出“诊断报告”再输出代码

  • 痛点:大模型拿到错误后,急于输出代码,往往只是“瞎蒙”一个改法。
  • 策略:强制要求 Fixer Agent 遵循 Diagnosis -> Fix Plan -> Code 的标准格式输出。
  • Prompt 示例
    “收到报错后,你必须按以下格式作答:
    1. 错误诊断:分析 R 报错的根本原因。
    2. 修复方案:说明你打算修改哪几行代码。
    3. 修正代码:将修改后的完整代码放在 <r_code> 标签中。”

🏗️ 第三部分:架构级防线 (Architectural Safeguards)

9. 异常分类与短路机制 (Error Classification & Circuit Breaker)

有些错大模型能修,有些错大模型绝对修不好,千万不要浪费 Token 循环重试。

在 Node.js 中建立错误拦截字典:

  • 可重试 (Retriable)object not found, unexpected input, could not find function通常是少加了 library 或拼错变量)。
  • 直接短路 (Hard Abort)system is computationally singular (多重共线性,数据数学性质导致,大模型改代码没用), cannot allocate vector of size (内存超限,直接中断并提示用户)。

10. 建立“错题本”机制 (Error Memory / RAG for Fixes)

  • 终极杀招:在数据库建一张 ssa_fixed_errors 表。
  • 流程:当某次 R报错 -> LLM修复 -> 再次执行成功 时,将这个组合 (报错信息 + 修复前代码 -> 修复后代码) 存入向量数据库。
  • 使用:下次 Fixer Agent 遇到类似报错时,先从向量库检索历史成功修复案例喂给它。随着系统运行的时间越长,它修 Bug 的能力就越强,最终无限逼近资深 R 程序员。