Ollama + CrewAI 기반 로컬 블로그 포스팅 AI 시스템 (Mac 환경)
로컬 LLM(Ollama)과 멀티 에이전트 프레임워크(CrewAI)를 활용하여 블로그 글을 자동으로 리서치, 작성, 교정하는 시스템입니다.
[Researcher Agent] → 최신 DevOps 토픽 리서치 (Serper 웹 검색)
↓
[Writer Agent] → 블로그 글 작성 (마크다운)
↓
[Proofreader Agent] → 글 교정 및 다듬기
3개의 AI 에이전트가 순차적으로 협업하여 블로그 포스트를 완성합니다.
| 항목 | 설명 |
|---|---|
| macOS | Apple Silicon (M1/M2/M3/M4) 또는 Intel Mac |
| Docker Desktop | 다운로드 |
| Serper API Key | 무료 가입 (2,500회 무료 쿼리) |
# Docker 볼륨 생성 (모델 데이터 영속화)
docker volume create ollama-local
# Ollama 컨테이너 실행
docker run -d \
--name ollama \
-p 11434:11434 \
-v ollama-local:/root/.ollama \
ollama/ollama:0.1.34
# llama3 모델 다운로드 (약 4.7GB)
docker exec ollama ollama pull llama3:8b
# 모델 다운로드 확인
docker exec ollama ollama list
# 테스트 완료 후 컨테이너 정지
docker stop ollama && docker rm ollama# Homebrew로 설치
brew install ollama
# Ollama 서비스 시작
ollama serve &
# llama3 모델 다운로드
ollama pull llama3:8b
# 모델 확인
ollama list참고: 네이티브 설치 시
main-crewai.py에서base_url을http://host.docker.internal:11434또는http://localhost:11434로 변경해야 합니다.
Ollama는 로컬에서 실행되므로 웹 검색 기능이 없습니다. Researcher 에이전트가 웹 검색을 수행하려면 Serper API가 필요합니다.
- https://serper.dev/ 접속
- 무료 회원가입 (Google 계정 가능)
- Dashboard에서 API Key 복사
- 무료 플랜: 2,500회 쿼리 제공
BlogPostingAI/
├── compose.yaml # Docker Compose 설정
├── crewai.Dockerfile # CrewAI 컨테이너 빌드
├── main-crewai.py # 메인 스크립트 (에이전트/태스크 정의)
├── requirements.txt # Python 의존성
└── README.md
services:
ollama:
image: ollama/ollama:0.1.34
container_name: ollama
ports:
- "11434:11434"
volumes:
- ollama-local:/root/.ollama
crewai:
image: my-crewai
container_name: crewai
depends_on:
- ollama
extra_hosts:
- "telemetry.crewai.com:127.0.0.1"
volumes:
ollama-local:
external: true
extra_hosts로 CrewAI 텔레메트리를 차단하여 불필요한 외부 통신을 방지합니다.
FROM python:3.12.4
WORKDIR /app
COPY requirements.txt ./requirements.txt
RUN pip install -r requirements.txt
COPY main-crewai.py ./
CMD [ "python3", "-u", "main-crewai.py" ]crewai==0.32.0
crewai-tools==0.2.6
langchain==0.1.20
import os
from crewai import Agent, Task, Crew, Process
from crewai_tools import SerperDevTool
from langchain.llms import Ollama
ollama_model = Ollama(
base_url='http://ollama:11434',
model="llama3:8b")
# CrewAI 텔레메트리 비활성화
os.environ["OTEL_SDK_DISABLED"] = "true"
# Serper API Key 설정 (자신의 키로 교체)
os.environ["SERPER_API_KEY"] = "여기에_본인의_SERPER_API_KEY를_입력하세요"
search_tool = SerperDevTool()
# === 에이전트 정의 ===
researcher = Agent(
role='Researcher',
goal='Discover a newest and attracting topic about DevOps',
backstory="You're world class researcher working on a big IT company",
verbose=True,
allow_delegation=False,
llm=ollama_model,
tools=[search_tool]
)
writer = Agent(
role='Writer',
goal='Create DevOps blog post',
backstory="You're a best technical writer who is specialized on writing IT content",
verbose=True,
allow_delegation=False,
llm=ollama_model
)
proofreader = Agent(
role='Proofreader',
goal='Edit and proofread technical article',
backstory="You're a famous proofreader who is specialized on IT domain",
verbose=True,
allow_delegation=False,
llm=ollama_model
)
# === 태스크 정의 ===
research_task = Task(
description='Investigate the latest DevOps news',
agent=researcher,
expected_output='A comprehensive 3 paragraphs long report on the latest and famous DevOps.'
)
writing_task = Task(
description='Write a blog post about DevOps with one topic provided from the researcher',
agent=writer,
expected_output='A 4 paragraph article about DevOps formatted as markdown.',
)
proofreading_task = Task(
description='Proofread the provided blog post to make more natural article',
agent=proofreader,
expected_output='A 4 paragraph article about DevOps formatted as markdown.',
)
# === Crew 실행 ===
crew = Crew(
agents=[researcher, writer, proofreader],
tasks=[research_task, writing_task, proofreading_task],
llm=ollama_model,
verbose=2,
process=Process.sequential
)
result = crew.kickoff()
print(result)cd BlogPostingAI
# CrewAI 이미지 빌드
docker build -f crewai.Dockerfile -t my-crewai .main-crewai.py 파일에서 아래 부분을 본인의 API Key로 교체합니다:
os.environ["SERPER_API_KEY"] = "여기에_본인의_SERPER_API_KEY를_입력하세요"# 전체 시스템 실행 (Ollama + CrewAI)
docker compose up -d
# CrewAI 로그 실시간 확인
docker compose logs crewai -f
# 작업 완료 후 종료
docker compose downdocker compose up -d && docker compose logs crewai -f && docker compose down1. docker compose up
├── Ollama 컨테이너 시작 (LLM 서빙)
└── CrewAI 컨테이너 시작 (main-crewai.py 실행)
2. CrewAI 순차 실행 (Process.sequential)
├── [Researcher] Serper API로 최신 DevOps 뉴스 검색
├── [Writer] 리서치 결과 기반 블로그 글 작성
└── [Proofreader] 글 교정 및 최종 완성
3. 결과 출력 → 터미널에 마크다운 형식 블로그 글 출력
# 볼륨이 생성되었는지 확인
docker volume ls | grep ollama
# 없으면 생성
docker volume create ollama-local
# Ollama 컨테이너에서 직접 pull
docker compose exec ollama ollama pull llama3:8b# 로그 확인
docker compose logs crewai
# Ollama 연결 확인
docker compose exec crewai curl http://ollama:11434/api/tags- API Key가 올바른지 확인
- 무료 쿼리 횟수(2,500회)를 초과하지 않았는지 확인
- Serper Dashboard에서 사용량 확인
Docker Desktop > Settings > Resources에서 메모리를 8GB 이상으로 설정하세요. llama3:8b 모델은 약 5GB RAM을 사용합니다.
Ollama Docker 이미지는 ARM64를 네이티브 지원하므로 별도 설정 없이 동작합니다.
main-crewai.py에서 에이전트의 goal과 태스크의 description을 수정하세요:
# 예: AI/ML 주제로 변경
researcher = Agent(
role='Researcher',
goal='Discover the latest trends in AI and Machine Learning',
...
)
research_task = Task(
description='Investigate the latest AI/ML news and breakthroughs',
...
)# 더 가벼운 모델
docker exec ollama ollama pull gemma:2b
# 더 강력한 모델 (16GB+ RAM 필요)
docker exec ollama ollama pull llama3:70b# main-crewai.py에서 모델 변경
ollama_model = Ollama(
base_url='http://ollama:11434',
model="gemma:2b" # 원하는 모델명으로 변경
)태스크 설명과 기대 출력을 한국어로 변경하세요:
writing_task = Task(
description='리서처가 제공한 주제로 DevOps 블로그 글을 한국어로 작성하세요',
agent=writer,
expected_output='마크다운 형식의 4개 단락으로 구성된 한국어 DevOps 블로그 글.',
)