📅 Sense Stock 개발, 세 번째 회고록 (2025-08-12)
두번째회고 때보다 시간이 꽤 많이 흘렀는데... 한달이 넘었네 ㅋㅋㅋ, 그만큼 변화된게 엄청 많다.
https://cord-ai.tistory.com/237
Sense Stock 개발 회고, 두 번째
📅 Sense Stock 개발, 두 번째 회고록 (2025-07-04)https://notebooklm.google.com/notebook/cf4e6f87-9bfb-4284-937e-0b0175090d1c/audio 로그인 - Google 계정이메일 또는 휴대전화accounts.google.com 이번에도 돌아왔다. 나의 회고
cord-ai.tistory.com
<NotebookLM Audio Overview>
지루한 글 읽어볼 필요없이 Audio에 모든게 담겨 있습니다 ㅋㅋㅋ 정말 좋은 기술... 대단
스크립트도 따로 받아볼 수 있으면 좋겠는데...아쉽
LLM의 Token Limit 문제를 해결하기 위해 데이터 처리 방식을 갈아엎었다.
지난번에는 S&P500 히트맵 이미지를 텍스트로 변환하는 작업을 진행했었다. 하지만 티커와 변동률이 제대로 매칭되지 않아 LLM에 참조시킬 수 없다는 결론을 내렸었다. 이번에는 LLM이 실제로 참조할 수 있는 정형 데이터(Text)를 수집하고, 이 과정에서 발생한 Token Limit 문제를 해결하는 데 집중했다.
초기 목표는 간단했다. 시장 분석에 필요한 모든 데이터(섹터, 티커, 경제 발표, 기업 실적, 변동률 등)를 최대한 많이 긁어모아 LLM에 한 번에 넘겨주는 것이었다. 데이터가 많을수록 더 똑똑한 답변을 내놓을 것이라고 순진하게 믿었다. 하지만 이 방식은 곧바로 거대한 장벽에 부딪혔다. 바로 LLM의 Token Limit과 그에 따른 어마어마한 비용($0.68/1회) 문제였다. 데이터를 모두 참조시키자니 토큰 초과로 실행이 불가능했고, 어찌어찌 실행한다 해도 비용이 감당이 안 됐다.
그래서 모든 데이터를 한 번에 넘기는 무식한 방법 대신, 사용자의 질문에서 핵심 키워드를 뽑아내고, 그와 관련된 최소한의 데이터만 필터링해서 LLM에 넘겨주는 구조를 적용해보기로 했다.
두 번째 회고 직후
이전 작업에서 S&P500 히트맵을 이미지에서 텍스트로 추출하는 시도는 실패로 돌아갔습니다. 티커와 변동률이 정확히 연결되지 않아 LLM이 분석할 수 있는 데이터로 활용하기엔 부적합했죠. 그래서 이 이미지는 나중에 시각 자료로만 활용하기로 하고, LLM을 위한 데이터 수집은 텍스트 기반의 정형 데이터로 방향을 완전히 전환했습니다.
본격적인 금융 데이터 수집 착수
분석에 핵심적인 아래와 같은 데이터를 수집하는 것을 목표로 삼았습니다.
- 기업 정보: 섹터, 티커 등
- 시장 데이터: 변동률
- 이벤트 데이터: 경제 발표, 기업 실적
초기 계획은 이 모든 데이터를 일단 모아서 LLM에 전부 참조시키는 것이었습니다.
데이터 수집 도구 변경: Selenium → Playwright
데이터 추출(크롤링) 도구로 기존에 사용하던 Selenium 대신 Playwright를 도입했습니다. Playwright는 다음과 같은 장점이 있어 선택했습니다.
- 속도와 성능: Playwright는 최신 아키텍처(WebSocket)를 사용하여 Selenium보다 일반적으로 더 빠른 속도를 보입니다.
- 편의성: 자동 대기(auto-wait) 기능이 내장되어 있어 동적 콘텐츠가 많은 최신 웹사이트를 다루기 더 수월합니다.
- 간편한 설정: 브라우저 드라이버를 별도로 관리할 필요 없이 내장된 브라우저를 사용하여 설정이 더 간단합니다.
새로운 발견
S&P500 지수가 반드시 500개 기업으로만 구성되는 것은 아니라는 점입니다. 일부 기업이 여러 종류의 주식(예: Class A, Class C)을 상장하는 경우, 지수에는 500개가 넘는 항목이 포함될 수 있습니다. 현재 502개
Next Step
데이터 수집 자동화 워크플로우 구축
수집할 데이터를 정하고, n8n을 이용해 수집 주기에 따라 워크플로우를 구성했습니다.
- 매일 수집: 시장의 단기적인 흐름을 파악하기 위한 데이터
- Sector 동향, S&P500 기업 리스트, S&P500 Heatmap 이미지
- 매주 수집: 주간 단위의 주요 이벤트를 추적하기 위한 데이터
- Economic (경제 지표 발표), Earning (기업 실적 발표)
- 스케줄: 매주 월요일 오전 9시 자동으로 실행되도록 설정
특히 주간 데이터는 수집 및 관리 방식을 효율화했습니다.
- 가독성 개선: 중복을 피하기 위해 각 이벤트(Row)마다 날짜를 표시하는 대신, 같은 날짜의 첫 번째 이벤트에만 날짜를 기입하도록 변경했습니다.
- 데이터 업데이트 자동화: 수집한 데이터를 '이번 주'와 '다음 주' 데이터로 나누어 저장하고, 매주 스케줄이 실행될 때마다 시트의 기존 내용을 전부 지우고 새로운 데이터로 덮어쓰는 방식으로 최신성을 유지했습니다.
API 호출 제한과 캐싱의 발견 ⚠️
데이터를 Google Sheets에 저장하고 필요할 때마다 API로 불러오는 방식을 사용하다가 API 호출 횟수 제한(Rate Limit) 에 부딪혔습니다. 계속해서 API를 호출하는 방식은 확장성에 문제가 있다는 것을 깨닫게 된 계기였죠.
이때 캐싱(Caching) 이라는 개념을 처음 접했습니다.
- 캐싱이란? 자주 요청되는 데이터나 결과를 미리 복사해두고, 요청이 오면 빠르게 제공하는 기술입니다. 매번 원본 데이터 소스(API, DB 등)에 접근할 필요가 없어 속도가 빠르고 부하를 줄일 수 있습니다.
사용자 수가 늘어날 것을 대비해 Redis 같은 인메모리 데이터 스토어를 사용하는 것이 가장 이상적인 구조라고 판단했지만, 당장은 구현의 어려움으로 인해 차선책을 선택했습니다.
- 임시 해결책: 수집한 데이터를 API로 호출하는 대신, 로컬 서버의 파일(.json 등)로 직접 저장하고 필요할 때마다 이 파일을 읽어오는 방식으로 우선 문제를 해결했습니다.
이 시점부터 단순히 데이터를 모으는 것을 넘어, '어떻게 효율적으로 저장하고 관리할 것인가'라는 데이터 아키텍처 설계에 대한 깊은 고민이 시작되었습니다.
Docker 환경에서의 파일 접근 🐳
로컬 파일에 데이터를 저장하고 읽어오는 방식 역시 순탄치만은 않았습니다. Docker 환경에서 Self-hosting으로 n8n을 운영하다 보니, 보안상의 이유로 워크플로우 노드가 서버의 파일 시스템에 자유롭게 접근할 수 없었습니다.
이 문제는 n8n의 환경 변수(Environment Variables) 설정을 통해 해결했습니다.
- N8N_RESTRICT_FILE_ACCESS_TO 변수를 사용해 데이터를 저장하고 읽어올 특정 폴더의 경로를 지정해주었습니다. 이렇게 함으로써 n8n의 Read/Write Disk 노드가 해당 폴더에만 안전하게 접근할 수 있도록 허용했습니다.
Last Step
LLM의 토큰 제한(Token Limit)이라는 거대한 벽
데이터 파이프라인을 완성하고 수집한 모든 데이터를 LLM에 참조시키자, 예상했던 문제가 터졌습니다. 바로 토큰 제한입니다.
- 토큰(Token)이란? LLM이 텍스트를 처리하는 기본 단위입니다. 모델마다 한 번에 처리할 수 있는 토큰의 양(Context Window)이 정해져 있으며, 이를 초과하면 오류가 발생합니다.
- 비용 문제: 토큰 사용량은 곧 비용으로 직결됩니다. 더 많은 데이터를 참조시킬수록, 더 좋은 모델을 사용할수록 비용은 기하급수적으로 늘어납니다. (회당 $0.68)
단순히 데이터를 쏟아붓는 방식은 기술적으로도, 비용적으로도 불가능하다는 결론에 도달했습니다. 이때부터 프로젝트의 핵심 과제는 '어떻게 하면 토큰을 줄일 수 있을까?', 즉 '어떻게 하면 LLM에게 전달할 데이터를 최소한으로, 하지만 효과적으로 정제할 수 있을까?' 가 되었습니다.
해결을 위한 시도와 좌절
토큰을 줄이기 위해 여러 가지 방법을 시도했습니다.
- 1차 시도 (데이터 범위 축소): 분석 대상을 S&P500 기업으로 한정하고, 기업 실적 데이터 역시 S&P500에 해당하는 것만 필터링해서 저장했습니다. 동시에 시가총액, 매출 등의 정보를 추가하여 데이터의 밀도를 높이는 시도도 병행했습니다.
- 2차 시도 (Call Workflow 도입): Economic 데이터처럼 정형화된 정보는 LLM이 직접 워크플로우(Tool)를 호출하여 스스로 데이터를 참조하도록 변경했습니다. 하지만 이 방법만으로는 여전히 참조할 데이터의 총량이 너무 많았습니다.
이때 사실.. 이 방식으로는 안되나? 싶었다...😕, 그래서 또 갈아 엎을 뻔했지
그렇지만 또 다른 길이 있다는 걸 이때 알게 되었다... 더 흥미로운 주제로 접근 해볼 수 있겠다.
=> '모든 정보'가 아닌 '필요한 정보'만 제공하기 💡
과거에 만들었던 사용자 질문 분석 워크플로우에서 해답을 찾았습니다. LLM에게 모든 재료를 주고 요리하라고 하는 대신, 사용자가 원하는 요리에 딱 맞는 재료만 골라서 주는 방식으로 바꾼 것입니다.
이 새로운 워크플로우의 흐름은 다음과 같습니다.
- 키워드 추출: 사용자가 "테슬라 어때?"라고 질문하면, Tesla 라는 핵심 키워드를 추출합니다.
- 관련 기업 식별: S&P500 리스트에서 Tesla와 가장 관련 있는 기업들을 최대 5개까지 찾아냅니다.
- 데이터 선별 로딩: 로컬에 저장된 데이터 중, 오직 이 5개 기업에 대한 정보만 불러옵니다.
- 최소한의 데이터로 LLM 호출: 선별된 최소한의 데이터를 컨텍스트로 LLM에 넘겨 분석을 요청합니다.
이 간단한 아이디어를 통해 토큰 문제를 극적으로 해결할 수 있었습니다. 수많은 길을 돌아왔지만, 결국 가장 단순하고 효과적인 해법을 찾아낸 것입니다.
현재의 고민과 새로운 방향 모색 🤔
기술적인 큰 산을 하나 넘고 나니, 이제 진짜 본질적인 고민들이 시작됐다.
우선 당면한 과제는 프롬프트 엔지니어링. LLM의 답변 퀄리티가 너무 들쑥날쑥해서 이대로는 못 쓰겠다. 답변 포맷을 좀 정형화하고 싶은데, 지시사항이 조금만 길어져도 토큰 비용이 바로 뛰어버리니 이것도 부담이다. 일단은 단순 요약(Lv1/2) / 디테일 분석(Lv3)으로 응답 레벨을 나눠서 비용과 퀄리티 사이에서 줄타기를 해볼 생각이다.
하지만 더 근본적인 고민이 머리를 떠나지 않는다. '내가 만들고 있는 이게 과연 특별한가?'
솔직히 말해, 최신 뉴스 요약이나 기업 분석 같은 기능은 이미 시장에 널리고 널렸다. 더 큰 문제는 비용이다. 이 비싼 운영비를 감당하면서 이미 흔한 기능을 제공하는 게 무슨 의미가 있나 싶다. 이대로 가다가는 밑 빠진 독에 물 붓기다.
그래서 방향을 완전히 틀어볼까 한다. '분석 툴'이 아니라 '콘텐츠 채널' 로의 전환이다.
전략의 핵심은 숏폼(피드). 남들이 다 하는 딱딱한 분석 정보 대신, 데이터를 '시각적으로 매력적인 콘텐츠' 로 재가공해서 '부담 없이 소비할 수 있는 채널' 을 만들고 싶다. 목표는 더 이상 '정확한 분석'이 아니다.
'흥미를 유발하는 데이터 큐레이션' 이다. 사람들이 "오, 이건 재밌는데?" 하고 가볍게 넘겨볼 수 있는 그런 콘텐츠 말이다. 이게 이 비싼 기술을 가지고 살아남을 수 있는 유일한 길이 아닐까 싶다.
https://cord-ai.tistory.com/253
💣 프로젝트 트러블슈팅 및 삽질 기록
프로젝트를 진행하며 마주쳤던 주요 이슈들과 해결 과정을 공유한다.세번째 회고록에 다 작성하기엔 내용이 너무 많아 따로 정리한다.https://cord-ai.tistory.com/252 Sense Stock 개발 회고, 세 번째📅 Sen
cord-ai.tistory.com
'Automation Tool > n8n Project' 카테고리의 다른 글
Sense Stock, D+24 (4) | 2025.08.14 |
---|---|
💣 프로젝트 트러블슈팅 및 삽질 기록 (4) | 2025.08.12 |
Sense Stock, D+23 (2) | 2025.08.11 |
Sense Stock, D+22 (4) | 2025.08.06 |
Sense Stock, D+21 (4) | 2025.08.04 |
댓글