프로젝트 한 줄 소개
글쓰기를 시작하게 돕는 첫 문장 생성기
이 프로젝트는 "짧은 글을 대신 써주는 도구"가 아니라, 사용자가 첫 문장을 선택함으로써 글을 시작하게 만드는 도구를 목표로 했다.
문제 정의
처음에는 다음과 같은 아이디어에서 출발했다.
"키워드만 입력하면 짧은 글을 완성해주는 도구"
하지만 구체화 과정에서, 내가 해결하려던 문제의 본질은 다르다는 점을 확인했다.
관찰한 문제
- 글쓰기가 멈추는 지점은 대부분 완성 단계가 아니라 시작 단계
- 키워드는 떠오르지만 첫 문장이 정리되지 않아 글이 미뤄짐
- 완성형 결과물을 제공해도 사용자의 글로 자연스럽게 이어지지 않음
문제 재정의
문제의 핵심은 "글을 잘 쓰지 못하는 것"이 아니라 글을 시작하지 못하는 상태였다.
따라서 목표를 다음과 같이 재정의했다.
- ❌ 완성된 글을 대신 만들어주는 도구
- ✅ 사용자가 선택을 통해 시작할 수 있게 돕는 도구
핵심 설계 방향
왜 "입력"보다 "선택"인가
- 첫 문장을 직접 입력하게 하면 시작 장벽이 다시 생긴다
- 첫 문장을 선택하게 하면 최소한의 책임이 발생한다
- 선택된 문장은 이후 전개에 대한 자연스러운 동기가 된다
이 프로젝트는 완성보다 착수를 돕는 도구를 만드는 것이 본질이다.
MVP 설계
입력
- 키워드: 3~5개
- 톤 선택
- 담담
- 건조
- 감정적
- 서사적
출력
- 첫 문장 후보 3개
- 각 후보는 한 문장
- 결말을 내리지 않고 이후 전개가 열려 있는 구조
시스템 구조
[Browser]
└─ keywords, tone
↓
[Node.js / Express API]
└─ SYSTEM_PROMPT + user input
↓
[Sentence Generation]
설계 결정
프롬프트는 클라이언트가 아니라 서버에 고정했다.
이유는 다음과 같다.
- 프롬프트 규칙 일관성 유지
- 실험 및 수정 용이
- API 키 보안
- 클라이언트 로직 단순화
구현과 1차 검증
개발 환경
| 영역 | 기술 | |------|---| | Backend | Node.js, Express | | Frontend | HTML, Vanilla JavaScript | | AI 연동 | OpenAI 호환 Responses / Chat Completions 계열 API |
API 구조
-
엔드포인트 : POST /api/first-lines
-
Request 예시
Copy{
"keywords": ["고독", "새벽", "귀가"],
"tone": "담담"
}
- Response 예시
Copy{
"result": "첫 문장 후보 텍스트"
}
초기 이슈와 Mock 모드 도입
개발 초기에 API 호출 과정에서 429 quota exceeded 문제가 발생했다.
이 오류는 코드 문제가 아니라 계정/결제 한도 문제였고, 개발이 멈추지 않도록 Mock 모드를 도입했다.
Mock 모드 도입 목적
- 서버–프론트 연결 검증
- 입력 → 처리 → 출력 흐름 확인
- "선택 가능한 첫 문장 후보"라는 UX 개념 검증
이 판단 덕분에 실제 모델 연동 전에도 도구의 구조와 감각을 검증할 수 있었다.
프롬프트 설계와 톤 실험
이 단계의 고민은 문장 품질보다 출력 규칙이었다.
- 프롬프트 설계 원칙
- 한 문장만 출력
- 결말·정리 금지
- 질문형 문장 금지
- 상황·관찰 중심
###톤 재정의
| 톤 | 설계 방식 | |------|---| | 건조 | 단문, 행동/상태 중심 | | 담담 | 관찰 중심, 감정 최소 | | 감정적 | 단일 감정 감각화 | | 서사적 | 시간·사건 암시 |
초기에는 톤 값이 실제 문장에 충분한 차이를 만들지 못했다. 그래서 톤을 형용사처럼 다루지 않고, 문장의 방향성 규칙으로 재정의했다.
한국어 자연어 처리 개선
- 조사(로/으로) 처리 문제 발견
- 받침 여부 기반 자동 보정 로직 추가
- 문장 자연스러움 개선
- 이 프로젝트의 핵심 검증 기준은 문장이 얼마나 잘 쓰였는가가 아니라, 사용자가 실제로 문장을 선택하는가였다.
선택형 UI와 행동 검증
선택형 UI 설계
- 후보 문장을 카드 형태로 표시
- 클릭 시 선택 상태가 시각적으로 드러나도록 구성
- 선택된 문장은 별도 영역에 고정
- 선택 이후 복사 및 이어 쓰기 가능
재생성 흐름
같은 키워드·톤 조건에서도 여러 후보를 비교할 수 있도록 "다시 생성" 흐름을 추가했다.
이 기능은 단순 편의 기능이 아니라, 선택 행동을 관찰하기 위한 장치로 설계했다.
사용자 선택 로그
문장이 선택될 때마다 다음 정보를 기록했다.
필드 설명 timestamp 선택 발생 시각 keywords 입력된 키워드 목록 tone 선택된 톤 selectedLine 사용자가 선택한 문장
로그는 서버 측에서 selection-logs.jsonl 파일에 한 줄씩 누적 저장되도록 설계했다.
1차 완성 선언
이 프로젝트에서 1차 완성의 기준은 다음과 같았다.
- 핵심 문제 정의가 명확할 것
- 그 문제를 해결하는 최소 기능이 구현되었을 것
- 사용자의 행동이 실제로 발생할 것
- 그 행동이 기록·검증 가능할 것
현재 구현 범위
- 키워드 기반 첫 문장 후보 생성
- 톤 선택에 따른 문장 구조 차별화
- 선택형 UI를 통한 사용자 선택 유도
- 선택된 문장의 고정 표시 및 복사
- 사용자 선택 로그 수집 및 저장
- Mock 기반 실험 환경 구축
이 프로젝트는 문장 품질 경쟁이 아니라 시작 행동을 검증 가능한 구조로 만든 실험 도구로서 1차 완성 상태에 도달했다.
확장: AI API 연동과 디버깅 기록
이후 단계에서는 실제 API 연동을 통해 구조를 확장했다.
- OpenAI SDK 초기 연동 시도
처음에는 OpenAI SDK를 직접 붙이려 했지만, 다음 오류를 만났다.
CopyOpenAIError: Missing credentials. Please pass an apiKey, or set the OPENAI_API_KEY environment variable.
원인
- OPENAI_API_KEY 미설정
- 서버 시작 시점에 SDK 초기화 → 키 없으면 서버 자체가 종료
이 경험을 통해 키 관리가 개발 흐름 자체를 막을 수 있다는 점을 확인했다.
- 프론트/백엔드 실행 환경 충돌 | 환경 | 포트 | |------|---| 프론트 (Live Server) | 127.0.0.1:5500 백엔드 (Express) | localhost:3000
프론트에서 fetch('/api/...') 요청이 5500 포트로 나가면서 API 호출이 계속 실패했다.
해결
- Express에서 정적 파일도 함께 서빙
- 프론트와 백엔드를 동일 포트에서 동작하도록 조정
이후 개발 구조를 실제 서비스 구조에 더 가깝게 맞춤
- 무료 OpenAI 호환 API 탐색과 시행착오
테스트 비용을 줄이기 위해 apifree.ai를 사용했다.
처음에는 잘못된 URL로 요청해 405 Not Allowed를 받았고, 처음엔 서버 오류로 오해했다.
실제 원인
- 사용한 주소는 모델 소개용 웹 페이지
- 실제 API 호출 엔드포인트가 아니었음
문서를 다시 읽고 나서 정확한 엔드포인트와 인증 방식을 확인했다.
- POST https://api.apifree.ai/v1/chat/completions
- Authorization: Bearer API_KEY
- 환경변수 이름 혼선
실제로는 다음처럼 여러 이름을 시도했다.
Copy$env:APIFREE_KEY=...
$env:APIFREE_API_KEY=...
하지만 서버는 API_KEY만 기대하고 있었다.
최종 해결
Copy$env:API_KEY="실제키"
이 과정은 단순 실수라기보다, 실제 환경변수 명세와 구현 기대값이 어긋날 때 얼마나 쉽게 개발 흐름이 꼬일 수 있는지 보여주는 경험이었다.
결과
- 키워드 + 톤 입력 기반 첫 문장 후보 3개 생성 구조 구현
- 선택형 UI와 로그 수집을 통해 사용자 행동 검증 가능
- Mock → 실제 API 연동까지 단계적으로 확장
- 프롬프트 설계, 환경변수, 엔드포인트, 디버깅 과정을 구조적으로 정리
이 프로젝트에서 보여주고 싶은 점
이 프로젝트는 단순한 문장 생성기가 아니다.
- 글쓰기 문제를 "완성"이 아니라 "착수"로 재정의한 점
- 문장 품질보다 사용자 행동을 검증 기준으로 삼은 점
- Mock 기반으로 구조를 먼저 검증한 뒤 API를 붙인 점
- 성공 사례만이 아니라 시행착오와 판단 과정을 기록한 점
한 줄 요약
firstline-tool은 글쓰기의 병목을 "완성"이 아닌 "착수"로 재정의하고, 선택형 UI와 사용자 로그를 통해 사용자의 시작 행동을 검증 가능한 구조로 구현한 첫 문장 생성기 프로토타입이다.



