챗으로 만들기
아래 글 전체를 복사해 평소 쓰는 챗(ChatGPT·Claude·Gemini 등)에 붙여넣고, 맨 끝에 원하는 기능을 적어 보내세요. 챗이 휩셋 JSON을 돌려주면 그대로 복사해 휩휩 패널의 가져오기 칸에 붙여넣으면 됩니다. 고칠 곳이 있으면 패널이 목록을 주고, 그 목록을 챗에 다시 붙여넣으면 됩니다.
지금부터 휩휩(WhipWhip)의 휩셋을 설계해서 JSON 객체 하나로 써 주세요. 이 안내를 끝까지 먼저 읽으세요. 맨 끝 "내 요청" 아래에 제가 원하는 것을 적습니다. 꼭 필요한 정보가 빠졌을 때만 짧은 질문 하나를 하고, 그렇지 않으면 바로 JSON으로 답해 주세요.
휩휩이 무엇인가
휩휩은 브라우저 확장입니다. 제가 쓰는 웹챗(ChatGPT·Claude·Gemini·Grok·Perplexity) 위에 패널을 띄우고, 저장해 둔 절차를 그 챗 안에서 대신 실행합니다. 입력창에 글을 쓰고, 보내고, 답을 기다리고, 답을 읽어 일부를 저장하고, 결과를 보여 줍니다.
- 휩셋은 휩을 모은 이름 있는 묶음입니다. 당신이 쓸 것이 이것입니다.
- 휩은 버튼 하나입니다. 누르면 그 휩의 카드를 위에서 아래로 차례대로 실행합니다.
- 카드는 한 단계입니다. 프롬프트 쓰기, 보내기, 답을 변수에 저장하기, 저에게 묻기, 다른 대화로
옮기기, 결과 보여 주기 같은 것입니다. 모든 카드에는
card이름과config설정이 있습니다. - 변수는 이 휩셋의 휩들이 함께 쓰는 이름 있는 값입니다. 값은 실행이 끝나도 남기 때문에, 한 휩이 저장한 것을 다른 휩이 나중에 읽을 수 있습니다.
- 태그는 역할입니다. 특정 대화 하나에 붙이는 이름입니다(예:
writer,critic). 휩은 지금 대화에 역할을 붙이고, 나중에 그 대화로 돌아갈 수 있습니다. 서로 다른 두 챗 사이에 일을 넘기는 방법이 이것입니다.
휩휩은 API를 부르지 않습니다. 모든 일이 실제 챗 페이지에서, 제가 직접 입력한 것과 똑같이 일어납니다. 그래서 휩은 사람이 그 페이지에서 할 수 있는 일을 카드 하나씩 할 수 있을 뿐입니다.
카드가 어떻게 이어지나
챗과 대화하기. prompt_write는 입력창에 글을 넣습니다(보내지는 않습니다). submit은 그 글을
보내고 답이 다 나올 때까지 기다립니다. submit 뒤에는 답을 쓸 수 있습니다.
답 남기기. var_save에 "valueSource": "var.last.assistant"를 주면 가장 최근 답 전체를 변수에
저장합니다. 결과를 남기는 기본 방법입니다. ask_and_extract는 답에서 짧은 이름 붙은 값(제목,
점수, 분류)을 뽑을 때 씁니다 — 프롬프트 끝에 값을 태그로 덧붙이라는 지시를 더하고 그 값을 읽습니다.
긴 답 전체를 담는 데 쓰지 마세요. extract_response는 별도 임시 탭에서 구조화된 JSON을 받아 옵니다.
드물게만 쓰세요. validate는 최근 답이 형식(JSON, 정규식, 비어 있지 않음)을 지켰는지 보고, 아니면
챗에게 다시 요청합니다.
저에게 묻기. 두 가지입니다.
user_input변수를 프롬프트에 토큰으로 넣습니다. 휩이 실행되기 전에 휩휩이 그 휩에 필요한user_input변수마다 작은 입력 폼을 보여 줍니다. 기본이고 보통 가장 좋습니다.input_prompt는 실행 도중, 그 카드가 있는 자리에서 묻습니다. 그 순간에만 의미가 있는 질문 (예: 답을 읽은 뒤 "이 스크랩 이름은?")이거나,"alwaysAsk": true로 이미 채워진 값을 확인받을 때 씁니다.
choice_prompt는 선택지에서 고르게 합니다. 고정 목록(options에 한 줄에 하나)이나 목록 변수의
항목에서 고를 수 있습니다.
결과 보여 주기. show_result_modal은 변수로 만든 글을 창으로 띄웁니다. 제가 복사할 것 같으면
"copyButton": "copy_body"를 주세요.
대화 옮겨 다니기. new_chat은 같은 서비스에서 새 대화를 엽니다. open_service는 다른 서비스로
갑니다. open_url은 주소를 엽니다. tag_current_chat은 실행이 서 있는 대화에 역할을 붙입니다.
go_to_role은 그 역할을 가진 대화로 실행을 옮깁니다. 역할은 어떤 휩이 go_to_role로 가기 전에
먼저 tag_current_chat으로 붙어 있어야 합니다. 그래서 역할이 둘인 셋은 보통 역할마다 짧은 "시작"
휩을 두어 그 챗에 역할을 알려 주고 태그를 붙입니다: prompt_write(이 대화에서 너는 누구다) →
submit → tag_current_chat.
목록. "valueType": "array" 변수는 레코드 목록을 담습니다. append_item은 레코드를 더하고
(fields는 이름/값 쌍 목록, autoId는 레코드마다 id를 붙입니다), upsert_item은 id로 더하거나
바꾸고, patch_item은 레코드 하나의 일부 필드를 바꾸고, remove_item은 하나를 지웁니다.
derive_index는 목록을 글로 바꿔(항목마다 한 줄, <<item.field>> 토큰이 든 템플릿으로) 다른 변수에
저장합니다. 그래야 프롬프트나 결과 창이 그 목록을 보여 줄 수 있습니다. 여러 번 실행에 걸쳐 무언가를
기억하는 셋(노트, 라이브러리, 기록)은 목록으로 만듭니다.
변수.
source: "user_input"— 제가 줍니다(실행 전 폼, 또는input_prompt).source: "set_by_action"— 카드가 씁니다:var_save,input_prompt,choice_prompt,ask_and_extract,extract_response,validate(그variable),derive_index, 목록 카드.source: "constant"—defaultValue에 적은 고정 글.- 키는 영문자·숫자·
_만 씁니다. 라벨은 제가 보는 이름이니 제 언어로 쓰세요. - 카드가 쓰는 변수는 전부
variables에 선언해야 합니다.
토큰
카드 글 안에서 변수는 **<<var.key>>**로 씁니다 — 양쪽에 꺾쇠 두 개씩입니다. 목록 템플릿 안에서는
<<item.field>>입니다. <<now>>는 오늘 날짜입니다.
중괄호로 토큰을 쓰지 마세요. <<…>>는 휩휩이 알아서 바꿉니다.
JSON 모양
{
"format": "whipwhip.authoring/1",
"name": "…", 셋 이름, 제 언어로
"description": "…", 선택, 한 문장
"inline_guide": "…", 선택, 셋 쓰는 법
"tags": [ { "name": "writer" } ], 역할. A–Z a–z 0–9 _ - 로 3–10자
"variables": [ { "key": "…", "label": "…", "source": "…", "required": true } ],
"whips": [
{
"label": "…", 버튼 글, 짧게
"description": "…", 선택
"preflightStyle": "form", 선택: "form"(기본) 또는 "none"
"scopeTags": [ "writer" ], 선택: 이 휩이 속한 역할 대화
"actions": [ { "card": "prompt_write", "config": { "text": "…" } } ]
}
]
}
id, usedVars, requiresVars, producesVars, askInline, 키, 서명, 버전은 쓰지 마세요.
휩휩이 채웁니다.
카드 레퍼런스
prompt_write
채팅창에 내용을 입력하거나 수정합니다.
text— 글, 필수, <<var.key>> 토큰 가능mode— 다음 중 하나replace·append·prependpreflight— true 또는 false. 프롬프트의 <<var.key>> 토큰에 대해 실행 전 입력 폼을 표시합니다inputStyle— 다음 중 하나form·inline, 쓰이는 조건:preflight=true
submit
작성된 내용을 전송하고, 대기를 끄지 않았다면 AI의 응답을 기다립니다.
skipWait— true 또는 false. 전송 직후 다음 액션으로 넘어갑니다. 휩이 응답을 읽지 않을 때 사용합니다 — 예: 같은 프롬프트를 여러 탭에 뿌리는 경우.
input_prompt
사용자에게 필요한 정보를 입력받습니다.
title— 글selectedVars—[{ "key": …, "question": … }], 필수inputStyle— 다음 중 하나form·inlinealwaysAsk— true 또는 false. 변수에 이미 값이 있어도 이 입력을 표시해, 프리필된(또는 LLM이 뽑은) 값을 커밋 전에 검토·수정할 수 있게 합니다
ask_and_extract
AI에게 질문하고 필요한 정보를 변수로 자동화하여 추출합니다.
text— 글, 필수, <<var.key>> 토큰 가능preflight— true 또는 false. 프롬프트의 <<var.key>> 토큰에 대해 실행 전 입력 폼을 표시합니다inputStyle— 다음 중 하나form·inline, 쓰이는 조건:preflight=truevarsToExtract—[{ "key": …, "description": … }], 필수
extract_response
AI의 응답을 분석하여 구조화된 데이터로 변환합니다. 처리하는 동안 임시 탭이 포그라운드로 열립니다.
key— 변수 키, 필수. 캡처한 값을 저장할 변수 이름입니다.schema— 글, 필수. AI가 반환할 JSON의 구조를 설명합니다.promptSuffix— 글. 추출 프롬프트에 추가되는 선택적 텍스트입니다.retries— 숫자. 유효하지 않은 JSON일 때 다시 요청할 횟수입니다.
validate
응답이 형식을 지켰는지 보고 아니면 다시 요구합니다. 형식만 봅니다 — 내용이 맞는지는 판정할 수 없습니다.
source— 다음 중 하나last_assistant·var. 직전 응답 또는 저장된 변수. 변수는 검사만 합니다 — 다시 물어도 과거 값은 안 바뀝니다.key— 변수 키, 쓰이는 조건:source=varrule— 다음 중 하나json·regex·non_empty·whipset, 필수. JSON: 파싱됨(필수 키 지정 가능). 정규식: 패턴 일치. 비어있지 않음: 공백이 아닌 응답. 휩셋: 챗이 쓴 휩휩 휩셋 JSON — 틀리면 고칠 곳 목록을 실어 다시 요구합니다.pattern— 글, 쓰이는 조건:rule=regexrequiredKeys— 글, 쓰이는 조건:rule=json. 쉼표로 구분한 최상위 키 목록.retries— 숫자. 실패로 끝내기 전 교정 프롬프트를 보낼 횟수. 0 = 검사만.correction— 글. 형식이 안 맞을 때 보냅니다. 비우면 기본 문구를 씁니다.variable— 변수 키
send_to_services
같은 글을 고른 AI들에 보내고, 모든 답을 기다려 한 변수에 모읍니다. 지금 탭의 AI는 지금 탭에, 나머지는 뒤쪽 새 탭에 보냅니다.
servicesVar— 변수 키, 필수. AI 서비스 id의 JSON 배열이 담긴 변수. 보통 "AI 서비스" 소스 + 여러 개 선택으로 채웁니다.text— 글, 필수, <<var.key>> 토큰 가능. 모든 AI에 똑같이 보낼 글. 변수 토큰을 쓸 수 있습니다.tagPrefix— 글. 주면 AI마다 "이름_약자" 태그(약자 gpt·gem·cla·grk·ppx)를 대화에 붙여 다음에 이어서 물을 수 있게 합니다. 이름은 6자까지.key— 변수 키, 필수. AI마다 제목과 답(또는 실패 사유)이 적힌 글이 저장됩니다.
var_save
작성기, AI 응답 등의 내용을 변수에 담아 저장합니다.
valueSource— 아래 값 출처 중 하나, 또는var.<변수 키>, 필수. 값을 읽어올 위치를 선택합니다.key— 변수 키, 필수. 캡처한 값을 저장할 변수 이름입니다.valueFilter— 다음 중 하나""·code, 다음 값에 따라 쓰임valueSource
var_flush
저장된 모든 변수 값을 초기화합니다.
설정 없음 — "config": {}.
append_item
배열 변수에 항목을 추가합니다 (예: ADR 목록에 레코드 추가).
key— 변수 키, 필수. 변경할 배열 타입 변수. 먼저 변수 타입을 "array"로 설정하세요.fields—[{ "name": …, "value": … }], 필수, <<var.key>> 토큰 가능. 추가할 레코드의 필드(이름 → 값). 값에 <<var.x>> 토큰 사용 가능, 따옴표·개행은 자동 처리됩니다.autoId— true 또는 false. id를 직접 넣지 않으면 새 항목마다 안정적으로 증가하는 id를 붙입니다.idPrefix— 글, 쓰이는 조건:autoId=true. 숫자 앞에 붙는다. 예: "adr-" → adr-1, adr-2 …
upsert_item
"id" 필드로 매칭해 배열 변수의 항목을 삽입하거나 갱신합니다.
key— 변수 키, 필수. 변경할 배열 타입 변수. 먼저 변수 타입을 "array"로 설정하세요.fields—[{ "name": …, "value": … }], 필수, <<var.key>> 토큰 가능. 삽입/갱신할 레코드의 필드. "id" 필드를 포함하세요 — 교체할 기존 항목을 매칭합니다.
patch_item
id로 매칭한 항목의 지정 필드만 수정하고 나머지 필드는 유지합니다 (예: 상태만 전환).
key— 변수 키, 필수. 변경할 배열 타입 변수. 먼저 변수 타입을 "array"로 설정하세요.itemId— 글, 필수, <<var.key>> 토큰 가능. 부분수정할 항목의 "id". <<var.x>> 토큰을 지원합니다.fields—[{ "name": …, "value": … }], 필수, <<var.key>> 토큰 가능. 이 필드들만 수정되고 항목의 나머지 필드는 유지됩니다. 값에 <<var.x>> 토큰 사용 가능.
remove_item
"id"로 배열 변수의 항목을 제거합니다.
key— 변수 키, 필수. 변경할 배열 타입 변수. 먼저 변수 타입을 "array"로 설정하세요.itemId— 글, 필수, <<var.key>> 토큰 가능. 제거할 항목의 "id". <<var.x>> 토큰을 지원합니다.
derive_index
배열 변수에서 항목당 한 줄씩 요약/인덱스 문자열을 만듭니다.
sourceKey— 변수 키, 필수. 요약할 배열 변수.key— 변수 키, 필수. 파생된 인덱스 문자열을 받을 변수.mode— 다음 중 하나join·count. 인덱스 문자열(기본), 또는 필터 후 남은 항목 수만.itemTemplate— 글, 쓰일 때 필수, <<item.field>> 토큰 가능, 다음 값에 따라 쓰임mode. 항목마다 렌더링해 줄바꿈으로 연결. <<item.field>> 토큰 사용, 예: <<item.id>> — <<item.title>>.filterField— 글. 이 필드가 아래 값과 맞는 항목만 포함. 비우면 전체 포함.filterOp— 다음 중 하나eq·ne, 다음 값에 따라 쓰임filterField. 필드가 없는 항목은 어느 쪽이든 빈 값으로 칩니다.filterValue— 글, <<var.key>> 토큰 가능, 다음 값에 따라 쓰임filterField. 필터 필드와 비교할 값. <<var.x>> 토큰 지원.sortField— 글. 렌더 전에 이 필드로 정렬합니다. 숫자를 인식하므로 adr-2가 adr-10보다 앞섭니다. 비우면 입력 순서를 유지합니다.sortDir— 다음 중 하나asc·desc, 다음 값에 따라 쓰임sortFieldlimit— 숫자. 최대 이 개수만 유지. 비우면 전체.limitFrom— 다음 중 하나end·start, 다음 값에 따라 쓰임limit
go_to_role
역할(태그)이 결속된 대화로 실행을 옮깁니다.
tagName— 태그 이름tagCandidates— 태그 이름 목록. 이 스텝이 갈 수 있는 역할을 고르세요. 비우면 고정 라우팅입니다. 후보가 전부 결속돼야 실행됩니다.tagVar— 변수 키. 고른 역할 이름이 담긴 변수(예: 선택 스텝이 채움). 후보를 고른 경우에만 쓰입니다.
new_chat
현재 서비스에서 새 대화를 엽니다.
isTemp— 다음 중 하나false·trueopenMode— 다음 중 하나current·new_tab·background
open_service
다른 AI 서비스로 전환합니다 (ChatGPT, Gemini, Claude…).
service— 다음 중 하나chatgpt·gemini·claude·grok·perplexityopenMode— 다음 중 하나current·new_tab·background
open_url
https:// 주소로 이동합니다.
target— 글openMode— 다음 중 하나current·new_tab·background
tag_current_chat
현재 대화에 태그를 붙여 관리합니다.
tagName— 태그 이름, 필수
choice_prompt
사용자에게 옵션 목록을 보여주고, 고른 값을 변수에 담습니다.
label— 글optionsSource— 다음 중 하나static·variable·services. 선택지를 가져올 위치를 지정합니다. "AI 서비스"는 ChatGPT·Claude·Gemini·Grok·Perplexity를 채웁니다.options— 글, 쓰일 때 필수, 다음 값에 따라 쓰임optionsSource. 각 줄이 버튼이 됩니다. 선택한 줄이 변수에 저장됩니다.dynamicOptionsVar— 변수 키, 쓰일 때 필수, 쓰이는 조건:optionsSource=variable. 선택지가 담긴 변수 (한 줄에 하나). 런타임에 파싱됩니다.optionLabel— 글, <<item.field>> 토큰 가능, 쓰이는 조건:optionsSource=variable. 선택지마다 렌더되는 라벨 템플릿. <<item.field>> 토큰 사용, 예: <<item.id>> — <<item.title>>.optionValueField— 글, 쓰이는 조건:optionsSource=variable. 선택된 값으로 쓸 항목 필드(기본 "id"). 뒤의 항목 수정/삭제에 항목 id로 넘깁니다.multiple— true 또는 false. 체크리스트로 띄우고 확인을 누르면 체크한 값들을 JSON 배열로 저장합니다.lockCurrentService— true 또는 false, 쓰이는 조건:optionsSource=services. 여러 개 선택일 때, 휩을 실행한 탭의 AI를 "지금 탭"으로 표시하고 체크한 채 잠급니다.warnInConversation— true 또는 false, 쓰이는 조건:optionsSource=services. 여러 개 선택일 때, 실행한 탭이 이미 대화 중이면 그 AI만 앞 맥락을 안고 답한다고 체크리스트 위에 알립니다.continueGroup— 글, 쓰이는 조건:optionsSource=services. 여러 개 선택일 때, 실행한 탭이 "이름_약자" 태그 무리에 속하면 맨 위에 "이어서 묻기" 행을 기본으로 켜고 그 AI들을 미리 체크합니다. "여러 AI에 보내기"의 태그 이름과 같게 둡니다.rememberAs— 글, 쓰이는 조건:multiple=true. 이름을 주면 이번 선택을 기억해 다음 실행에서 미리 체크합니다. 어느 탭·워크스페이스에서 실행해도 같은 기억을 씁니다.key— 변수 키, 필수. 선택한 항목이 저장될 변수 키입니다.
show_result_modal
변수에 저장된 값을 활용해 결과창을 띄웁니다.
title— 글body— 글, 필수copyButton— 다음 중 하나none·copy_body
import_whipset
변수에 든, 챗이 쓴 휩셋 JSON을 가져옵니다. 저장 전에 미리보기로 확인받습니다.
key— 변수 키, 필수. 보통 앞의 "검사" 카드(휩셋 규칙)가 저장한 변수입니다.
값 출처(var_save.valueSource)
builtin.date_today · builtin.date_iso · builtin.time_now · builtin.timestamp · builtin.day_of_week · builtin.page_url · builtin.page_title · builtin.page_domain · builtin.language · builtin.random_uuid · builtin.selection · composer · var.last.user · var.last.assistant
흔한 실수
<<var.x>>대신 중괄호로 토큰 쓰기.- 아무 카드도 쓰지 않는
set_by_action변수, 또는 글에는 쓰면서 선언하지 않은 변수. submit없이 답 읽기(var_save의var.last.assistant).- 실제로 보내야 하는데
prompt_write뒤에submit을 빠뜨리기. "valueType": "array"가 아닌 변수에 목록 카드 쓰기.- 어떤 휩도
tag_current_chat으로 붙이지 않는 역할로go_to_role하기, 또는tags에 선언하지 않은 태그. - 10자를 넘거나, 공백이 있거나,
main인 태그 이름. - 카드에 없는 필드를 쓰거나 카드 이름을 지어내기.
- 긴 답 전체를
ask_and_extract로 담기 —var_save의var.last.assistant를 쓰세요. - 모든 걸 하는 거대한 휩 하나. 버튼이 분명한 휩 몇 개가 낫습니다.
예시
대화 하나: 초안을 다듬어 보여 주기
{
"format": "whipwhip.authoring/1",
"name": "초안 다듬기",
"description": "거친 초안을 또렷하게 고쳐 쓰고 결과를 보여 줍니다.",
"tags": [],
"variables": [
{ "key": "draft", "label": "초안", "source": "user_input", "required": true },
{ "key": "polished", "label": "다듬은 글", "source": "set_by_action", "required": false }
],
"whips": [
{
"label": "다듬기",
"actions": [
{ "card": "prompt_write", "config": { "text": "아래 초안을 또렷하고 간결하게 고쳐 써 줘. 내 뜻과 말투는 지켜 줘. 고친 글만 답해.\n\n<<var.draft>>", "mode": "replace" } },
{ "card": "submit", "config": {} },
{ "card": "var_save", "config": { "valueSource": "var.last.assistant", "key": "polished" } },
{ "card": "show_result_modal", "config": { "title": "다듬은 글", "body": "<<var.polished>>", "copyButton": "copy_body" } }
]
}
]
}
역할 둘: 서로 다른 챗의 작가와 비평가
{
"format": "whipwhip.authoring/1",
"name": "작가와 비평가",
"inline_guide": "챗 하나를 열고 '작가 시작', 다른 챗을 열고 '비평가 시작'을 누르세요. 그다음 어디서든 '쓰고 검토받기'를 실행합니다.",
"tags": [ { "name": "writer" }, { "name": "critic" } ],
"variables": [
{ "key": "task", "label": "쓸 것", "source": "user_input", "required": true },
{ "key": "draft", "label": "초안", "source": "set_by_action", "required": false },
{ "key": "review", "label": "비평", "source": "set_by_action", "required": false },
{ "key": "final", "label": "최종본", "source": "set_by_action", "required": false }
],
"whips": [
{
"label": "작가 시작",
"actions": [
{ "card": "prompt_write", "config": { "text": "이 대화에서 너는 내 작가야. 완성된 초안을 쓰고, 내가 비평을 가져오면 고쳐 써. '좋아'라고만 답해.", "mode": "replace" } },
{ "card": "submit", "config": {} },
{ "card": "tag_current_chat", "config": { "tagName": "writer" } }
]
},
{
"label": "비평가 시작",
"actions": [
{ "card": "prompt_write", "config": { "text": "이 대화에서 너는 까다로운 비평가야. 초안을 보여 주면 가장 약한 지점을 짧은 번호 목록으로 짚어. '좋아'라고만 답해.", "mode": "replace" } },
{ "card": "submit", "config": {} },
{ "card": "tag_current_chat", "config": { "tagName": "critic" } }
]
},
{
"label": "쓰고 검토받기",
"actions": [
{ "card": "go_to_role", "config": { "tagName": "writer" } },
{ "card": "prompt_write", "config": { "text": "<<var.task>>", "mode": "replace" } },
{ "card": "submit", "config": {} },
{ "card": "var_save", "config": { "valueSource": "var.last.assistant", "key": "draft" } },
{ "card": "go_to_role", "config": { "tagName": "critic" } },
{ "card": "prompt_write", "config": { "text": "과제: <<var.task>>\n\n초안:\n<<var.draft>>", "mode": "replace" } },
{ "card": "submit", "config": {} },
{ "card": "var_save", "config": { "valueSource": "var.last.assistant", "key": "review" } },
{ "card": "go_to_role", "config": { "tagName": "writer" } },
{ "card": "prompt_write", "config": { "text": "이 비평을 반영해 초안을 고쳐 줘. 고친 전문을 답해.\n\n<<var.review>>", "mode": "replace" } },
{ "card": "submit", "config": {} },
{ "card": "var_save", "config": { "valueSource": "var.last.assistant", "key": "final" } },
{ "card": "show_result_modal", "config": { "title": "초안 · 비평 · 최종본", "body": "[초안]\n<<var.draft>>\n\n[비평]\n<<var.review>>\n\n[최종본]\n<<var.final>>", "copyButton": "copy_body" } }
]
}
]
}
쌓이는 목록: 답 스크랩 노트
{
"format": "whipwhip.authoring/1",
"name": "답 스크랩 노트",
"tags": [],
"variables": [
{ "key": "clip", "label": "스크랩한 답", "source": "set_by_action", "required": false },
{ "key": "clip_title", "label": "제목", "source": "set_by_action", "required": false },
{ "key": "notes", "label": "노트", "source": "set_by_action", "valueType": "array", "required": false },
{ "key": "notes_index", "label": "노트 목록", "source": "set_by_action", "required": false },
{ "key": "notes_full", "label": "노트 전문", "source": "set_by_action", "required": false },
{ "key": "summary", "label": "요약", "source": "set_by_action", "required": false }
],
"whips": [
{
"label": "이 답 저장",
"actions": [
{ "card": "var_save", "config": { "valueSource": "var.last.assistant", "key": "clip" } },
{ "card": "input_prompt", "config": { "title": "이 답 저장", "selectedVars": [ { "key": "clip_title", "question": "짧은 제목을 붙여 주세요" } ], "inputStyle": "inline", "alwaysAsk": true } },
{ "card": "append_item", "config": { "key": "notes", "autoId": true, "idPrefix": "note-", "fields": [ { "name": "title", "value": "<<var.clip_title>>" }, { "name": "text", "value": "<<var.clip>>" }, { "name": "date", "value": "<<now>>" } ] } },
{ "card": "derive_index", "config": { "sourceKey": "notes", "key": "notes_index", "itemTemplate": "<<item.id>> — <<item.title>> (<<item.date>>)" } },
{ "card": "show_result_modal", "config": { "title": "노트", "body": "<<var.notes_index>>" } }
]
},
{
"label": "노트 요약",
"actions": [
{ "card": "derive_index", "config": { "sourceKey": "notes", "key": "notes_full", "itemTemplate": "### <<item.title>>\n<<item.text>>" } },
{ "card": "new_chat", "config": { "openMode": "current" } },
{ "card": "prompt_write", "config": { "text": "이 노트들에 공통으로 흐르는 것과 합치면 무엇이 되는지 정리해 줘.\n\n<<var.notes_full>>", "mode": "replace" } },
{ "card": "submit", "config": {} },
{ "card": "var_save", "config": { "valueSource": "var.last.assistant", "key": "summary" } },
{ "card": "show_result_modal", "config": { "title": "요약", "body": "<<var.summary>>", "copyButton": "copy_body" } }
]
}
]
}
출력 규칙
- 제가 어떤 휩을 어떤 순서로 누를지 먼저 생각하고, 동작하는 가장 작은 셋을 설계하세요.
- 이름·라벨·질문·프롬프트·결과 제목은 제가 요청을 쓴 언어로 쓰세요. 카드 이름, 필드 이름, 변수 키, 태그 이름은 이 안내에 적힌 그대로 둡니다.
- 휩셋 전체를 담은 JSON 코드블록 하나로 답하세요. 블록 뒤에 어떤 버튼부터 누르면 되는지 짧은 문장 두 개까지만 덧붙여도 됩니다.
- 제가 휩휩이 알려 준 고칠 곳 목록을 붙여넣으면, 전부 고쳐서 완전한 JSON을 다시 보내 주세요. 고친 부분만 보내지 마세요.