diff --git a/.Rbuildignore b/.Rbuildignore index a8d03dde..0af279a1 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -13,5 +13,3 @@ ^cla$ ^pkgdown$ ^\.claude$ -^AI_ASSISTANT_MODULE_GUIDE\.md$ -^AI_ASSISTANT_MODULE_GUIDE\.ko\.md$ diff --git a/_pkgdown.yml b/_pkgdown.yml index 3f7d97db..0389bfbc 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -9,6 +9,34 @@ authors: href: https://www.zarathu.com html: +navbar: + structure: + left: [intro, reference, articles, news] + components: + articles: + text: Articles + menu: + - text: "Subgroup Analysis" + - text: "-------" + - text: "Subgroup & Competing Risk Analysis" + href: articles/jsmodule_subgroup_cmprsk.html + - text: "-------" + - text: "AI" + - text: "-------" + - text: "AI Assistant Guide (EN)" + href: articles/ai-assistant-guide.html + - text: "AI Assistant 가이드 (KO)" + href: articles/ai-assistant-guide-ko.html +articles: +- title: "Subgroup Analysis" + desc: "Subgroup and competing risk analysis module" + contents: + - jsmodule_subgroup_cmprsk +- title: "AI Assistant" + desc: "AI-powered statistical code generation" + contents: + - ai-assistant-guide + - ai-assistant-guide-ko template: bootstrap: 5 light-switch: yes diff --git a/AI_ASSISTANT_MODULE_GUIDE.ko.md b/vignettes/ai-assistant-guide-ko.Rmd similarity index 94% rename from AI_ASSISTANT_MODULE_GUIDE.ko.md rename to vignettes/ai-assistant-guide-ko.Rmd index 157fc12f..9e4118f5 100644 --- a/AI_ASSISTANT_MODULE_GUIDE.ko.md +++ b/vignettes/ai-assistant-guide-ko.Rmd @@ -1,3 +1,23 @@ +--- +title: "AI Assistant 모듈 가이드" +author: "Jaewoong Heo" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{AI Assistant 모듈 가이드} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + echo = TRUE, + eval = FALSE +) +``` + # AI Assistant 모듈 jsmodule 패키지를 위한 AI 기반 통계 분석 코드 생성 모듈입니다. @@ -12,14 +32,14 @@ AI Assistant 모듈은 통계 분석을 위한 R 코드를 생성하는 대화 `.Renviron` 파일에 API 키를 추가하세요: -```r +```{r api-setup} # .Renviron 파일 열기 usethis::edit_r_environ() # 다음 중 하나를 추가: -ANTHROPIC_API_KEY=your_key_here -OPENAI_API_KEY=your_key_here -GOOGLE_API_KEY=your_key_here +# ANTHROPIC_API_KEY=your_key_here +# OPENAI_API_KEY=your_key_here +# GOOGLE_API_KEY=your_key_here # 저장 후 R 세션 재시작 ``` @@ -28,7 +48,7 @@ GOOGLE_API_KEY=your_key_here #### 옵션 A: jsBasicGadget과 함께 사용 -```r +```{r basic-gadget} library(jsmodule) # AI Assistant가 포함된 gadget 실행 @@ -39,7 +59,7 @@ jsBasicGadget() #### 옵션 B: 독립 실행형 Shiny 앱 -```r +```{r standalone-app} library(shiny) library(jsmodule) library(survival) @@ -127,7 +147,7 @@ MatchIt, timeROC - **보안 참고**: UI에 입력된 API 키는 브라우저 메모리에만 저장되며 디스크에 저장되지 않음 - **권장 사항**: 로컬 개발 및 단일 사용자 애플리케이션에 적합 -```r +```{r dev-mode} # 개발 모드 - 사용자가 UI에서 설정 가능 aiAssistantUI("ai", show_api_config = TRUE) # 기본값 @@ -147,7 +167,7 @@ callModule(aiAssistant, "ai", - **보안 참고**: 사용자가 API 키를 보거나 수정하는 것을 방지 - **권장 사항**: 공유 API 키를 사용하는 프로덕션 배포에 필수 -```r +```{r prod-mode} # 프로덕션 모드 - .Renviron에서만 API 키 읽기 aiAssistantUI("ai", show_api_config = FALSE) @@ -162,7 +182,7 @@ callModule(aiAssistant, "ai", ### 사용자 정의 변수 구조 -```r +```{r custom-varStruct} server <- function(input, output, session) { data <- reactive(lung) data.label <- reactive(jstable::mk.lev(lung)) @@ -189,7 +209,7 @@ server <- function(input, output, session) { AI 응답을 개선하기 위해 배경 정보를 제공하세요: -```r +```{r analysis-context} callModule(aiAssistant, "ai", data = data, data_label = data.label, @@ -205,7 +225,7 @@ callModule(aiAssistant, "ai", 프로덕션 환경에서는 API 설정 UI를 숨기세요: -```r +```{r production-deploy} ui <- fluidPage( aiAssistantUI("ai", show_api_config = FALSE) ) @@ -223,14 +243,18 @@ server <- function(input, output, session) { ### API 키를 찾을 수 없음 **문제**: "API key not configured" 오류 + **해결책**: + 1. `.Renviron` 파일에 올바른 변수명이 있는지 확인 2. `.Renviron` 편집 후 R 세션 재시작 3. 키가 유효한지 확인 (터미널에서 테스트: `Sys.getenv("ANTHROPIC_API_KEY")`) ### 코드 실행 오류 **문제**: 생성된 코드가 실행 실패 + **해결책**: + 1. 자동 수정을 위해 "Ask AI to Fix" 버튼 클릭 2. 실행 전 에디터에서 코드 검토 3. 데이터에 필요한 변수가 있는지 확인 @@ -238,16 +262,19 @@ server <- function(input, output, session) { ### Summary 결과가 너무 조각남 **문제**: `summary()` 결과가 여러 조각으로 나뉨 + **해결책**: 최신 버전에서 수정되었습니다. jsmodule 패키지를 업데이트하세요. ### 텍스트 출력에 이스케이프 시퀀스 표시 **문제**: `\n`이 줄바꿈 대신 그대로 보임 + **해결책**: 최신 버전에서 수정되었습니다. jsmodule 패키지를 업데이트하세요. ## 모범 사례 ### 1. 구체적인 질문하기 ❌ 나쁨: "이 데이터를 분석해줘" + ✅ 좋음: "wt.loss를 결과변수로, age, sex, ph.ecog를 예측변수로 선형회귀분석 수행" ### 2. 생성된 코드 검토 @@ -320,6 +347,7 @@ AI Assistant 모듈은 보안과 사용성의 균형을 위해 **환경 인식 **환경 감지**: 모듈은 다음을 통해 프로덕션 환경을 자동 감지합니다: + 1. `DEPLOYMENT_ENV` 환경 변수 (`production` 또는 `development`) 2. shinyapps.io 배포 감지 3. RStudio Connect 감지 @@ -328,16 +356,16 @@ AI Assistant 모듈은 보안과 사용성의 균형을 위해 **환경 인식 **배포 모드 설정**: 로컬 개발용 (기본값): -```r +```{r dev-env} # 별도 설정 불필요 - 기본값이 개발 모드 # 또는 .Renviron에 명시적으로 설정: -DEPLOYMENT_ENV=development +# DEPLOYMENT_ENV=development ``` 프로덕션 배포용: -```r +```{r prod-env} # .Renviron 파일에 추가: -DEPLOYMENT_ENV=production +# DEPLOYMENT_ENV=production ``` 또는 마커 파일 생성: @@ -356,6 +384,7 @@ R -e "install.packages('RAppArmor')" ``` **플랫폼 지원**: + - ✅ **Linux**: 완전한 RAppArmor 샌드박싱 사용 가능 - ⚠️ **macOS/Windows**: 프로덕션 모드에서 경고와 함께 표준 eval로 폴백 - 권장사항: 최대 보안을 위해 Linux 서버에 배포 @@ -370,45 +399,52 @@ R -e "install.packages('RAppArmor')" **⚠️ 중요: API 키 처리 방식** **API 키 사용 방법**: + - API 키는 환경 변수(`.Renviron`) 또는 UI 입력에서 읽음 - UI에 입력된 경우, 키는 현재 R 세션 메모리에만 존재 - API 호출은 `httr` 패키지를 사용하여 AI 제공자 API로 전달 **오픈소스입니다**: + - 모든 코드는 https://github.com/jinseob2kim/jsmodule 에서 공개되어 감사 가능 - 숨겨진 API 키 저장이나 전송 없음 - 코드를 직접 검토할 수 있습니다 ✅ **이 모듈이 API 키로 하지 않는 것**: + - 어디에도 저장하지 않음 - 로그에 기록하지 않음 - AI 제공자 외에는 전송하지 않음 ✅ **AI 제공자로 전송되는 것**: + - 사용자의 질문과 프롬프트 - 데이터 구조 정보 (변수명, 타입, 요약 통계) - 이전 대화 기록 - 생성된 코드 (오류 수정용) **전송되지 않는 것**: + - 원시 데이터 값 (질문에 명시적으로 포함하지 않는 한) - 파일 시스템 정보 #### 배포 유형별 모범 사례 **개인/데스크톱 사용** (권장): -```r +```{r personal-use} # .Renviron에 API 키 저장 (사용자 홈 디렉토리) # 사용자 계정에만 비공개로 유지됩니다 -ANTHROPIC_API_KEY=your_key_here +# ANTHROPIC_API_KEY=your_key_here ``` **팀/공유 사용**: + - 각 팀원이 `.Renviron`에 자신의 API 키를 사용해야 함 - 개별 설정을 허용하려면 `show_api_config = TRUE` 설정 - 사용자 간 API 키를 공유하지 마세요 **공개 웹 애플리케이션**: + - ⚠️ **권장하지 않음**: `show_api_config = TRUE`로 공개 배포하지 마세요 - 공개 배포가 필요한 경우 다음 대안을 고려하세요: 1. 서버 측 API 프록시 구현 (커스텀 백엔드 필요) @@ -435,6 +471,7 @@ ANTHROPIC_API_KEY=your_key_here #### 규정 준수 고려사항 민감한 데이터로 작업하는 경우: + 1. ✅ 데이터 구조 및 변수명이 AI 제공자로 전송됨 2. ✅ 통계 요약이 전송될 수 있음 3. ⚠️ 질문에 실제 데이터 값을 포함하지 마세요 @@ -444,7 +481,7 @@ ANTHROPIC_API_KEY=your_key_here ### 권장 보안 설정 **최대 보안을 위해**: -```r +```{r max-security} # 1. .Renviron에 API 키 저장 (코드에 절대 포함하지 않음) usethis::edit_r_environ() # 추가: ANTHROPIC_API_KEY=your_key diff --git a/AI_ASSISTANT_MODULE_GUIDE.md b/vignettes/ai-assistant-guide.Rmd similarity index 94% rename from AI_ASSISTANT_MODULE_GUIDE.md rename to vignettes/ai-assistant-guide.Rmd index a6428a6d..93a3bc09 100644 --- a/AI_ASSISTANT_MODULE_GUIDE.md +++ b/vignettes/ai-assistant-guide.Rmd @@ -1,3 +1,23 @@ +--- +title: "AI Assistant Module Guide" +author: "Jaewoong Heo" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{AI Assistant Module Guide} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + echo = TRUE, + eval = FALSE +) +``` + # AI Assistant Module AI-powered statistical analysis code generation module for jsmodule package. @@ -12,14 +32,14 @@ The AI Assistant module provides an interactive chat interface that generates R Add your API key to `.Renviron` file: -```r +```{r api-setup} # Open .Renviron file usethis::edit_r_environ() # Add one of the following lines: -ANTHROPIC_API_KEY=your_key_here -OPENAI_API_KEY=your_key_here -GOOGLE_API_KEY=your_key_here +# ANTHROPIC_API_KEY=your_key_here +# OPENAI_API_KEY=your_key_here +# GOOGLE_API_KEY=your_key_here # Save and restart R session ``` @@ -28,7 +48,7 @@ GOOGLE_API_KEY=your_key_here #### Option A: Use with jsBasicGadget -```r +```{r basic-gadget} library(jsmodule) # Launch gadget with AI Assistant included @@ -39,7 +59,7 @@ jsBasicGadget() #### Option B: Standalone Shiny App -```r +```{r standalone-app} library(shiny) library(jsmodule) library(survival) @@ -127,7 +147,7 @@ The `show_api_config` parameter controls how API keys are managed: - **Security Note**: API keys entered in UI are only stored in browser memory and never saved to disk - **Recommendation**: Suitable for local development and single-user applications -```r +```{r dev-mode} # Development mode - users can configure in UI aiAssistantUI("ai", show_api_config = TRUE) # Default @@ -147,7 +167,7 @@ callModule(aiAssistant, "ai", - **Security Note**: Prevents users from seeing or modifying API keys - **Recommendation**: Mandatory for production deployments with shared API keys -```r +```{r prod-mode} # Production mode - API key from .Renviron only aiAssistantUI("ai", show_api_config = FALSE) @@ -162,7 +182,7 @@ callModule(aiAssistant, "ai", ### Custom Variable Structure -```r +```{r custom-varStruct} server <- function(input, output, session) { data <- reactive(lung) data.label <- reactive(jstable::mk.lev(lung)) @@ -189,7 +209,7 @@ server <- function(input, output, session) { Provide background information to improve AI responses: -```r +```{r analysis-context} callModule(aiAssistant, "ai", data = data, data_label = data.label, @@ -205,7 +225,7 @@ callModule(aiAssistant, "ai", Hide API configuration UI for production: -```r +```{r production-deploy} ui <- fluidPage( aiAssistantUI("ai", show_api_config = FALSE) ) @@ -223,14 +243,18 @@ server <- function(input, output, session) { ### API Key Not Found **Problem**: "API key not configured" error + **Solution**: + 1. Check `.Renviron` file has correct variable name 2. Restart R session after editing `.Renviron` 3. Verify key is valid (test in terminal: `Sys.getenv("ANTHROPIC_API_KEY")`) ### Code Execution Errors **Problem**: Generated code fails to execute + **Solution**: + 1. Click "Ask AI to Fix" button for automatic correction 2. Review code in editor before execution 3. Check data has required variables @@ -238,16 +262,19 @@ server <- function(input, output, session) { ### Summary Results Too Fragmented **Problem**: `summary()` results split into many pieces + **Solution**: This is now fixed in the latest version. Update jsmodule package. ### Text Output Shows Escape Sequences **Problem**: `\n` visible instead of line breaks + **Solution**: This is now fixed in the latest version. Update jsmodule package. ## Best Practices ### 1. Be Specific in Questions ❌ Bad: "analyze this data" + ✅ Good: "perform linear regression with wt.loss as outcome and age, sex, ph.ecog as predictors" ### 2. Review Generated Code @@ -320,6 +347,7 @@ The AI Assistant module implements **environment-aware code execution** to balan **Environment Detection**: The module automatically detects production environments using: + 1. `DEPLOYMENT_ENV` environment variable (`production` or `development`) 2. shinyapps.io deployment detection 3. RStudio Connect detection @@ -328,16 +356,16 @@ The module automatically detects production environments using: **Setting Deployment Mode**: For local development (default): -```r +```{r dev-env} # No setup needed - defaults to development mode # Or explicitly set in .Renviron: -DEPLOYMENT_ENV=development +# DEPLOYMENT_ENV=development ``` For production deployment: -```r +```{r prod-env} # Add to .Renviron file: -DEPLOYMENT_ENV=production +# DEPLOYMENT_ENV=production ``` Or create a marker file: @@ -356,6 +384,7 @@ R -e "install.packages('RAppArmor')" ``` **Platform Support**: + - ✅ **Linux**: Full RAppArmor sandboxing available - ⚠️ **macOS/Windows**: Falls back to standard eval with warning in production mode - Recommendation: Deploy on Linux servers for maximum security @@ -370,45 +399,52 @@ R -e "install.packages('RAppArmor')" **⚠️ IMPORTANT: API Key Handling** **How API Keys are Used**: + - API keys are read from environment variables (`.Renviron`) or UI input - When entered in UI, keys exist only in the current R session memory - API calls are made using the `httr` package to AI provider APIs **This is Open Source**: + - All code is publicly available and auditable at https://github.com/jinseob2kim/jsmodule - No hidden API key storage or transmission - You can review the code yourself ✅ **What this module does NOT do with API keys**: + - Never saves them anywhere - Never logs them - Never transmits them except to the AI provider ✅ **What IS sent to AI providers**: + - Your prompts and questions - Data structure information (variable names, types, sample statistics) - Previous conversation history - Generated code (for error fixing) **NOT sent**: + - Raw data values (unless explicitly included in your question) - File system information #### Best Practices by Deployment Type **For Personal/Desktop Use** (Recommended): -```r +```{r personal-use} # Store API key in .Renviron (user's home directory) # This keeps the key private to your user account -ANTHROPIC_API_KEY=your_key_here +# ANTHROPIC_API_KEY=your_key_here ``` **For Team/Shared Use**: + - Each team member should use their own API key in `.Renviron` - Set `show_api_config = TRUE` to allow individual configuration - Do NOT share API keys between users **For Public Web Applications**: + - ⚠️ **NOT RECOMMENDED**: Do not deploy with `show_api_config = TRUE` publicly - If you must deploy publicly, consider these alternatives: 1. Implement server-side API proxy (requires custom backend) @@ -435,6 +471,7 @@ ANTHROPIC_API_KEY=your_key_here #### Compliance Considerations If you're working with sensitive data: + 1. ✅ Data structure and variable names are sent to AI provider 2. ✅ Statistical summaries may be sent 3. ⚠️ Avoid including actual data values in questions @@ -444,7 +481,7 @@ If you're working with sensitive data: ### Recommended Security Setup **For Maximum Security**: -```r +```{r max-security} # 1. Store API key in .Renviron (never in code) usethis::edit_r_environ() # Add: ANTHROPIC_API_KEY=your_key