InDesign-LLM 통합 문서 자동화 시스템 구축 가이드
Adobe InDesign과 LLM API(OpenAI, Gemini)를 통합한 문서 자동화 시스템은 충분히 구현 가능하다. ExtendScript의 네이티브 HTTPS 미지원이라는 핵심 제약을 우회하는 방법이 여러 가지 존재하며, restix 라이브러리, CEP 패널, 또는 파일 기반 데이터 교환 방식이 가장 실용적인 접근법이다. 특히 수능 영어 문항 자동 생성의 경우, GPT-4o 기반 시스템이 4등급 수준(68점)의 문항을 생성할 수 있으며, o1-preview 모델은 1등급(88점) 수준까지 도달했다.
ExtendScript의 HTTP 통신 한계와 우회 방법
Socket 객체의 근본적 제약
ExtendScript의 Socket 객체는 TCP/IP 레벨의 기본 연결만 지원하며, SSL/TLS 암호화를 전혀 처리하지 못한다. OpenAI와 Gemini API는 모두 HTTPS를 필수로 요구하므로, 네이티브 Socket으로는 직접 연결이 불가능하다. HTTP/1.0만 지원하고 청크 전송 인코딩도 처리하지 못해 LLM의 스트리밍 응답 수신에도 문제가 있다.
// Socket 객체 - HTTP만 가능, HTTPS 불가
var conn = new Socket;
if (conn.open("api.example.com:80")) {
conn.write("GET /endpoint HTTP/1.0\r\n");
conn.write("Host: api.example.com\r\n\r\n");
var reply = conn.read(999999);
conn.close();
}
| 프로토콜 | 지원 여부 | 비고 |
|---|---|---|
| HTTP | ✅ 제한적 | Socket으로 수동 구현 필요 |
| HTTPS/SSL | ❌ 불가 | SSL/TLS 지원 없음 |
| XMLHttpRequest | ❌ 불가 | 브라우저 API 미포함 |
restix 라이브러리가 최적의 무료 솔루션
restix는 플랫폼별 스크립팅(Windows: VBScript+ServerXMLHTTP, macOS: AppleScript+curl)을 활용해 HTTPS 요청을 가능하게 하는 오픈소스 라이브러리다. CS4부터 CC 2024까지 모든 버전에서 작동하며, app.doScript() 메서드를 통해 외부 스크립트를 호출한다.
#include "restix.jsx"
var request = {
url: "https://api.openai.com",
command: "v1/chat/completions",
port: 443,
method: "POST",
headers: [
{name: "Authorization", value: "Bearer YOUR_API_KEY"},
{name: "Content-Type", value: "application/json"}
],
body: JSON.stringify({
model: "gpt-4o",
messages: [{role: "user", content: "수능 영어 빈칸추론 문제 생성"}]
})
};
var response = restix.fetch(request);
var data = JSON.parse(response.body);
상용 솔루션으로는 JSXGetURL($49/년)이 있으며, libcurl 기반의 네이티브 성능과 InDesign Server 지원이 장점이다.
Node.js와 Python 연동 아키텍처
CEP 패널 기반 통합이 가장 성숙한 접근법
CEP(Common Extensibility Platform) 패널은 Chromium 기반 HTML5 환경을 제공하여 fetch API와 XMLHttpRequest를 완벽히 지원한다. 패널 JavaScript에서 API를 호출하고, CSInterface를 통해 ExtendScript와 양방향 통신한다.
┌─────────────────────────────────────────┐
│ CEP Panel (JavaScript/HTML) │
│ ↓ fetch() → LLM API │
│ ↓ CSInterface.evalScript() │
├─────────────────────────────────────────┤
│ ExtendScript Engine (JSX) │
│ ↓ InDesign DOM 조작 │
└─────────────────────────────────────────┘
CEP 패널 JavaScript 예시:
async function generateContent(prompt) {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-4o',
messages: [{role: 'user', content: prompt}]
})
});
const data = await response.json();
const csInterface = new CSInterface();
csInterface.evalScript(
`createTextFrame('${data.choices[0].message.content.replace(/'/g, "\\'")}')`,
(result) => console.log("완료:", result)
);
}
CEP 12가 마지막 메이저 릴리스로 발표되었으나, 보안 업데이트는 계속된다. 신규 프로젝트는 UXP 전환을 고려해야 한다.
UXP가 Adobe의 미래 방향
UXP v8.0이 InDesign 2025(v20.0)에 탑재되었으며, ES6+ 현대 JavaScript와 fetch API를 네이티브 지원한다. .idjs 확장자의 UXP 스크립트는 Scripts Panel에서 직접 실행 가능하다.
// UXP 스크립트 (modern JavaScript)
const { app } = require("indesign");
const fs = require("uxp").storage.localFileSystem;
async function processAIContent() {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: { 'Authorization': 'Bearer API_KEY' },
body: JSON.stringify({ model: 'gpt-4o', messages: [...] })
});
const data = await response.json();
const doc = app.activeDocument;
const textFrame = doc.pages[0].textFrames.add();
textFrame.contents = data.choices[0].message.content;
}
Python COM/AppleScript 브릿지
Windows에서는 pywin32를 통한 COM 연결이 가장 안정적이며, macOS에서는 appscript 라이브러리로 AppleScript 브릿지를 구현한다.
# Windows COM 연결
import win32com.client
from openai import OpenAI
client = OpenAI()
app = win32com.client.Dispatch('InDesign.Application.2024')
doc = app.ActiveDocument
# LLM으로 콘텐츠 생성
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "제품 설명 작성"}]
)
# InDesign에 텍스트 배치
page = doc.Pages[0]
text_frame = page.TextFrames.Add()
text_frame.GeometricBounds = [0, 0, 100, 200]
text_frame.Contents = response.choices[0].message.content
실무 워크플로우 설계
파일 기반 데이터 교환이 가장 범용적
LLM API 호출과 InDesign 스크립트 실행을 JSON 파일로 연결하는 방식이 플랫폼 독립적이고 디버깅이 용이하다.
전체 파이프라인:
[Node.js/Python] [JSON 파일] [InDesign]
LLM API 호출 ────▶ layout_data.json ────▶ JSX 스크립트
콘텐츠 생성 데이터 저장 문서 생성
JSON 데이터 구조 예시:
{
"elements": [
{
"type": "text",
"content": "Spring Collection 2025",
"style": "Headline",
"bounds": [50, 50, 100, 500]
},
{
"type": "image",
"path": "/images/hero.jpg",
"bounds": [110, 50, 300, 500]
}
]
}
ExtendScript JSON 처리 (json2.js 필요):
#include "json2.js"
var jsonFile = File(Folder.myDocuments + "/layout_data.json");
jsonFile.open('r');
var data = JSON.parse(jsonFile.read());
jsonFile.close();
var doc = app.activeDocument;
var page = doc.pages[0];
for (var i = 0; i < data.elements.length; i++) {
var elem = data.elements[i];
if (elem.type === "text") {
var tf = page.textFrames.add({
geometricBounds: elem.bounds,
contents: elem.content
});
try {
tf.paragraphs.everyItem().appliedParagraphStyle =
doc.paragraphStyles.itemByName(elem.style);
} catch (e) {}
}
if (elem.type === "image") {
var imgFrame = page.rectangles.add({geometricBounds: elem.bounds});
imgFrame.place(new File(elem.path));
imgFrame.fit(FitOptions.FILL_PROPORTIONALLY);
}
}
Node.js에서 InDesign 스크립트 트리거
// generate-and-run.js
import OpenAI from 'openai';
import { spawn } from 'child_process';
import fs from 'fs';
const openai = new OpenAI();
async function generateDocument(prompt) {
// 1. LLM으로 콘텐츠 생성
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{role: 'user', content: prompt}],
response_format: { type: "json_object" }
});
// 2. JSON 파일 저장
const layoutData = JSON.parse(completion.choices[0].message.content);
fs.writeFileSync('./layout_data.json', JSON.stringify(layoutData, null, 2));
// 3. InDesign 스크립트 실행 (macOS)
spawn('osascript', ['-e',
`tell application "Adobe InDesign 2025" to do script "${scriptPath}" language javascript`
]);
}
AI 통합 플러그인 현황
MATE for InDesign이 현재 최고의 상용 솔루션
MATE(omata.io)는 ChatGPT, Claude, Gemini, Mistral API를 직접 통합한 InDesign 플러그인으로, 자연어 명령을 스크립트로 변환하고 자동 실행한다. 텍스트 번역, 길이 조절, GREP 패턴 생성, 이미지 플레이스홀더 생성 기능을 제공한다. $39 일회성 구매(BYOK 방식)로 사용 가능하다.
오픈소스 대안:
-
OpenAI for InDesign (Roland Dreger, GitHub): GPT-4o 지원 UXP 플러그인, 번역/텍스트 요약/GREP 생성 기능
-
Lorem Chatum (Adam Twardoch): ChatGPT 기반 맥락 인식 플레이스홀더 텍스트 생성
Data Merge의 한계와 서드파티 도구
InDesign 내장 Data Merge는 5,000개 미만 레코드의 간단한 프로젝트에 적합하지만, 조건부 서식/콘텐츠 불가, 맞춤 페이지 레이아웃 불가, 대량 데이터셋 크래시 등의 제약이 있다.
| 도구 | 가격 | 용도 |
|---|---|---|
| EasyCatalog | $1,898/seat | 엔터프라이즈 카탈로그 |
| InData Pro | \~$387 | 데이터베이스 동기화 |
| DataLinker | $229/년 | 중소규모 자동화 |
| Pagination.com | SaaS | 클라우드 기반 |
수능 영어 문항 생성 전략
문항 유형별 구조와 프롬프트 설계
빈칸 추론(31-34번) – 최고 난이도 문항:
Generate a CSAT English 빈칸추론 question.
SPECIFICATIONS:
- Academic passage (180-220 words) about [심리학/사회과학/자연과학]
- Blank contains a phrase (8-15 words) expressing [핵심 논지/논리적 결론]
- Difficulty: 3점 고난도
DISTRACTOR REQUIREMENTS:
- All 5 options similar in length and grammatical structure
- Include one "attractive distractor" that appears correct but contradicts a subtle detail
- Each distractor relates to passage topic but is logically incorrect
Output JSON format:
{
"passage": "Full text with ___________",
"question_stem": "다음 빈칸에 들어갈 말로 가장 적절한 것은? [3점]",
"choices": ["① ...", "② ...", "③ ...", "④ ...", "⑤ ..."],
"correct_answer": 2,
"explanation": "정답 근거 및 오답 분석"
}
순서 배열(36-37번):
Generate a CSAT English 순서배열 question.
STRUCTURE:
1. Opening paragraph (2-3 sentences) introducing topic
2. Three paragraphs (A), (B), (C) each 2-3 sentences
COHERENCE MARKERS:
- Paragraph A: demonstrative reference (This, These, Such)
- Paragraph B: contrast/addition marker (However, Moreover)
- Paragraph C: conclusion marker (Therefore, As a result)
Ensure ONLY ONE correct ordering is logically valid.
Create clear topic chains: repeated keywords, synonyms, pronouns.
난이도 조절 파라미터
| 파라미터 | 쉬움(2점) | 보통(2-3점) | 어려움(3점) |
|---|---|---|---|
| 어휘 수준 | EBS 고빈도 | 혼합 | 저빈도, 학술적 |
| 문장 복잡도 | 단문/중문 | 복문 1-2절 | 다중 내포절 |
| 추론 깊이 | 직접 재진술 | 1단계 추론 | 다단계 추론 |
| 지문 길이 | 120-150단어 | 150-200단어 | 200-250+단어 |
| 오답 유사도 | 명확히 구분 | 중간 | 매우 유사 |
프롬프트 엔지니어링 최적화
형식 지정 프롬프트가 가장 효과적:
당신은 대한민국 수능 영어 출제위원입니다.
다음 형식을 반드시 따라 문제를 생성하세요:
지문: (주제와 관련된 학술적 지문 180-220단어)
질문: (문제 유형에 맞는 질문문)
선지:
① (선택지 1)
② (선택지 2)
③ (선택지 3)
④ (선택지 4)
⑤ (선택지 5)
정답: (정답 번호)
해설: (정답 근거와 오답 분석)
Let's think step by step. 단계별로 생각하며 문제를 만드세요.
KICE_slayer_AI_Korean 연구 결과, GPT o1-preview가 88점(1등급, 상위 4%)을 기록했으며, GPT-4는 평균 68점(4등급)을 달성했다. 영어 프롬프트에 한국어 요구사항 조합이 최적의 성능을 보였다.
배치 처리를 위한 InDesign 스크립트 예시
텍스트 프레임과 테이블 생성
// 텍스트 프레임 생성 및 스타일 적용
function createStyledTextFrame(page, bounds, content, styleName) {
var textFrame = page.textFrames.add({
geometricBounds: bounds,
contents: content
});
try {
var pStyle = app.activeDocument.paragraphStyles.itemByName(styleName);
if (pStyle.isValid) {
textFrame.paragraphs.everyItem().appliedParagraphStyle = pStyle;
}
} catch (e) {}
textFrame.textFramePreferences.firstBaselineOffset = FirstBaseline.ASCENT_OFFSET;
return textFrame;
}
// 테이블 생성
function createTableFromData(page, bounds, tableData, hasHeader) {
var textFrame = page.textFrames.add({geometricBounds: bounds});
var numRows = tableData.length;
var numCols = tableData[0].length;
var table = textFrame.insertionPoints[0].tables.add({
bodyRowCount: numRows,
columnCount: numCols
});
for (var row = 0; row < numRows; row++) {
for (var col = 0; col < numCols; col++) {
var cell = table.cells.item(col + ":" + row);
cell.contents = String(tableData[row][col]);
if (hasHeader && row === 0) {
cell.fillTint = 20;
cell.texts[0].fontStyle = "Bold";
}
}
}
return table;
}
수능 문항 워크시트 자동 생성
#include "json2.js"
function generateCSATWorksheet(jsonPath) {
var data = readJSONFile(jsonPath);
var doc = app.documents.add();
for (var i = 0; i < data.questions.length; i++) {
var q = data.questions[i];
var page = (i === 0) ? doc.pages[0] : doc.pages.add();
// 문제 번호 및 배점
createStyledTextFrame(page, [20, 20, 35, 100],
q.number + ". [" + q.points + "점]", "QuestionNumber");
// 지문
createStyledTextFrame(page, [40, 20, 150, 400],
q.passage, "PassageText");
// 질문
createStyledTextFrame(page, [155, 20, 170, 400],
q.question_stem, "QuestionStem");
// 선지
var choiceY = 175;
for (var c = 0; c < q.choices.length; c++) {
createStyledTextFrame(page, [choiceY, 20, choiceY + 15, 400],
q.choices[c], "Choice");
choiceY += 18;
}
}
return doc;
}
권장 구현 전략
개발 환경별 최적 접근법
| 환경 | 권장 방법 | 이유 |
|---|---|---|
| 데스크톱 인터랙티브 | CEP 패널 + fetch | 현대 JS, 풍부한 UI |
| 배치 자동화 | restix + JSON 파일 교환 | 단순함, 안정성 |
| 서버/대량 처리 | InDesign Server + SOAP | 멀티인스턴스, 확장성 |
| 신규 프로젝트 | UXP 플러그인 | 미래 지향, ES6+ |
3단계 구현 로드맵
1단계 – 프롬프트 개발:
-
형식 지정 프롬프트 + Zero-shot-CoT 조합
-
문항 유형별 JSON 스키마 정의
-
난이도 파라미터 테스트
2단계 – 파이프라인 구축:
-
Node.js/Python으로 LLM API 호출 스크립트
-
JSON → InDesign Data Merge CSV 변환
-
InDesign 템플릿 설계 (스타일, 마스터 페이지)
3단계 – 자동화 및 품질 관리:
-
배치 내보내기 (PDF 워크시트 + 정답지)
-
인간 검토 워크플로우 통합
-
피드백 기반 프롬프트 개선
이 시스템으로 수능 영어 문항 대량 생성이 실현 가능하며, LLM의 품질 향상에 따라 점진적으로 자동화 범위를 확대할 수 있다. 핵심은 LLM 출력을 구조화된 JSON으로 받아 InDesign 스크립트가 해석할 수 있는 형태로 변환하는 것이다.
답글 남기기