[AI] CrewAI 에이전트를 활용한 키워드 기반 맛집 검색 개선

2025. 2. 16. 19:04·AI

처음에는 사용자가 원하는 지역을 입력하면 Google Maps API를 통해 주변 맛집을 찾아주고, 필터링을 거쳐 최적의 식당을 추천하면 될 줄 알았다. 하지만 직접 테스트해보니, 생각만큼 좋은 결과가 나오지 않았다. 단순히 지역을 기반으로 검색하는 방식만으로는 사용자의 구체적인 요구사항이 반영되지 않았고, 원하는 스타일의 맛집을 추천하기 어려웠다.

 

 

1. 기존 방식의 문제점

기존에는 사용자가 입력한 여행 일정에서 지역(location) 정보만 추출하여 맛집을 검색하는 방식이었다. 하지만 이렇게 하면 단순히 지역 내 식당 목록만 가져올 뿐, 사용자가 원하는 조건(가족과 함께 갈 수 있는 곳, 반려견 동반 가능 등)이 반영되지 않는 문제가 발생했다.

문제점 정리

  1. 사용자 요구가 반영되지 않음
    • 지역 기반으로만 검색하면, 사용자가 원하는 특정 스타일의 맛집(예: 아이와 함께 가기 좋은 식당, 프라이빗한 분위기의 레스토랑 등)을 추천하지 못했다.
  2. 추천 가능한 맛집 수 부족
    • Google Maps API에서 기본 리스트를 가져온 후 필터링을 시도했지만, 처음부터 적절한 리스트가 수집되지 않으면 필터링을 해도 추천할 맛집이 거의 없는 문제가 있었다.

이러한 한계를 해결하기 위해, 단순한 지역 검색이 아니라 사용자의 전체 여행 데이터를 기반으로 적절한 검색 키워드를 생성하는 방식으로 개선했다. 이를 통해 사용자의 요구사항을 반영한 맞춤형 맛집 추천이 가능하도록 변경했다.

 

 

2. 개선된 로직

이전에는 단순히 지역 정보만을 검색에 활용했지만, 이제는 AI가 사용자의 여행 일정과 요구사항을 분석하여 최적의 검색 키워드를 생성한 후, 해당 키워드를 기반으로 검색을 수행하는 방식으로 변경했다.

개선된 검색 방식

  1. 사용자가 입력한 여행 일정 데이터를 AI 에이전트에게 전달
  2. AI가 여행 정보와 프롬프트를 분석하여 3개의 검색 키워드 생성
  3. Google Places API를 활용해 키워드 기반으로 맛집 검색 수행
  4. 네이버 API를 활용해 추가적인 식당 정보(리뷰, 상세 정보 등) 보완
  5. 최종적으로 필터링을 거쳐 사용자 맞춤형 맛집 리스트 반환

 

3. 키워드 추출 AI 에이전트

사용자가 입력한 여행 일정(지역, 일정, 연령대, 동행자, 여행 목적, 요청사항) 을 분석하여,
Google Maps API에서 검색할 최적의 3가지 키워드를 생성하는 AI 에이전트를 설계했다.

키워드 추출 에이전트 코드

이 에이전트는 사용자의 여행 정보와 프롬프트를 입력받아 3개의 검색 키워드를 생성한다.
각 키워드는 "지역명 + 목적" 형식으로 구성되며, 실제 검색에 효과적인 키워드만을 사용한다.

"keyword_extraction": Agent(
    role="키워드 추출 전문가",
    goal="여행 정보와 프롬프트에서 맛집 검색에 필요한 정확히 3개의 핵심 키워드를 추출합니다.",
    backstory="""나는 자연어 처리 전문가로, 사용자의 요구사항에서 핵심 키워드를 추출하여 맛집 검색의 정확도를 높입니다.
    각 키워드는 '지역명 + 목적' 형식으로 구성하며, 실제 검색에 효과적인 구체적인 키워드만을 사용합니다.""",
    tools=[],
    llm=self.llm,
    verbose=True,
    async_execution=True,
    memory=True,
),

 

 

4. 키워드 생성 로직

Google Places API에서 효과적인 검색을 수행하기 위해, 키워드 생성 Task를 아래와 같이 구성했다.

