본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 15. 04:04

미경험 엔지니어가 AI 업무 자동화를 만들며 뼈저리게 느낀 'AI보다 먼저 설계할 것'

요약

AI 업무 자동화 도구를 개발하며 느낀 설계의 중요성을 다룹니다. 프롬프트 최적화보다 데이터 정규화와 입력 정보의 정리가 AI의 성능과 안정성에 더 결정적인 역할을 함을 강조합니다.

핵심 포인트

  • 프롬프트 작성보다 AI에게 전달할 데이터의 정규화가 우선되어야 함
  • 다양한 입력 소스를 공통 포맷으로 변환하여 AI의 판단 안정성 확보
  • 무분별한 알림 발송을 지양하고 유의미한 정보만 필터링하는 설계 필요
  • AI가 헤매지 않도록 입력을 구조화하는 것이 핵심

안녕하세요!

최근 개인적으로 Macbook pro를 구매해서 즐겁게 사용 중인 신입입니다!

AI 에이전트(AI Agent)나 AI 주도 개발(AI-driven development)에 관한 기사가 상당히 늘어나고 있습니다.

저는 아직 미경험 엔지니어에 가까워서, 처음부터 깔끔한 설계가 가능했던 것은 아닙니다.

오히려 처음에는 "AI에게 던지면 어떻게든 되지 않을까?" 정도의 감각이었습니다.

하지만 업무용 AI 자동화 도구를 몇 가지 만들어 보니, AI 그 자체보다 그 전후의 설계가 훨씬 더 중요하다는 것을 알게 되었습니다.

제가 만들었던 것은 예를 들어 다음과 같은 것들입니다.

의뢰 수집·평가·Discord 알림 도구

Gmail, 의뢰 포털, 소개 사이트에서 의뢰 정보 취득

  • Gemini로 의뢰 평가

  • 알림 완료된 의뢰를 중복 제거하여 Discord로 알림

외부 업무 서비스 / Gmail 동기화 파이프라인

외부 서비스나 Gmail에서 의뢰·인재 정보 취득

  • 공통 포맷으로 정규화(Normalization)하여 DB 저장

  • 매칭 후보를 확인하여 Discord 알림

동영상 챕터 편집 도구

동영상 업로드

  • 장면 검출, OCR, 음성 텍스트 변환(Transcription)

  • Gemini로 화면 내용을 분석하여 장(Chapter) 나누기 보조

Cloudflare Worker 기반의 정기 실행 도구

  • Cron으로 외부 데이터 취득
  • D1 / R2 / KV에 상태 저장
  • AI 평가 후 필요한 것만 알림

모두 겉모습은 다르지만, 만들면서 실패하고 수정하는 과정에서 공통점이 보였습니다.

이 기사에서는 미경험에 가까운 제가 AI 업무 자동화 도구를 만들면서, "이 부분을 미리 생각해 두었더라면 나중에 고생하지 않았을 텐데"라고 느낀 점들을 정리합니다.

AI를 도입하면 나도 모르게 가장 먼저 프롬프트(Prompt)를 생각하게 됩니다.

저도 처음에는 프롬프트를 다듬는 데만 매달렸습니다.

하지만 실제로 효과가 있었던 것은 프롬프트 이전에, AI에게 전달할 정보를 어디까지 정리하느냐였습니다.

의뢰 평가 도구에는 입력 소스가 여러 개 있습니다.

Source입구중복 판정
Gmail 알림Gmail message ID / 의뢰 IDmessage ID / matching ID
...

각각 HTML이기도 하고, 메일 본문이기도 하며, GraphQL의 응답(Response)이기도 합니다.

이대로 AI에게 던지면 매번 입력 형식이 너무 달라서 평가가 안정되지 않습니다.

그래서 우선 사람이 읽고 싶은 형태로 모았습니다.

