Files
HaHafeng ac724266c1 feat(ssa): SSA Agent mode MVP - prompt management + Phase 5A guardrails + UX enhancements
Backend:
- Agent core prompts (Planner + Coder) now loaded from PromptService with 3-tier fallback (DB -> cache -> hardcoded)
- Seed script (seed-ssa-agent-prompts.ts) for idempotent SSA_AGENT_PLANNER + SSA_AGENT_CODER setup
- SSA fallback prompts added to prompt.fallbacks.ts
- Phase 5A: XML tag extraction, defensive programming prompt, high-fidelity schema injection, AST pre-check
- Default agent mode migration + session CRUD (rename/delete) APIs
- R Docker: structured error handling (20+ patterns) + AST syntax pre-check

Frontend:
- Default agent mode (QPER toggle removed), view code fix, analysis result cards in chat
- Session history sidebar with inline rename/delete, robust plan parsing from reviewResult
- R code export wrapper for local reproducibility (package checks + data loader + polyfills)
- SSA workspace CSS updates for sidebar actions and plan display

Docs:
- SSA module doc v4.2: Prompt inventory (2 Agent active / 11 QPER archived), dev progress updated
- System overview doc v6.8: SSA Agent MVP milestone
- Deployment checklist: DB-5 (seed script) + BE-10 (prompt management)

Made-with: Cursor
2026-03-08 15:23:09 +08:00

110 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# **架构优化方案R 代码的本地复现与导出包装 (Export Wrapper)**
**问题诊断:** 大模型在 Agent 管线中生成的 R 代码是高度依赖“平台沙箱环境”的。它缺失了数据读取操作 (df),且引用了平台专属的 UI 辅助函数 (make\_table\_block\_from\_df 等)。
**解决目标:** 用户点击“下载 R 代码”时,系统必须动态注入“本地兼容层”,使得代码可以在任何一台普通的 RStudio 中一键运行。
## **一、 根本解决方案:导出包装器 (Export Wrapper)**
当用户点击“下载 R 代码”时,前端不能仅仅把 Agent 生成的代码原样保存为 .R 文件。我们需要像编译器一样,将代码包裹在一个**标准的本地复现模板**中。
完整的导出文件应该由 3 个部分拼接而成:
1. **数据加载层 (Data Loading)**
2. **函数兼容层 (Polyfills / Mock Helpers)**
3. **Agent 生成的核心代码 (Core Logic)**
## **二、 包装器代码实现范例**
前端或后端在生成下载文件时,请使用以下字符串拼接逻辑:
// 伪代码:在前端 SSACodeModal 或后端导出 API 中实现
function generateDownloadableRCode(agentCode: string, fileName: string): string {
const headerAndPolyfills \= \`
\# \=====================================================================
\# SSA-Pro 智能统计分析 \- 本地复现脚本
\# \=====================================================================
\# 1\. 自动安装缺失的包 (本地复现安全保障)
required\_packages \<- c("dplyr", "gtsummary", "base64enc", "ggplot2")
new\_packages \<- required\_packages\[\!(required\_packages %in% installed.packages()\[,"Package"\])\]
if(length(new\_packages)) install.packages(new\_packages)
suppressPackageStartupMessages({
library(dplyr)
library(gtsummary)
library(base64enc)
library(ggplot2)
})
\# \=====================================================================
\# 2\. 数据读取 (请确保数据文件与本脚本在同一目录下)
\# \=====================================================================
\# 系统已将您的原始数据名填入,如果路径不同请手动修改:
file\_name \<- "${fileName}"
if (file.exists(file\_name)) {
if (grepl("\\\\\\\\.csv$", file\_name, ignore.case \= TRUE)) {
df \<- read.csv(file\_name, stringsAsFactors \= FALSE)
} else if (grepl("\\\\\\\\.xlsx?$", file\_name, ignore.case \= TRUE)) {
library(readxl)
df \<- read\_excel(file\_name)
}
} else {
\# 如果找不到文件,生成测试数据以防代码直接崩溃
warning(paste("找不到数据文件:", file\_name, "。将使用模拟数据进行演示。"))
df \<- data.frame(
root\_curve \= sample(c(1, 2), 100, replace \= TRUE),
Yqol \= sample(c(0, 1), 100, replace \= TRUE)
)
}
\# \=====================================================================
\# 3\. 平台 UI 辅助函数本地兼容层 (Polyfills)
\# 这使得平台专用的 make\_\*\_block 函数在本地控制台优雅地输出,而不报错
\# \=====================================================================
make\_markdown\_block \<- function(text) {
cat("\\\\n========================================\\\\n")
cat(text, "\\\\n")
}
make\_table\_block\_from\_df \<- function(data, title="", footnote="") {
cat("\\\\n---", title, "---\\\\n")
print(data)
if(footnote \!= "") cat("注:", footnote, "\\\\n")
return(list(type="table"))
}
make\_image\_block \<- function(base64\_data, title="", alt="") {
cat("\\\\n\[图形已生成:", title, "- 请查看 RStudio 的 Plots 面板\]\\\\n")
return(list(type="image"))
}
make\_kv\_block \<- function(items, title="") {
cat("\\\\n---", title, "---\\\\n")
print(unlist(items))
return(list(type="key\_value"))
}
\# \=====================================================================
\# 4\. 核心分析代码 (由 AI Agent 生成)
\# \=====================================================================
\`;
return headerAndPolyfills \+ "\\n" \+ agentCode;
}
## **三、 为什么必须这么做?(架构收益)**
1. **防患于未然的数据读取:** 我们不仅注入了 read.csv还加入了 file.exists 检查。如果医生把 R 脚本发给另一个没有原始数据的统计师,代码会自动生成一组 Mock模拟数据。这样 R 脚本无论如何都能跑通,极大提升了产品的专业感。
2. **优雅的 Polyfills (兼容层) 技术:**
这是前端工程(如适配老版本浏览器)最常用的技术。我们在脚本头部用普通的 print() 和 cat() 重写了 make\_table\_block\_from\_df 等函数。这样,大模型生成的复杂 UI 代码在本地 RStudio 中执行时,不仅**不会报错**,还会把结果**整齐地打印在本地控制台上**。
3. **保持 Agent Prompt 的纯净:**
我们**不需要**去修改 CoderAgent 的 System Prompt 让它“记得写读取文件的代码”。因为每次让 LLM 动态写数据读取逻辑它很容易因为编码UTF-8 vs GBK或文件路径错误而翻车。把这种死板的工作交给前端的字符串拼接Wrapper是最稳定、最省 Token 的做法。
## **四、 实施建议**
请前端团队接手此任务:
在 AgentCodePanel.tsx 或 SSACodeModal.tsx 中,找到处理\*\*“导出 R 脚本 (Export/Download .R)”\*\*的 onClick 函数。在生成 Blob 对象并触发浏览器下载之前,将原有的代码字符串通过上述包装器函数处理一遍即可。这只需半小时即可实现。