본 글은 에이전틱 프로그래밍을 체험하기 위해서 로컬 LLM을 세팅하고 데모를 해보는 글입니다.
이 글을 작성하기 위해서 Gemini 의 도움을 받았음을 알립니다.
에이전트 프레임워크, crewai 설치하기
1. 가상환경 설치하기 (Anacodna 설치)
Anaconda 웹 사이트에 가서 설치하자. (링크)
리눅스에서 Anaconda를 설치하는 방법은 본 링크를 참고한다.
아래의 명령어를 입력하여 Anaconda 최신 배포버전을 설치한다 (글 작성 시기의 최신은 `25.12.02 배포이다.)
wget https://repo.anaconda.com/archive/Anaconda3-2025.12-2-Linux-x86_64.sh
터미널에서 위 파일을 다운로드 받은 곳으로 가서 아래의 명령어를 입력하여 설치한다.
bash ~/Anaconda3-2025.12-2-Linux-x86_64.sh
yes를 입력하여 사용 약관에 동의한다.
다음으로, 기본 설치 위치에 대해 동의한다면 Enter 를 입력한다. 별도 원하는 위치가 있다면 절대 경로를 입력한다.
conda 를 초기화한다면 이번에도 yes를 입력한다.
설치가 완료되었다면 아래의 명령어를 입력하여 설치가 효력이 발생하도록 하자.
source ~/.bashrc
2. 필요한 라이브러리 설치하기
생성한 가상환경에서 아래의 명령어를 통해서 필수 라이브러리를 설치하자.
pip install crewai langchain-openai
로컬 LLM 세팅하기
1. Docker 설치하기
잘 해본다..
2. Ollama 설치하기
도커를 통해서 Ollama 컨테이너를 생성/실행한다.
이미지가 없다면 알아서 다운로드 받아서 컨테이너를 실행한다.
# Terminal.1
docker run -d --gpus=all -p 11434:11434 --name ollama ollama/ollama
입력한 명령어를 설명하면 다음과 같다.
-d : 백그라운드로 실행한다.
--gpus=all : 해당 컨테이너가 사용할 GPU 를 할당한다. (모두 할당함)
-p [HostPort:ContainerPort] : 호스트-컨테이너의 포트를 포워딩한다.
--name [ContainerName] : 컨테이너의 이름을 별도로 할당한다.
ollama/ollama : 로컬에 설치되어있는 이미지의 이름으로, 이 이미지를 컨테이너로 생성/실행한다.
llama3.1:8b 모델을 다운받고 컨테이너에 접속한다. (전체 용량은 4.9GB 정도이다.)
# Teminal.1
docker exec -it ollama ollama run llama3.1:8b
다른 새 터미널을 생성한 후, 아래의 코드를 실행해보자.
python main_llama.py
main.py 코드는 아래와 같다. 접은 글을 펼치면 코드가 나온다.
# main_llama.py
import os
from crewai import Agent, Task, Crew, LLM
# 1. 로컬 Ollama 환경 설정
# Ollama는 기본적으로 11434 포트에서 OpenAI와 호환되는 로컬 API 서버를 제공합니다.
os.environ["OPENAI_API_KEY"] = "ollama" # 로컬 환경이므로 임의의 문자열을 넣으면 됩니다.
# 가지고 계신 8B 모델의 정확한 이름으로 변경하세요 (예: 'llama3', 'gemma:7b', 'phi3' 등)
target_model = "llama3.1:8b"
llm = LLM(
model=target_model,
base_url="http://localhost:11434/v1", # Ollama의 로컬 엔드포인트 주소
temperature=0.2
)
# --------------------------------------------------
# 2. 에이전트 정의 (The Agent)
# 에이전트에게 페르소나와 목표를 부여합니다.
# --------------------------------------------------
code_reviewer = Agent(
role='시니어 소프트웨어 아키텍트',
goal='주어진 코드의 구조적 결함을 찾고, 엄격한 코딩 스타일 가이드를 강제(Enforce)합니다.',
backstory='당신은 20년 경력의 깐깐한 개발자입니다. 가독성이 떨어지거나 비효율적인 로직, 스타일 가이드를 어긴 코드를 보면 반드시 짚고 넘어갑니다. 항상 구체적인 개선 코드를 함께 제시합니다.',
verbose=True, # 에이전트가 생각하는 과정을 콘솔에 출력
allow_delegation=False, # 다른 에이전트에게 업무 위임 금지
llm=llm
)
# --------------------------------------------------
# 3. 작업 정의 (The Task)
# 에이전트가 달성해야 할 구체적인 임무를 설명합니다.
# --------------------------------------------------
# 리뷰할 샘플 코드 (일부러 비효율적이고 스타일이 엉망인 코드)
sample_code = """
def calc( a,b ):
res=0
for i in range(b): res+=a
return res
print(calc( 5, 3 ))
"""
review_task = Task(
description=f'다음 파이썬 코드를 분석하고 개선점을 제안하세요:\n\n{sample_code}\n\n결과물에는 발견된 문제점, 코딩 스타일 위반 사항, 그리고 리팩토링된 최종 코드가 포함되어야 합니다.',
expected_output='문제점 분석 및 PEP8 스타일 가이드가 적용된 리팩토링 코드 보고서',
agent=code_reviewer
)
# --------------------------------------------------
# 4. 크루 구성 및 실행 (The Crew)
# 에이전트와 작업을 묶어서 실행을 지시합니다.
# --------------------------------------------------
crew = Crew(
agents=[code_reviewer],
tasks=[review_task],
verbose=True
)
print("🚀 에이전트가 코드 리뷰를 시작합니다...\n")
result = crew.kickoff()
print("\n==============================================")
print("🎯 최종 결과물:")
print("==============================================")
print(result)
이를 통해서 터미널에 아래의 결과물을 획득 할 수 있다.
🚀 에이전트가 코드 리뷰를 시작합니다...
╭──────────────────────── 🚀 Crew Execution Started ────────────────────────╮
│ │
│ Crew Execution Started │
│ Name: crew │
│ ID:
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────╯
╭───────────────────────────── 📋 Task Started ─────────────────────────────╮
│ │
│ Task Started │
│ Name: 다음 파이썬 코드를 분석하고 개선점을 제안하세요: │
│ │
│ │
│ def calc( a,b ): │
│ res=0 │
│ for i in range(b): res+=a │
│ return res │
│ print(calc( 5, 3 )) │
│ │
│ │
│ 결과물에는 발견된 문제점, 코딩 스타일 위반 사항, 그리고 리팩토링된 최종 │
│ 코드가 포함되어야 합니다. │
│ ID: │
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────── 🤖 Agent Started ─────────────────────────────╮
│ │
│ Agent: 시니어 소프트웨어 아키텍트 │
│ │
│ Task: 다음 파이썬 코드를 분석하고 개선점을 제안하세요: │
│ │
│ │
│ def calc( a,b ): │
│ res=0 │
│ for i in range(b): res+=a │
│ return res │
│ print(calc( 5, 3 )) │
│ │
│ │
│ 결과물에는 발견된 문제점, 코딩 스타일 위반 사항, 그리고 리팩토링된 최종 │
│ 코드가 포함되어야 합니다. │
│ │
╰───────────────────────────────────────────────────────────────────────────╯
╭────────────────────────── ✅ Agent Final Answer ──────────────────────────╮
│ │
│ Agent: 시니어 소프트웨어 아키텍트 │
│ │
│ Final Answer: │
│ **문제점 분석 및 리팩토링 코드 보고서** │
│ │
│ ### 문제점 분석 │
│ │
│ * 함수 이름 `calc`는 너무 짧고 의미가 모호합니다. 더 자세한 설명이 │
│ 필요합니다. │
│ * 변수 이름 `a`, `b`은 의미를 명확하게 나타내지 않습니다. 더 자세한 │
│ 설명이 필요합니다. │
│ * 로직은 간단하지만, `for` 루프를 사용하여 반복을 수행하는 것은 │
│ 비효율적입니다. 더 빠른 방법으로 계산할 수 있습니다. │
│ * 함수 내에서 변수 `res`는 초기화가 너무 늦습니다. 초기화 시점에 바로 │
│ 할당해도 됩니다. │
│ │
│ ### PEP8 스타일 가이드 위반 사항 │
│ │
│ * 함수 이름과 변수 이름이 영어로만 구성되어 있지 않습니다. PEP │
│ 8에서는 영어로만 사용하는 것을 권장합니다. │
│ * 함수 내에서 공백이 부족합니다. PEP 8에서는 공백을 적절히 사용하여 │
│ 코드의 가독성을 높이는 것이 중요합니다. │
│ │
│ ### 리팩토링된 최종 코드 │
│ │
│ ```python │
│ def calculate_sum(a: int, b: int) -> int: │
│ """ │
│ 두 수를 더한 합을 반환한다. │
│ │
│ Args: │
│ a (int): 첫 번째 숫자 │
│ b (int): 두 번째 숫자 │
│ │
│ Returns: │
│ int: 두 수의 합 │
│ """ │
│ return a * b │
│ │
│ print(calculate_sum(5, 3)) │
│ ``` │
│ │
│ ### 개선된 점 │
│ │
│ * 함수 이름 `calculate_sum`은 더 자세하고 의미가 명확합니다. │
│ * 변수 이름 `a`, `b`도 더 자세하게 설명되어 있습니다. │
│ * 로직이 더 빠르게 수행됩니다. `for` 루프 대신 곱셈을 사용하여 두 │
│ 수의 합을 계산합니다. │
│ * 변수 `res`는 초기화 시점에 바로 할당됩니다. │
│ │
│ ### 참고 │
│ │
│ * PEP 8은 파이썬 코딩 스타일 가이드입니다. 더 자세한 내용은 [PEP │
│ 8](https://www.python.org/dev/peps/pep-0008/)을 참조하세요. │
│ * 리팩토링된 코드는 더 가독성 있고 유지보수하기 쉬운 코드를 │
│ 제공합니다. │
│ │
╰───────────────────────────────────────────────────────────────────────────╯
╭─────────────────────────── 📋 Task Completion ────────────────────────────╮
│ │
│ Task Completed │
│ Name: 다음 파이썬 코드를 분석하고 개선점을 제안하세요: │
│ │
│ │
│ def calc( a,b ): │
│ res=0 │
│ for i in range(b): res+=a │
│ return res │
│ print(calc( 5, 3 )) │
│ │
│ │
│ 결과물에는 발견된 문제점, 코딩 스타일 위반 사항, 그리고 리팩토링된 최종 │
│ 코드가 포함되어야 합니다. │
│ Agent: 시니어 소프트웨어 아키텍트 │
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────╯
==============================================
🎯 최종 결과물:
==============================================
**문제점 분석 및 리팩토링 코드 보고서**
### 문제점 분석
* 함수 이름 `calc`는 너무 짧고 의미가 모호합니다. 더 자세한 설명이 필요합니다.
* 변수 이름 `a`, `b`은 의미를 명확하게 나타내지 않습니다. 더 자세한 설명이 필요합니다.
* 로직은 간단하지만, `for` 루프를 사용하여 반복을 수행하는 것은 비효율적입니다. 더 빠른 방법으로 계산할 수 있습니다.
* 함수 내에서 변수 `res`는 초기화가 너무 늦습니다. 초기화 시점에 바로 할당해도 됩니다.
### PEP8 스타일 가이드 위반 사항
* 함수 이름과 변수 이름이 영어로만 구성되어 있지 않습니다. PEP 8에서는 영어로만 사용하는 것을 권장합니다.
* 함수 내에서 공백이 부족합니다. PEP 8에서는 공백을 적절히 사용하여 코드의 가독성을 높이는 것이 중요합니다.
### 리팩토링된 최종 코드
```python
def calculate_sum(a: int, b: int) -> int:
"""
두 수를 더한 합을 반환한다.
Args:
a (int): 첫 번째 숫자
b (int): 두 번째 숫자
Returns:
int: 두 수의 합
"""
return a * b
print(calculate_sum(5, 3))
```
### 개선된 점
* 함수 이름 `calculate_sum`은 더 자세하고 의미가 명확합니다.
* 변수 이름 `a`, `b`도 더 자세하게 설명되어 있습니다.
* 로직이 더 빠르게 수행됩니다. `for` 루프 대신 곱셈을 사용하여 두 수의 합을 계산합니다.
* 변수 `res`는 초기화 시점에 바로 할당됩니다.
### 참고
* PEP 8은 파이썬 코딩 스타일 가이드입니다. 더 자세한 내용은 [PEP 8](https://www.python.org/dev/peps/pep-0008/)을 참조하세요.
* 리팩토링된 코드는 더 가독성 있고 유지보수하기 쉬운 코드를 제공합니다.
╭───────────────────────────── Crew Completion ─────────────────────────────╮
│ │
│ Crew Execution Completed │
│ Name: crew │
│ ID:
│ Final Output: **문제점 분석 및 리팩토링 코드 보고서** │
│ │
│ ### 문제점 분석 │
│ │
│ * 함수 이름 `calc`는 너무 짧고 의미가 모호합니다. 더 자세한 설명이 │
│ 필요합니다. │
│ * 변수 이름 `a`, `b`은 의미를 명확하게 나타내지 않습니다. 더 자세한 │
│ 설명이 필요합니다. │
│ * 로직은 간단하지만, `for` 루프를 사용하여 반복을 수행하는 것은 │
│ 비효율적입니다. 더 빠른 방법으로 계산할 수 있습니다. │
│ * 함수 내에서 변수 `res`는 초기화가 너무 늦습니다. 초기화 시점에 바로 │
│ 할당해도 됩니다. │
│ │
│ ### PEP8 스타일 가이드 위반 사항 │
│ │
│ * 함수 이름과 변수 이름이 영어로만 구성되어 있지 않습니다. PEP │
│ 8에서는 영어로만 사용하는 것을 권장합니다. │
│ * 함수 내에서 공백이 부족합니다. PEP 8에서는 공백을 적절히 사용하여 │
│ 코드의 가독성을 높이는 것이 중요합니다. │
│ │
│ ### 리팩토링된 최종 코드 │
│ │
│ ```python │
│ def calculate_sum(a: int, b: int) -> int: │
│ """ │
│ 두 수를 더한 합을 반환한다. │
│ │
│ Args: │
│ a (int): 첫 번째 숫자 │
│ b (int): 두 번째 숫자 │
│ │
│ Returns: │
│ int: 두 수의 합 │
│ """ │
│ return a * b │
│ │
│ print(calculate_sum(5, 3)) │
│ ``` │
│ │
│ ### 개선된 점 │
│ │
│ * 함수 이름 `calculate_sum`은 더 자세하고 의미가 명확합니다. │
│ * 변수 이름 `a`, `b`도 더 자세하게 설명되어 있습니다. │
│ * 로직이 더 빠르게 수행됩니다. `for` 루프 대신 곱셈을 사용하여 두 │
│ 수의 합을 계산합니다. │
│ * 변수 `res`는 초기화 시점에 바로 할당됩니다. │
│ │
│ ### 참고 │
│ │
│ * PEP 8은 파이썬 코딩 스타일 가이드입니다. 더 자세한 내용은 [PEP │
│ 8](https://www.python.org/dev/peps/pep-0008/)을 참조하세요. │
│ * 리팩토링된 코드는 더 가독성 있고 유지보수하기 쉬운 코드를 │
│ 제공합니다. │
│ │
│ │
╰───────────────────────────────────────────────────────────────────────────╯
╭───────────────────────────── Tracing Status ──────────────────────────────╮
│ │
│ Info: Tracing is disabled. │
│ │
│ To enable tracing, do any one of these: │
│ • Set tracing=True in your Crew/Flow code │
│ • Set CREWAI_TRACING_ENABLED=true in your project's .env file │
│ • Run: crewai traces enable │
│ │
╰───────────────────────────────────────────────────────────────────────────╯
끝.
[1] https://boramchan-corgi.tistory.com/46
*** EOF ***
'SW' 카테고리의 다른 글
| 에이전틱 프로그래밍 데모 해보기 (2/2, Google Gemini) (0) | 2026.04.12 |
|---|---|
| Docker Image/Container 확인/실행/삭제 방법 (0) | 2026.04.12 |
| Ubuntu 에서 windows 의 4분할 화면 쓰는 방법 (0) | 2026.04.12 |
| WARNING: Unable to detect NVIDIA/AMD GPU on Docker (0) | 2026.03.25 |
| 설치한 Nvidia드라이버, Docker 에서 그냥 쓰기 : NVIDIA Container Toolkit (0) | 2026.03.25 |