type ProjectForEvaluation = {
source: "gmail" | "project_portal" | "referral_site" | "media";
sourceId: string;
...

AI에게 "이 정보를 판단해 줘"라고 말하기 전에, 먼저 모든 소스를 이 형태로 정규화합니다.

이렇게 하면 프롬프트가 짧아집니다.

다음 의뢰 정보를 S/A/B/C로 평가해 주세요.
평가 이유, 우려 사항, 다음에 사람이 확인해야 할 사항도 출력해 주세요.

AI가 고생하게 만드는 것이 아니라, AI가 헤매지 않는 입력을 만드는 것입니다.

초보자일수록 이 부분을 건너뛰기 쉽지만, 이 부분이 가장 효과적이었습니다.

업무 자동화에서 가장 먼저 저지르기 쉬운 실수는 모든 것을 Discord나 Slack으로 흘려보내는 것입니다.

저도 처음에는 "알림이 오면 편리하겠지"라고 생각했습니다.

하지만 전부 흘려보내면 금방 아무도 보지 않게 됩니다.

의뢰 수집 도구에서는 처음에 여러 입력 소스로부터 의뢰를 모읍니다.

  • Gmail 알림
  • 의뢰 포털
  • 소개 사이트
  • 외부 서비스의 목록 페이지
  • 수동으로 저장한 JSON

여기서 얻은 것을 전부 알림으로 보내면, 알림 채널은 그저 로그(Log) 저장소가 되어 버립니다.

그래서 알림 대상을 좁혔습니다.

function shouldNotifyProject(evaluation: ProjectEvaluation) {
if (evaluation.rank === "S") return true;
if (evaluation.rank === "A" && evaluation.needsHumanReview) return true;
...

알림의 목적은 "처리 결과를 전부 흘려보내는 것"이 아니라, "사람의 다음 행동을 만드는 것"입니다.

이것을 결정하고 나니 화면도 API도 상당히 만들기 쉬워졌습니다.

  • DB에는 전건 저장한다
  • Discord에는 사람이 반응해야 할 것만 보낸다
  • Run logs에서는 취득 건수, 스킵 건수, 실패 이유를 확인한다
  • Raw payload는 나중에 재분석할 수 있도록 남겨둔다

AI가 처리하는 범위와 사람이 판단하는 범위를 나누는 것이 중요했습니다.

이 부분을 나누지 않으면, 미경험자인 저조차도 언뜻 보기에는 대단한 것을 만들 수 있지만, 운용하다 보면 금방 알림 피로 (Notification Fatigue)를 느끼게 됩니다.

AI를 사용한 자동화에서 은근히 중요한 것이 중복 제거 (Deduplication)입니다.

이것은 만들기 전에는 별로 의식하지 못했습니다.

동일한 안건이 여러 경로를 통해 들어오는 경우가 있습니다.

  • Gmail 알림으로 들어옴
  • 안건 사이트 목록에도 나타남
  • 상세 페이지의 URL이 다름
  • 메일 ID는 다르지만 안건 ID는 동일함
  • 본문은 조금 다르지만 실체는 동일함

이것을 AI 평가 (AI Evaluation) 후에 처리하면 불필요하게 토큰 (Token)을 사용하게 됩니다.

따라서 AI에게 전달하기 전에 최대한 걸러냅니다.

type SourceState = {
source: string;
sourceId: string;
...

중복 판정에 사용한 것은 대체로 이 정도입니다.

  • Gmail message ID
  • 외부 서비스 측의 안건 ID
  • URL의 정규화 (Normalization) 결과
  • 상세 본문의 hash
  • 이미 알림을 보낸 state

AI는 편리하지만, 같은 것을 몇 번이고 반복해서 읽게 하면 그냥 돈과 시간이 녹아내립니다.

"AI로 똑똑하게 판단하기" 전에, "애초에 판단할 필요가 없는 것은 전달하지 않기"가 더 효과적이었습니다.

이것은 AI라기보다, 일반적인 시스템 설계 (System Design)에 관한 이야기였습니다. 만들고 나서야 깨달았습니다.

AI 연동이나 외부 API 연동에서는 실패를 전제로 한 설계가 상당히 중요해집니다.

처음에는 성공 패턴만을 보고 만들었습니다.

실제로 만들다 보면 이런 일이 일어납니다.

  • 외부 API가 일시적으로 다운됨
  • HTML 구조가 변경됨
  • Discord 알림만 실패함
  • AI 평가만 타임아웃 (Timeout) 발생
  • 동일한 데이터가 이중으로 취득됨
  • 나중에 동일한 payload를 재처리하고 싶어짐

그래서 처리 결과뿐만 아니라, 취득 원본인 raw payload나 실행 로그 (Execution Log)를 남기도록 했습니다.

type RunLog = {
id: string;
source: string;
...

중요한 것은 처리를 분리하는 것입니다.

  • 취득
  • 정규화 (Normalization)
  • 중복 제거 (Deduplication)
  • AI 평가 (AI Evaluation)
  • 저장
  • 알림

이 중 알림만 실패했다면, 취득이나 AI 평가까지 실패로 처리하지 않습니다.

반대로 AI 평가가 실패하더라도, raw payload가 남아 있다면 나중에 재실행할 수 있습니다.

사소해 보이지만, 이 부분을 구축하면 운용 시의 안심감이 상당히 달라집니다.

미경험 시절에는 에러 화면을 보는 것만으로도 당황스럽지만, 로그가 있으면 "어디까지 성공했고, 어디서 실패했는지"를 추적할 수 있게 됩니다.

AI의 평가 기준이나 출력 포맷 (Output Format)은 운용하다 보면 반드시 바꾸고 싶어집니다.

예를 들어 안건 평가라면,

  • 무엇을 고평가로 할 것인가
  • 예산을 중시할 것인가
  • 납기를 중시할 것인가
  • 기존 사업과의 상성을 중시할 것인가
  • 알림을 보낼 rank의 임계값 (Threshold)을 바꿀 것인가
  • 출력에 "다음에 확인할 것"을 포함할 것인가

처음에는 코드에 직접 작성(Hard-coding)해도 동작합니다.

저도 처음에는 코드에 직접 썼습니다.

하지만 조금만 운용해 보면 금방 조정하고 싶어집니다.

그래서 AI의 평가 설정은 코드로부터 분리하는 것이 편했습니다.

type EvaluationConfig = {
model: string;
rankThreshold: "S" | "A" | "B" | "C";
...

프롬프트 (Prompt)도 역할별로 나누어 두면 다루기 쉽습니다.

PromptTemplate
- system
- extraction
...

AI의 동작은 코드가 아니라 운용 설정으로서 변경할 수 있는 편이 좋습니다.

특히 업무 자동화는 인간의 반응을 보면서 개선해 나가는 것이므로, 코드 배포 (Deployment) 없이도 조정할 수 있는 경계를 만들어 두는 것이 편했습니다.

이 부분도 만들기 전에는 몰랐습니다. 실제로 사용해 보면서 "이걸 매번 배포하는 건 귀찮은데"라고 느낀 뒤에야 알게 되었습니다.

안건 수집이나 알림 같은 처리는 계속 로컬 PC나 VPS에서 돌리는 것보다, Cloudflare Workers로 모으는 것이 운용이 가벼워졌습니다.

처음에는 로컬에서 돌아가면 만족했지만, 제 PC가 꺼져 있으면 돌아가지 않는 시점에서 업무 자동화로서는 약합니다.

예를 들어 안건 평가 툴에서는 Cloudflare Worker를 30분 간격으로 실행합니다.

  • Gmail API를 통해 메일 확인
  • 안건 사이트에서 미처리 안건 취득
  • KV로 처리 완료된 state 확인
  • Gemini로 평가
  • Discord 알림

Mac이 꺼져 있어도 동작합니다.

또한, 별도의 동기화 파이프라인에서는 Cloudflare Native 구성도 검토했습니다.

VPS에도 장점은 있습니다.

  • 기존의 Docker/FastAPI/Postgres를 옮기기 쉽다
  • Playwright 등의 브라우저 자동화가 하기 쉽다
  • 장시간 처리나 디버깅의 자유도가 높다

하지만, 작은 정기 실행 파이프라인이라면 Cloudflare Native 쪽이 운영이 가볍습니다.

  • OS 업데이트를 신경 쓸 필요가 없다
  • Docker daemon을 신경 쓸 필요가 없다
  • 디스크 용량을 걱정할 필요가 없다
  • Cron, DB, Object Storage, 로그, 배포를 동일한 플랫폼으로 모을 수 있다

제 경우, "최종적으로 운영하고 싶은 형태"로부터 역산하면 Cloudflare로 모으는 판단은 상당히 자연스러웠습니다.

미경험자라면 인프라를 크게 잡는 경향이 있지만, 작은 정기 실행이라면 "운영하지 않아도 되는 곳"에 두는 것이 지속 가능합니다.

동영상 챕터 편집 도구에서는 다루는 데이터가 안건(Case)이 아니라 동영상입니다.

하지만 구조는 상당히 비슷합니다.

  • 동영상 파일을 받는다
  • 장면(Scene)을 검출한다
  • 프레임(Frame)을 추출한다
  • OCR을 수행한다
  • 음성을 텍스트로 변환(Transcription)한다
  • Gemini로 화면 내용을 분석한다
  • 챕터 안으로 저장한다
  • 사람이 마지막에 편집한다

여기서도 AI에게 동영상 전체를 통째로 맡기기보다, 먼저 소재를 분해하는 것이 안정적이었습니다.

동영상
↓
장면
...

AI는 마지막 판단 보조로 사용한다.

그 전에, AI가 보기 쉬운 단위로 분해한다.

안건 평가든 동영상 분석이든, 결국 이 부분은 같았습니다.

AI에게 통째로 맡길수록 출력의 결과가 들쭉날쭉해집니다. 미경험자인 저에게는 그 들쭉날쭉함을 바로잡는 것이 더 힘들었습니다.

AI를 사용하면 작업은 빨라집니다.

하지만 빨라지는 만큼 무서운 조작도 늘어납니다.

특히 미경험자 시절에는 AI가 내놓은 명령어(Command)나 수정 사항이 정말 안전한지 판단하기 어려울 때가 있습니다.

특히 이 부분은 AI가 함부로 다루게 하고 싶지 않습니다.

.env

  • API 키
  • OAuth token
  • Webhook secret
  • DB dump
  • 고객 데이터
  • 운영(Production) DB
  • 운영(Production) 알림
  • main branch로의 직접 push

따라서 프로젝트 측에서 "AI에게 보여줄 것"과 "보여주지 않을 것"을 나눌 필요가 있습니다.

제 운영 방식에서는 적어도 다음 사항을 의식하고 있습니다.

.env
.env.*
secrets/
...

나아가 AI에게는 처음에 대상 범위를 좁혀서 의뢰합니다.

나쁜 예:

이 프로젝트를 적당히 고쳐줘

좋은 예:

안건 평가 도구의 중복 제거 로직만 봐주세요.
목적은 동일한 안건을 여러 경로로 가져오더라도 이중 알림이 가지 않도록 하는 것입니다.
운영(Production) DB 조작, 환경 변수 표시, 외부 알림의 실제 전송은 하지 마세요.
...

AI에게 전부 읽히는 것보다 필요한 범위를 지정하는 것이 정확도와 안전성을 모두 높였습니다.

AI가 강력할수록 이쪽의 의뢰가 허술해지는 느낌이 듭니다.

몇 가지를 만들어 보면서 AI 업무 자동화 도구에는 공통 패턴이 있다는 것을 느꼈습니다.

처음부터 알고 있었던 것이 아니라, 몇 개를 만들어 보고 나서야 겨우 보이기 시작한 느낌입니다.

외부 입력
↓
정규화
...

AI 부분만 보면 화려하지만, 실제로 중요한 것은 그 주변입니다.

  • 입력을 정돈한다
  • 상태(State)를 가진다
  • 중복을 방지한다
  • 실패해도 추적할 수 있다
  • 사람이 판단하는 출구(Exit)를 만든다
  • 설정을 운영 중에 변경할 수 있다

이 부분을 구축하면 AI를 실무에 상당히 쉽게 투입할 수 있습니다.

AI 업무 자동화에서 가장 중요한 것은 강력한 모델을 선택하는 것만이 아니었습니다.

오히려 미경험자에 가까운 제가 만들면서 효과를 본 것은 다음과 같습니다.

  • AI에게 전달하기 전에 입력을 정규화한다
  • 전체 알림이 아니라 사람이 봐야 할 것만 알림을 보낸다
  • AI에게 전달하기 전에 중복을 제거한다
  • 외부 API는 실패, 중복, 재처리를 전제로 한다
  • 프롬프트(Prompt)나 AI 설정은 코드와 분리한다
  • 정기 실행은 Cloudflare Workers 등 운영이 가벼운 곳으로 모은다
  • AI에게 맡길 범위와 맡기지 않을 범위를 결정한다

AI를 업무에 넣는다기보다, AI가 망설임 없이 일할 수 있는 업무 레인(Lane)을 만든다.

아직 깔끔하게 만들고 있다고는 할 수 없지만, 제 안에서는 이것이 가장 정답에 가깝게 느껴집니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0