Task(
    description=f"""이전 Task에서 얻은 좌표와 여행 정보를 바탕으로 맛집 검색에 사용할 가장 효과적인 검색 키워드 3개를 생성해주세요:
    
    # 입력 정보
    지역: {input_data['main_location']}
    좌표: 이전 태스크에서 생성된 좌표 결과
    여행 기간: {input_data['start_date']} ~ {input_data['end_date']}
    연령대: {input_data['ages']}
    동반자: {', '.join([f"{c['label']} {c['count']}명" for c in input_data['companion_count']])}
    요청사항: {prompt_text}

    # 규칙
    1. 정확히 3개의 검색 키워드를 생성할 것
    2. 각 키워드는 "{input_data['main_location']} + 목적" 형식으로 구성할 것
    3. 실제 검색에 효과적인 구체적인 키워드로 구성할 것
    4. 반환 형식은 다음과 같이 할 것:
    {{
        "coordinates": "이전 Task의 coordinates 값을 그대로 전달",
        "keywords": ["키워드1", "키워드2", "키워드3"]
    }}
    """,
    agent=self.agents["keyword_extraction"],
    expected_output="좌표와 3개의 맛집 검색 키워드",
),

실제 생성된 키워드 예시

 

 

5. Google Maps API를 활용한 맛집 검색

이제 생성된 키워드를 활용하여 Google Places API에서 맛집 리스트를 검색한다.

Google Places API를 활용한 검색 로직

class RestaurantBasicSearchTool(BaseTool):
    name: str = "RestaurantBasicSearchTool"
    description: str = "주어진 좌표와 검색 키워드를 기반으로 구글맵에서 식당 정보를 검색합니다."

    async def _arun(self, coordinates: str, search_keywords: List[str]) -> List[Dict]:
        url = "https://maps.googleapis.com/maps/api/place/textsearch/json"
        all_candidates = []
        lat, lng = coordinates.split(",")

        print(f"[keyword]: {search_keywords}")

        for keyword in search_keywords:
            simplified_keyword = keyword.split(" - ")[-1]  # 지역명 제거 후 검색
            params = {
                "query": simplified_keyword,
                "language": "ko",
                "type": "restaurant",
                "location": f"{lat},{lng}",
                "radius": "5000",
                "key": GOOGLE_MAP_API_KEY,
            }
            async with aiohttp.ClientSession() as session:
                async with session.get(url, params=params) as response:
                    data = await response.json()
                    results = data.get("results", [])
                    all_candidates.extend(results)
        
        return all_candidates

검색 방식 개선

  1. Google Places API에서 - 뒤의 텍스트(예: "해운대구 고깃집" 등)만 검색
  2. 좌표 기반 검색을 수행하여 보다 정밀한 결과 확보
  3. 최대 40개까지 결과를 수집하여 필터링을 진행

 

마무리

처음에는 단순한 지역 검색으로도 충분할 거라고 생각했지만, 직접 테스트를 하면서 많은 한계를 경험했다. CREW AI 에이전트를 적용한 후, 원하는 검색 결과가 훨씬 더 정확해졌다는 점이 인상적이었다. 앞으로도 사용자의 요구를 더욱 정밀하게 반영할 수 있도록 지속적으로 개선해 나가야겠다고 느꼈다.

'AI' 카테고리의 다른 글

[AI] 딥러닝 프레임워크 비교: 텐서플로우 vs 파이토치 vs 케라스  (0) 2025.03.03
[AI] 네이버 웹 검색 API × CrewAI 식당 검색, 동기 방식에서 비동기로 업그레이드  (0) 2025.02.11
[AI] CrewAI 태스크 결과가 서비스에서 라우터로 정상 전달되지 않는 문제 해결과정  (0) 2025.02.06
[AI] CrewAI를 활용한 맛집 추천 시스템 개선 과정(데이터 최적화 vs 정확도)  (0) 2025.02.03
[AI] CrewAI에서의 Tool, Agent, Task 개념  (0) 2025.02.02
'AI' 카테고리의 다른 글
  • [AI] 딥러닝 프레임워크 비교: 텐서플로우 vs 파이토치 vs 케라스
  • [AI] 네이버 웹 검색 API × CrewAI 식당 검색, 동기 방식에서 비동기로 업그레이드
  • [AI] CrewAI 태스크 결과가 서비스에서 라우터로 정상 전달되지 않는 문제 해결과정
  • [AI] CrewAI를 활용한 맛집 추천 시스템 개선 과정(데이터 최적화 vs 정확도)
dud9902
dud9902
개발자 취준생 기록일지
  • dud9902
    dud's DevStory
    dud9902
  • 전체
    오늘
    어제
    • 분류 전체보기 (79)
      • SpringBoot (14)
      • React (12)
      • Python (14)
      • AI (21)
      • DB (6)
      • Figma (1)
      • Markdown (1)
      • AWS (7)
      • 기타 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    twilio
    EC2
    AI
    redis
    Python
    CrewAI
    db
    AWS
    miniforge
    FastAPI
    pydantic
    docker
    recognize anything
    springboot
    langchain
    Agent
    스프링부트
    pytorch
    의존성 주입
    react
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dud9902
[AI] CrewAI 에이전트를 활용한 키워드 기반 맛집 검색 개선
상단으로

티스토리툴바