자습서 1: Cortex Search를 사용하여 간단한 검색 애플리케이션 개발¶
소개¶
이 자습서에서는 간단한 검색 애플리케이션을 위한 Cortex Search를 시작하는 방법을 설명합니다.
알아볼 내용¶
AirBnb 목록 데이터 세트에서 Cortex Search Service를 생성합니다.
Cortex Search Service를 쿼리할 수 있는 Streamlit in Snowflake 앱을 생성합니다.
전제 조건¶
이 자습서를 완료하려면 다음과 같은 필수 조건이 필요합니다.
데이터베이스, 테이블, 가상 웨어하우스 오브젝트, Cortex Search Service 및 Streamlit 앱을 만드는 데 필요한 권한을 부여하는 역할이 있는 Snowflake 계정과 사용자가 있습니다.
이러한 요구 사항을 충족하기 위한 지침은 20분만에 Snowflake 시작하기 섹션을 참조하십시오.
1단계: 설정¶
샘플 데이터 가져오기¶
Huggingface에서 호스팅 되는 샘플 데이터 세트를 사용하며, 단일 JSON 파일로 다운로드할 수 있습니다. 다음 링크를 따라 브라우저에서 직접 파일을 다운로드합니다.
참고
자습서 환경이 아닌 환경에서는 Snowflake 테이블에 이미 있는 데이터를 가져와서 사용할 수도 있습니다.
데이터베이스, 테이블, 웨어하우스 만들기¶
다음 문을 실행하여 이 자습서에 필요한 데이터베이스와 가상 웨어하우스를 생성합니다. 자습서를 마친 후 이러한 오브젝트를 삭제할 수 있습니다.
CREATE DATABASE IF NOT EXISTS cortex_search_tutorial_db;
CREATE OR REPLACE WAREHOUSE cortex_search_tutorial_wh WITH
WAREHOUSE_SIZE='X-SMALL'
AUTO_SUSPEND = 120
AUTO_RESUME = TRUE
INITIALLY_SUSPENDED=TRUE;
다음 사항을 참고하십시오.
CREATE DATABASE
문으로 데이터베이스를 만듭니다. 데이터베이스에는 ‘public’이라는 스키마가 자동으로 포함됩니다.CREATE WAREHOUSE
문으로 처음에 일시 중단되는 웨어하우스를 만듭니다. 또한 이 문으로AUTO_RESUME = true
가 설정되어, 컴퓨팅 리소스가 필요한 SQL 문을 실행할 때 웨어하우스를 자동으로 시작하게 됩니다.
2단계: Snowflake에 데이터 로드¶
검색 서비스를 생성하려면 먼저 예제 데이터를 Snowflake에 로드해야 합니다.
데이터 세트는 Snowsight 에서 업로드하거나 SQL을 사용하여 업로드할 수 있습니다. Snowsight 에서 업로드하려면:
왼쪽 탐색 표시줄 위에 있는 + Create 버튼을 선택합니다.
그런 다음 Table » From File 을 선택합니다.
오른쪽 상단 모서리에 있는 드롭다운에서 테이블의 웨어하우스로 새로 생성한 웨어하우스를 선택합니다.
JSON 데이터 파일을 대화 상자에 끌어서 놓습니다.
위에서 생성한 데이터베이스를 선택하고 PUBLIC 스키마를 지정합니다.
마지막으로 이름이
airbnb_listings
인 새 테이블 생성을 지정하고 Next 를 선택합니다.Load Data into Table 대화 상자에서 다음과 같이 조정합니다. 먼저 이 자습서에는 적용되지 않으므로
image_embeddings
,images
,text_embeddings
열의 선택을 취소합니다. 두 번째로,amenities
필드의 데이터 타입을 ARRAY 유형으로 조정합니다.이러한 조정이 완료되면 Load 를 선택하여 계속 진행합니다.
잠시 후, 데이터가 로드되었다는 확인 페이지가 표시됩니다.
Query Data 를 선택하면 다음 단계에서 사용할 새 Snowsight 워크시트가 열립니다.
3단계: 검색 서비스 만들기¶
다음 SQL 명령을 실행하여 새 테이블에 대한 검색 서비스를 생성합니다.
CREATE OR REPLACE CORTEX SEARCH SERVICE cortex_search_tutorial_db.public.airbnb_svc
ON listing_text
ATTRIBUTES room_type, amenities
WAREHOUSE = cortex_search_tutorial_wh
TARGET_LAG = '1 hour'
AS
SELECT
room_type,
amenities,
price,
cancellation_policy,
('Summary\n\n' || summary || '\n\n\nDescription\n\n' || description || '\n\n\nSpace\n\n' || space) as listing_text
FROM
cortex_search_tutorial_db.public.airbnb_listings;
- 이 명령의 인자를 분석해 보겠습니다.
ON
매개 변수는 검색할 쿼리의 열을 지정합니다. 이 경우, 소스 쿼리에서 기본 테이블에 있는 여러 텍스트 열의 연결로 생성되는listing_text
입니다.ATTRIBUTES
매개 변수는 검색 결과를 필터링할 수 있는 열을 지정합니다. 이 예제는listing_text
열에 쿼리를 발행할 때room_type
및amenities
에 필터링합니다.WAREHOUSE
및TARGET_LAG
매개 변수는 각각 사용자가 제공한 웨어하우스와 검색 서비스의 원하는 최신성을 지정합니다. 이 예제에서는cortex_search_tutorial_wh
웨어하우스를 사용하여 인덱스를 생성하고 새로 고침을 수행하며, 소스 테이블AIRBNB_LISTINGS
뒤에 서비스를'1 hour'
이하로 유지하도록 지정합니다.AS
필드는 서비스의 소스 테이블을 정의합니다. 이 예제에서는 원래 테이블의 여러 텍스트 열을 검색 열listing_text
로 연결하여 쿼리가 여러 필드를 검색할 수 있도록 합니다.
단계 4: Streamlit 앱 생성¶
Python SDK로 서비스를 쿼리(snowflake
Python 패키지 사용)할 수 있습니다. 이 자습서에서는 Streamlit in Snowflake 애플리케이션에서 Python SDK를 사용하는 방법을 보여줍니다.
먼저 서비스 생성 단계에서 전역 Snowsight UI 역할이 서비스를 생성하는 데 사용된 역할과 동일한지 확인합니다.
Snowsight 에 로그인합니다.
왼쪽 탐색 메뉴에서 Projects » Streamlit 를 선택합니다.
+ Streamlit App 를 선택합니다.
중요: 앱 위치에 대한
cortex_search_tutorial_db
데이터베이스와public
스키마를 선택합니다.Streamlit in Snowflake 편집기의 왼쪽 창에서 Packages 를 선택하고
snowflake
(버전 >= 0.8.0)를 추가하여 애플리케이션에 패키지를 설치합니다.예제 애플리케이션 코드를 다음 Streamlit 앱으로 바꿉니다.
# Import python packages import streamlit as st from snowflake.core import Root from snowflake.snowpark.context import get_active_session # Constants DB = "cortex_search_tutorial_db" SCHEMA = "public" SERVICE = "airbnb_svc" BASE_TABLE = "cortex_search_tutorial_db.public.airbnb_listings" ARRAY_ATTRIBUTES = {"AMENITIES"} def get_column_specification(): """ Returns the name of the search column and a list of the names of the attribute columns for the provided cortex search service """ session = get_active_session() search_service_result = session.sql(f"DESC CORTEX SEARCH SERVICE {DB}.{SCHEMA}.{SERVICE}").collect()[0] st.session_state.attribute_columns = search_service_result.attribute_columns.split(",") st.session_state.search_column = search_service_result.search_column st.session_state.columns = search_service_result.columns.split(",") def init_layout(): st.title("Cortex AI Search") st.markdown(f"Querying service: `{DB}.{SCHEMA}.{SERVICE}`".replace('"', '')) def query_cortex_search_service(query, filter={}): """ Queries the cortex search service in the session state and returns a list of results """ session = get_active_session() cortex_search_service = ( Root(session) .databases[DB] .schemas[SCHEMA] .cortex_search_services[SERVICE] ) context_documents = cortex_search_service.search( query, columns=st.session_state.columns, filter=filter, limit=st.session_state.limit) return context_documents.results @st.cache_data def distinct_values_for_attribute(col_name, is_array_attribute=False): session = get_active_session() if is_array_attribute: values = session.sql(f''' SELECT DISTINCT value FROM {BASE_TABLE}, LATERAL FLATTEN(input => {col_name}) ''').collect() else: values = session.sql(f"SELECT DISTINCT {col_name} AS VALUE FROM {BASE_TABLE}").collect() return [ x["VALUE"].replace('"', "") for x in values ] def init_search_input(): st.session_state.query = st.text_input("Query") def init_limit_input(): st.session_state.limit = st.number_input("Limit", min_value=1, value=5) def init_attribute_selection(): st.session_state.attributes = {} for col in st.session_state.attribute_columns: is_multiselect = col in ARRAY_ATTRIBUTES st.session_state.attributes[col] = st.multiselect( col, distinct_values_for_attribute(col, is_array_attribute=is_multiselect) ) def display_search_results(results): """ Display the search results in the UI """ st.subheader("Search results") for i, result in enumerate(results): result = dict(result) container = st.expander(f"[Result {i+1}]", expanded=True) # Add the result text. container.markdown(result[st.session_state.search_column]) # Add the attributes. for column, column_value in sorted(result.items()): if column == st.session_state.search_column: continue container.markdown(f"**{column}**: {column_value}") def create_filter_object(attributes): """ Create a filter object for the search query """ and_clauses = [] for column, column_values in attributes.items(): if len(column_values) == 0: continue if column in ARRAY_ATTRIBUTES: for attr_value in column_values: and_clauses.append({"@contains": { column: attr_value }}) else: or_clauses = [{"@eq": {column: attr_value}} for attr_value in column_values] and_clauses.append({"@or": or_clauses }) return {"@and": and_clauses} if and_clauses else {} def main(): init_layout() get_column_specification() init_attribute_selection() init_limit_input() init_search_input() if not st.session_state.query: return results = query_cortex_search_service( st.session_state.query, filter = create_filter_object(st.session_state.attributes) ) display_search_results(results) if __name__ == "__main__": st.set_page_config(page_title="Cortex AI Search and Summary", layout="wide") main()
위의 Streamlit-in-Snowflake 코드의 주요 구성 요소에 대한 간략한 분석은 다음과 같습니다.
get_column_specification
은 DESCRIBE SQL 쿼리를 사용하여 검색 서비스에서 사용 가능한 특성에 대한 정보를 가져와 Stremalit 상태에 저장합니다.init_layout
은 페이지의 헤더와 소개를 설정합니다.query_cortex_search_service
는 Python 클라이언트 라이브러리를 통해 Cortex Search Service 쿼리를 처리합니다.create_filter_object
는 Streamlit 양식에서 선택한 필터 특성을 적절한 오브젝트로 처리하여 Python 라이브러리가 Cortex Search를 쿼리하는 데 사용할 수 있도록 합니다.distinct_values_for_attribute
는 필터링 가능한 각 특성에 대해 드롭다운 메뉴를 채울 수 있는 값을 결정합니다.init_search_input
,init_limit_input
,init_attribute_selection
는 검색 쿼리에 대한 입력, 결과 수 제한, 특성 필터를 초기화합니다.display_search_results
는 검색 결과를 결과 페이지에 표시되는 마크다운 요소로 서식을 지정합니다.
5단계. 정리¶
정리(선택 사항)¶
자습서를 시작하기 전의 상태로 시스템을 되돌리려면 다음 DROP <오브젝트> 명령을 실행합니다.
DROP DATABASE IF EXISTS cortex_search_tutorial_db;
DROP WAREHOUSE IF EXISTS cortex_search_tutorial_wh;
데이터베이스를 삭제하면 테이블과 같은 모든 하위 데이터베이스 오브젝트가 자동으로 제거됩니다.
다음 단계¶
축하합니다! Snowflake에서 텍스트 데이터를 기반으로 간단한 검색 앱을 성공적으로 생성했습니다. 자습서 2 로 이동하여 Cortex LLM 함수 에 레이어를 지정하여 Cortex Search로 AI 챗봇을 구축하는 방법을 살펴볼 수 있습니다.
추가 리소스¶
또한 다음 리소스를 사용하여 계속 학습할 수 있습니다.