작은 에이전틱 트레이딩 앱을 만들었습니다. 몇 시간과 실행당 약 $0.20 정도 들었습니다.
Source: Dev.to
왜 이 프로젝트를 시작했는가
제가 기사들을 보고 사람들 얘기를 들을 때 AI 에이전트, 오케스트레이션 프레임워크, 그리고 멀티‑에이전트 아키텍처에 대해, 제 첫 번째 직감은: 코드를 안다면 몇 줄, 몇 번의 API 호출, 그리고 LLM만 있으면 된다. 그게 전부다. 그게 당신의 에이전트다.
그 직감을 시험해 보고 싶어서, 제가 실제로 관심 있는 것과 섞어 보았다: 트레이딩.
원하는 워크플로
아이디어는 간단했습니다: 다음을 수행하는 앱
- 내로부터 입력을 받음 (선택 사항).
- 몇 개의 API를 호출하여 시장 데이터와 뉴스를 수집합니다.
- 적절한 컨텍스트와 함께 모든 것을 LLM에 전송합니다.
- 출력을 향후 실행을 위해 저장 (기본적인 메모리 형태).
- 이메일 및 푸시 알림을 통해 결과를 전송합니다.
자동으로 주문을 체결하거나 취소하도록 하는 것이 불편합니다—아마 나중에 고려할 수 있겠지만. 현재는 단지 생각하게 하고 그 생각을 알려주길 원합니다.
앱이 실제로 하는 일
각 실행은 다음과 같은 구체적인 권고를 생성합니다:
WAIT- 특정 가격에
BUY(또는NOW) - 특정 가격에
SELL(또는NOW) - 기존 주문 수정 등.
‘시장이 상승세다’와 같은 막연한 말이 아니라, 이유가 첨부된 실행 가능한 다음 단계입니다. 최종 결정은 제가 내리지만, 모델이 모든 정보를 종합해 결정을 내리는 작업을 수행합니다.
구현 세부 사항
스택
| 구성 요소 | 이유 |
|---|---|
| Claude models (Opus) | 이미 Pro 계정이 있어 API 활성화가 쉽습니다. |
| LangChain | 라우팅을 위한 추상화 레이어를 제공합니다 (예: 빠른 정상 확인을 위한 Sonnet, 검증을 위한 Opus). |
| Tavily | 뉴스 데이터 소스이며, LangChain 도구로 구성됩니다. |
| Docker | 애플리케이션을 컨테이너화합니다. |
| K3s on Raspberry Pi 5 | 시장 개장 전 한 번, 시장 시간 중 여러 번 실행되는 cronjob 집합으로 동작합니다. |
| Gmail | 이메일 알림을 보냅니다. |
| Home Assistant | API를 통해 내 휴대폰으로 푸시 알림을 전송합니다. |
핵심 흐름
flowchart TD
A[Start (cronjob)] --> B[Gather user input / manual overrides]
B --> C[Fetch broker data (positions, pending orders)]
C --> D[Pull news via Tavily]
D --> E[Build prompt (dynamic variables inserted)]
E --> F[Call Claude (Opus) via LangChain]
F --> G[Generate run summary + recommendation]
G --> H[Save summary to file (memory)]
G --> I[Send email (Gmail) & push (Home Assistant)]
I --> J[End]Why LangChain?
- Partly to learn it.
- Partly because I want to extend the solution later (e.g., route first‑pass queries to Sonnet, then upscale to Opus).
- It’s a convenient abstraction, not a strict requirement—everything could be done without it.
Dynamic User Prompt
The prompt contains several runtime‑filled variables:
- Current position
- Pending orders
- Historical orders
These are populated via plain REST calls to my broker—no fancy orchestration needed.
누락된 과거 가격 데이터
내 브로커는 API를 통해 과거 가격 데이터를 제공하지 않으며, 별도의 데이터 제공업체에 비용을 지불하고 싶지 않다.
현재 프롬프트는 가격 차트나 기술 지표에 크게 의존하지 않는다. 대신 다음에 의존한다:
- 뉴스
- 시장 논평
- 애널리스트 의견 (모두 Tavily를 통해 가져옴)
이렇게 하면 시스템이 단순하고 저렴해진다. 나중에 과거 데이터 소스를 추가할 예정이다.
로컬 오버라이드 모드
앱을 로컬에서 실행할 때(크론 작업이 아닐 때) 다음을 할 수 있습니다:
- 수동 뉴스 항목을 붙여넣기.
- 특정 악기 가격을 강제 지정하기(예: “가격을 X로 가정”).
이는 테스트와 “가정” 시나리오에 매우 유용합니다.
메모리 (런‑투‑런 컨텍스트)
- 전체 LLM 출력을 저장하지 않습니다.
- 시스템 프롬프트는 모델에게 **“런 요약”**을 생성하도록 요청합니다—이는 모델의 추론 및 권고를 압축한 버전입니다.
- 이 요약은 파일에 저장되고 다음 프롬프트에 삽입됩니다.
Result: 모델은 이전에 어떤 결론을 내렸는지, 어떤 권고를 했는지, 그리고 조건이 변했는지를 확인할 수 있습니다. 벡터 DB, 임베딩, 검색 파이프라인이 필요 없으며, 단순 텍스트 파일만 사용합니다.
알림
- 이메일: 내 개인 Gmail 계정으로 나에게 메시지를 보냅니다.
- 푸시: Home Assistant가 이미 내 전화로 푸시하는 방법을 알고 있으므로 API를 호출하기만 하면 됩니다.
두 경우 모두 내 환경에서 간단하고, 신뢰할 수 있으며, 이미 실행 중입니다.
비용
- LLM 사용량: 실행당 약 $0.20 (컨텍스트 수집, 뉴스 읽기, 추론 및 권고안 생성에 사용하는 Claude API).
- 뉴스 데이터: Tavily의 무료 Researcher 티어 (현재 월간 실행 횟수에 충분히 충분함).
실제 비용은 LLM뿐입니다. 전문 트레이더라면 (로컬 모델, 파인‑튜닝된 금융 모델, 지연 시간 문제 등) 더 최적화할 수 있겠지만, 저에게는 이것으로 충분합니다.
마무리 생각
- 일부 단계에 local model 사용.
- financial reasoning에 맞게 fine‑tuned된 모델 찾기.
- latency와 cost 최적화.
하지만 나에게 현재 설정은 repeatable, auditable, and inexpensive한 의사결정 지원 도구를 제공한다. 이 도구는 내가 정확히 필요로 하는 것을 수행한다: think, reason, and tell me what to do—내가 최종 권한을 유지하면서.
Fun and Learn
Disclaimer: This is a personal learning project. Nothing here should be taken as financial advice. As a non‑native English speaker, I used an LLM to review and refine the language while keeping my original tone and ideas.
End‑to‑End Sketch
- Cronjob triggers the Docker container on K3s (Raspberry Pi 5).
- Broker API calls fetch current positions, pending orders, and order history.
- Tavily tool (via LangChain) fetches relevant market news.
- Prompt assembly: all dynamic data (including the previous run’s output as memory) is injected into the user prompt.
- Claude Sonnet processes the full context and produces a recommendation.
- Output is saved to a file (used as memory for the next run).
- Email + push notification sent to me with the recommendation.
- Human‑in‑the‑loop: I decide whether to act on the model’s recommendation.
That’s eight steps. Most of them are just API calls and string concatenation. The “agentic” part is really step 5 – the LLM reasoning over structured context with tool access. Step 8 is simply a person looking at his phone over coffee.
Why (or why not) a Fancy Orchestration Framework?
The obvious question: For a developer who can write code, why exactly do you need a fancy orchestration framework to build something like this?
There’s a market for “no‑code” AI agents and visual pipelines, but if you do write code, the essential pieces are:
- An LLM API
- A few REST calls (broker, news, notifications, etc.)
- String templating for prompts
- A file system (for memory)
- A way to send notifications (email, push, etc.)
- A container runtime (optional, but convenient)
- Logging (if you need audit or debug data)
That’s it. That’s the agent.
I’m not saying LangChain is strictly necessary either. I used it because I wanted to learn it and because the tool abstraction is convenient for the Tavily integration. I could have done the same thing with raw API calls and a hundred lines of Python.
The orchestration is just code. It always was.
The value of an LLM agent lies in:
- Prompt design
- Context assembly
- Quality of the model’s reasoning
Everything else is plumbing, and developers have been building plumbing for decades.