Files
QUZ/antigravity/sdk.go
T
2026-07-05 08:45:54 +00:00

84 lines
4.9 KiB
Go

package antigravity
import (
"bytes"
"context"
"fmt"
"os/exec"
"strings"
)
// StudyElement represents the extracted study content from a question.
type StudyElement struct {
QuestionID int `json:"questionId"`
Source string `json:"source"`
Category string `json:"category"`
Content string `json:"content"` // Markdown content containing formulas, charts, etc.
}
// GeneratedQuestion matches the structure to be saved in QuizQuestions DB.
type GeneratedQuestion struct {
QuestionText string `json:"questionText"`
Choice1 string `json:"choice1"`
Choice2 string `json:"choice2"`
Choice3 string `json:"choice3"`
Choice4 string `json:"choice4"`
CorrectAnswer int `json:"correctAnswer"`
CorrectAnswerStr string `json:"correctAnswerStr"`
Explanation string `json:"explanation"`
Difficulty string `json:"difficulty"`
Subject string `json:"subject"`
}
// CallAgy runs the agy CLI with the given prompt.
func CallAgy(ctx context.Context, prompt string) (string, error) {
cmd := exec.CommandContext(ctx, "agy", "--dangerously-skip-permissions", "--print", prompt)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
return "", fmt.Errorf("agy error: %v, stderr: %s", err, stderr.String())
}
return strings.TrimSpace(stdout.String()), nil
}
// ExtractStudyElement requests the AI to generate a comprehensive study sheet/note for a specific quiz question.
func ExtractStudyElement(ctx context.Context, questionText, choice1, choice2, choice3, choice4, correctAnswer, explanation string) (string, error) {
prompt := fmt.Sprintf("아래 기출문제의 문제, 보기, 정답, 해설을 철저히 분석하여 핵심 개념을 담은 \"학습요소(개념 정리)\"를 작성해 주세요.\n"+
"이 학습요소는 사용자가 이 문제를 완벽하게 이해하고 관련된 이론적 배경까지 학습할 수 있도록 돕는 학습 노트입니다.\n\n"+
"[기출문제]\n"+
"문제: %s\n"+
"보기 1: %s\n"+
"보기 2: %s\n"+
"보기 3: %s\n"+
"보기 4: %s\n"+
"정답: %s\n"+
"해설: %s\n\n"+
"[작성 지침]\n"+
"1. **매우 중요**: 문서의 가장 첫 번째 줄은 반드시 핵심 학습개념/키워드를 설명하는 제목으로 시작해 주세요. (예: `# AES 암호화 알고리즘` 또는 `# OSI 7계층과 캡슐화`)\n"+
" - 첫 줄 외에 다른 서두(예: \"네, 아래는 개념 정리입니다\" 등)는 일절 포함하지 마십시오.\n"+
"2. 단순 정답 해설을 넘어, 문제에 포함된 핵심 개념의 정의, 특징, 작동 방식, 장단점을 일목요연하게 정리해 주세요. (표, 리스트 적극 활용)\n"+
"3. **KaTeX 문법 규칙**: 수식 작성 시 파싱 오류를 철저히 방지하세요. 괄호 매칭을 완벽히 지키고, 수식 내부에 한글을 포함해야 하는 경우 반드시 `\\text{한글}` 형식을 사용하세요. 인라인 수식은 `$수식$`, 디스플레이 수식은 `$$수식$$`로만 작성하세요.\n"+
"4. **Mermaid 문법 규칙**: Mermaid 버전 10.9.6 문법을 엄격히 지켜 `syntax error in text mermaid` 에러를 예방하세요.\n"+
" - `subgraph` 이름(타이틀)에는 공백이나 한글, 괄호가 들어가므로 **반드시** 쌍따옴표로 감싸서 선언하세요. (예: `subgraph \"정상 스택 (Normal)\"`)\n"+
" - 화살표 연결선의 텍스트 라벨 `|설명|` 안에는 괄호 `()`, 슬래시 `/`, 백슬래시 `\\` 등의 특수문자를 절대 쓰지 마세요. (예: `-->|SMTP 프로토콜 포트 25|` 로 표현)\n"+
" - 노드 내부에 한글, 공백, 기호, 괄호가 포함되는 경우 **반드시** 쌍따옴표로 감싸서 선언하세요 (예: `A[\"AES 암호화\"] --> B[\"키 생성\"]`).\n"+
" - 연결 화살표 기호는 오직 `-->` 또는 `-.->` 만 사용해야 하며, `->` 나 `- >` 처럼 깨진 형식을 쓰지 마세요.\n"+
" - 서브그래프(subgraph)를 열었다면 반드시 `end`로 닫아 마감하세요.\n"+
" - 백슬래시(`\\`)는 이스케이프 오류 방지를 위해 두 번(`\\\\`) 겹쳐 적으세요.\n"+
"5. 다른 불필요한 설명은 제외하고, 오직 첫 줄 개념명(# ...)으로 시작하는 마크다운 본문만 반환해 주세요.",
questionText, choice1, choice2, choice3, choice4, correctAnswer, explanation)
return prompt, nil
}
// GenerateDescriptiveQuestion generates a new descriptive/practical exam question based on given reference questions.
func GenerateDescriptiveQuestion(ctx context.Context, referenceExams []string) (*GeneratedQuestion, error) {
// We will create the prompt text in quiz_service.go using callAIEngine.
// This function is kept for backwards compatibility but we will format the prompt inside quiz_service to leverage both API and agy engines.
return nil, fmt.Errorf("use the prompt constructor and callAIEngine helper instead")
}