Aptible AI의 엔지니어링 팀은 SRE 팀이 생산 문제를 조사하고 해결할 수 있도록 돕기 위해 지난 4개월 동안 AI 에이전트를 구축했습니다. 유사한 목적으로 자체 에이전트를 구축하는 중이었던 수많은 초기 테스터 및 디자인 파트너와 이야기를 나눴기 때문에 자체 에이전트로 수행한 작업과 구축 방법을 설명하는 가이드를 함께 작성하기로 결정했습니다. 직접 하나.
다음 단계별 튜토리얼에서는 다음 방법을 알려드립니다.
하지만 먼저 몇 가지 고려 사항과 전문가의 팁을 알아보세요.
? 고려사항: 새로운 것을 구축할 필요가 없다면 구축해서는 안 됩니다. 그렇습니다. 많은. 시장에 나와 있는 도구. 특정 사용 사례에 따라 자신에게 적합한 것을 찾을 수도 있습니다.
Aptible이 자체 사고 대응을 검색하고 최종적으로 개발하게 된 원동력은 지식 사일로로 어려움을 겪고 있으며 특정 시스템에 문제가 발생할 때마다 3~4명의 해당 분야 전문가에게 의존하는 경향이 있었기 때문입니다.
그래서 우리는 정보 검색을 개선하기 위해 Danswer라는 오픈 소스 도구로 시작했습니다(인기 상용 경쟁사인 Glean과 유사). Slack에 직접 연결되어 다양한 정보 소스에서 자연어 질문에 대한 답변을 검색할 수 있었습니다. 문제는 색인된 데이터(예: 문서 및 채팅 기록)로만 제한된다는 것입니다.
⚒️ 우리가 구축한 것: 우리에게 필요한 것은 (문서 및 Slack뿐만 아니라) 다른 모든 시스템과 통합할 수 있는 도구였습니다. 우리는 로그와 지표, 애플리케이션 상태를 검색하고 사고가 끝난 후 보고서와 사후 분석을 생성해야 했습니다. 그래서 우리는 기본적으로 실시간 데이터와 인덱싱된 데이터 모두에 연결할 수 있는 일련의 통합을 기반으로 구축된 AI 에이전트를 설계했습니다. 자세한 내용은 나중에!
? 프로 팁: 자신만의 제품을 만들기로 결정하기 전에 이미 사용 가능한 제품이 무엇인지 살펴보세요. 시작하기 좋은 곳은 Reddit에서 아이디어를 크라우드소싱하거나(이 스레드 중 하나를 확인하세요) 오픈 소스 도구 중 일부를 확인하는 것입니다(특별히 사고 대응 도구를 찾고 있다면 여기 github에서 시작하기 좋은 곳이 있습니다). ). 내일부터 사용할 수 있는 오픈 소스 AI 에이전트의 목록도 많이 있습니다.
? 고려사항: 위에서 언급한 것처럼 여기서 가장 큰 고려사항은 에이전트가 어떤 종류의 정보에 액세스해야 합니까?입니다. API를 통해 단순히 타사 제공업체와 통합하면 문제가 없을 수도 있지만, 필요에 따라 보다 구체적인 통합이 필요한 경우 통합 작동 방식에 대해 좀 더 신중하게 생각해야 합니다.
제작을 시작하기 전에 무엇을 통합해야 할지 신중하게 고려하면 나중에 골치 아픈 일을 덜 수 있습니다. 데이터베이스를 쿼리하기 위해 사용자 정의 스크립트를 실행할 수 있으려면 에이전트가 필요합니까? 로그 및 지표를 실시간으로 검색해야 하며, 해당 정보를 검색하도록 에이전트를 어떻게 설계하시겠습니까? 소스에 대한 링크가 반환됩니까? 수동으로 조사해야 하는 로그 덩어리를 반환합니까, 아니면 예외가 있을 수 있는 위치를 추론할 수 있습니까?
⚒️ 우리가 구축한 것: Aptible AI는 일련의 통합을 기반으로 구축되었습니다. 통합은 단순히 제3자 공급자에 대한 연결이 아니라 우리 팀이 해당 공급자를 사용하는 방식에 고유한 구성 모음이기도 합니다. 예를 들어 Aptible AI는 동일한 공급자에 대해 여러 통합을 지원합니다. 왜냐하면 우리는 해당 공급자를 다른 방식으로 사용하기를 원할 수 있기 때문입니다. 팀마다 Datadog을 다르게 사용하고 서로 다른 측정항목에 관심을 두거나 서로 다른 태그를 사용하므로 각 팀은 필요한 방식으로 동일한 도구에 대한 통합을 사용할 수 있습니다.
Aptible AI는 다음을 포함한 다양한 일반 SRE 도구를 지원합니다.
이러한 통합의 실제 구현은 세 가지 사용자 정의 범주 중 하나에 속합니다.
우선 사용자 정의가 필요 없는 기본 통합이 있습니다(PagerDuty가 한 예입니다). PagerDuty에서 데이터를 가져와 AI의 컨텍스트에 추가하는 것뿐이므로 PagerDuty 통합을 활용하는 모든 팀은 이를 동일한 방식으로 사용합니다.
다음으로 일반 InfluxDB 통합을 기반으로 구축되었지만 컨테이너 측정항목 조회 및 재시작 활동 조회와 같은 특정 사용 사례에 맞게 맞춤설정된 더 많은 맞춤설정 가능한 통합(예: 이전의 Datadog 예시)이 있습니다.
마지막으로 Aptible 외부의 누구에게도 이해가 되지 않을 수 있는 완전한 맞춤형 도구가 있습니다(예를 들어 애플리케이션용 컨테이너를 가져오는 통합이 있습니다). 이는 인프라를 운영하는 방식에 전적으로 특정되며 경량 PubSub 인터페이스 또는 웹소켓 기반의 "안전한" 프록시를 통해 구현할 수 있습니다.
? 프로 팁: 적을수록 좋습니다! 모델에 선택할 수 있는 도구를 너무 많이 제공하면 잘못된 도구를 선택하여 혼란을 겪을 수 있습니다. 자세한 내용은 다음 섹션에서
? 고려사항: 모델에 관한 사항은 다음과 같습니다. 매일 새로운 모델이 나타나고 하나를 선택할 때 염두에 두어야 할 몇 가지 고려 사항이 있습니다(주로 특정 사용 사례와 관련됨). 직접 호스팅해야 하나요? 에이전트가 대화형이거나 작업 기반이거나 둘 다여야 합니까? 간단한 작업을 수행할 것인가 아니면 복잡한 작업을 수행할 것인가? 실시간 성능이 필요하신가요?
해당 콘텐츠는 이미 곳곳에 있으므로 존재하는 모든 모델을 살펴볼 필요는 없지만(자세한 내용을 알고 싶다면 이 자료가 훌륭한 리소스입니다), 우리가 내린 결정을 직접 살펴볼 수는 있습니다. Aptible AI를 구축할 때 고려한 옵션과 고려한 옵션.
절충점을 피할 수 없기 때문에 까다로운 과정입니다. 복잡한 작업을 수행하기 위해 에이전트가 필요한 경우 속도와 비용을 약간 희생해야 합니다.
모델의 크기, 기능 및 아키텍처는 작업에 간단한 분류가 필요한지 아니면 매우 복잡한 추론 및 상호 작용이 필요한지에 따라 크게 달라집니다. 단순하다면 의사결정 트리, 랜덤 포레스트 또는 단순 신경망과 같은 더 작고 가벼운 모델이면 충분합니다. 더 복잡하다면 GPT-4, BERT 또는 유사한 변환기 기반 아키텍처와 같은 더 강력한 모델을 고려할 수 있습니다.
보안 문제를 피하기 위해 셀프 호스팅을 선택하는 경우 자체 호스팅 버전이 호스팅 옵션보다 뒤처지기 때문에 기능을 희생해야 할 가능성이 높습니다.
에이전트가 분야별 지식에 대한 교육을 받아야 한다면 미세 조정을 위해 자체 데이터세트를 선별하거나 생성해야 합니다. 데이터 품질 문제를 피하기 위해 이미 대규모 데이터 세트에 대해 훈련된 사전 훈련된 모델을 사용할 수 있는지 확인하십시오(단, 에이전트가 액세스해야 하는 데이터에 따라 불가능할 수도 있음).
⚒️ 우리가 구축한 것: 우리는 현재 Aptible AI에 GPT-4o를 사용하고 있습니다. 왜냐하면 이것이 최고 품질의 답변을 제공할 가능성이 가장 높다고 믿기 때문입니다. 그러나 Aptible AI를 사용하는 고객은 자체 모델(자체 호스팅 모델 포함)을 사용하고 싶어할 수도 있다는 것을 알고 있습니다. 따라서 우리는 이를 염두에 두고 제작하고 있습니다.
? 프로 팁: 귀하의 에이전트는 귀하가 제공하는 정보만큼만 똑똑합니다. LLM은 귀하가 제공한 정보를 언제 어떻게 사용해야 하는지 이해하는 데 도움이 필요하며, 정보를 해석하는 방법에 대한 지침을 제공하지 않으면 단지 뭔가를 만들어낼 뿐입니다. LLM에 제공하는 정보를 사전에 선별하는 데 많은 노력을 기울이십시오!
? 고려 사항: 가능한 한 많은 데이터(문서, Slack 대화, 코드 저장소, 문제 추적기 등)를 검색하여 RAG 애플리케이션에 모두 넣고 싶은 유혹을 느낄 수 있습니다*, * 그리고 질문을 해보세요. 그러나 우리의 경험에 따르면 이것이 유용하기에는 거의 항상 노이즈가 너무 많습니다. 신속한 엔지니어링이 필요한 곳입니다.
이미 언급한 바 있지만 여기서 프롬프트 엔지니어링은 퍼즐의 중요한 부분입니다(프롬프트 기술에 대한 훌륭한 개요를 보려면 여기를 확인하세요). 신속한 엔지니어링이 향상될수록 에이전트의 성능도 향상됩니다.
상황에 따라 Aptible AI를 구축할 때 (시간이 지남에 따라) 고려한 몇 가지 사항은 다음과 같습니다.
제로샷 프롬프트: 대부분의 사람들이 ChatGPT와 대화할 때 수행하는 작업입니다. 그들은 단지 질문을 하고 응답을 받습니다. 반응이 좋지 않으면 질문을 다르게 하기도 합니다.
Few-shot 프롬프트: 약간 더 경험이 많은 사람들이 ChatGPT와 대화할 때 하는 작업입니다. 그들은 질문을 하고 그들이 원하는 출력의 예를 포함합니다. 기본 모델이 이미 수행 방법을 알고 있는 매우 간단한 작업에 대해 제로 샷 및/또는 퓨샷 프롬프트를 사용할 수 있습니다.
RAG(검색 증강 생성): 이는 모델이 추가 컨텍스트를 검색하고 이를 사용하여 질문에 답할 수 있도록 하는 기술입니다. 이는 AI 기반 문서 검색에 특히 유용합니다(참조: Glean 및 Danswer).
ReAct: 이 기술을 사용하면 에이전트는 인간의 추론과 가장 유사한 문제 해결을 위해 반복적인 방식으로 '생각'을 생성하고 '행동'을 취할 수 있습니다. ReAct는 문서 및 도구를 통해 실시간으로 참조 항목을 탐색하여 답변을 작성하는 등 다소 복잡한 문제에 적합합니다.
유념해야 할 중요한 점은 이러한 기술을 혼합하여 사용할 수 있다는 것입니다(다중 에이전트 접근 방식은 다음에서 다루겠습니다). 우리가 한 일은 다음과 같습니다…
⚒️ 우리가 구축한 것: Aptible AI는 다중 에이전트 구조를 가지고 있기 때문에(나중에 자세히 설명) 작업/질문의 복잡성에 따라 ReAct와 RAG를 혼합하여 구현했습니다.
따라서 AI에게 질문을 하면 모든 통합(사용 방법에 대한 지침 포함)이 AI에 전달됩니다. 그런 다음 AI는 사용 가능한 정보를 기반으로 어떤 도구를 호출할지 결정합니다. 각 통합 호출 후 AI는 답변을 제공하기에 충분한 정보가 있는지 결정하거나 추가 통합이 관련되어 잠재적으로 추가 정보를 생성할 수 있다고 결정할 수 있습니다.
이 과정 전반에 걸쳐 우리는 AI가 몇 가지 다른 메커니즘을 통해 어떤 통합을 활용할지에 대해 더 나은 결정을 내릴 수 있도록 돕기 위해 노력하고 있습니다.
통합을 위한 광범위한 프롬프트 엔지니어링을 통해 각 통합을 언제, 어떻게 사용할지, 그리고 출력을 해석하는 방법을 명확하게 확인합니다.
우리는 AI가 통합 응답의 가치를 자체 평가하도록 요청하는 자체 평가 시스템을 구축했습니다. AI가 통합을 호출할 때 어리석은 결정을 내리거나 잘못된 입력을 제공하는 경우에도 통합의 출력이 유용한지 자체 평가하도록 요청하면 일반적으로 사후에 이를 인식할 수 있습니다. 그런 다음 이를 사용하여 특정 출력이 응답에 얼마나 영향을 미치는지 영향을 미칠 수 있습니다. AI가 지속적으로 잘못된 결정을 내리는 경우 AI가 진행되지 않도록 차단할 수도 있습니다.
저희는 과거 경험을 바탕으로 Naïve Bayes를 구현했습니다. 예를 들어, 대부분의 경우 통합 A를 호출한 다음 B를 호출하여 유용한 결과를 얻는다면 계속 그렇게 하는 것이 유용할 것입니다. 또한 에이전트는 이전의 유사한 사고와 비교하는 등의 방법을 사용하여 특정 시나리오에서 어떤 통합이 유용한지, 언제 유용한지 더욱 좁힐 수 있습니다.
? 전문가 팁: 겉으로는 맞지만 사실은 아닌 말도 안되는 답변을 피하려면 한 걸음 물러서서 AI로 해결하려는 문제에 대해 일반적으로 가장 유용한 정보가 어디서 나오는지 생각해 보세요. – 그런 다음 이를 기반으로 에이전트를 설계하세요.
? 고려사항: 다중 에이전트 접근 방식이 점점 더 대중화되고 있지만 사용 사례에 따라 복잡하고 잠재적으로 불필요할 수 있습니다. 복잡한 문제를 해결하기 위해 다양한 기술을 사용하여 협력하는 상담원 팀을 보유하는 것은 매우 유용할 수 있습니다.
예를 들어 특정 인프라와 관련이 없는 Slack의 질문을 봇에게 묻는 경우(1995년 월드 시리즈에서 누가 우승했는지 알고 싶을 수도 있음) 제로샷 기반으로 에이전트를 구축할 수 있습니다. Slack(또는 Slack이 있는 모든 곳)과 통합된 ChatGPT 역할을 하도록 유도합니다.
그러나 질문이나 요구 사항이 복잡한 경우에는 기본적으로 소규모 연구 팀 역할을 하여 서로 다른 소스에서 지능적인 방식으로 데이터를 수집하고 분석하는 에이전트 팀을 갖는 것이 유용할 것입니다.
⚒️ 우리가 구축한 것: Aptible AI는 어떤 유형의 질문이나 작업을 해결해야 하는지 결정하는 브로커 에이전트로 시작하는 다중 에이전트 접근 방식을 사용합니다.
? 프로 팁: 다중 에이전트 접근 방식을 사용하지 않는 것보다 리팩토링하는 것이 더 쉽습니다! 따라서 그런 식으로 에이전트 구축을 시작하기 전에 해당 정보가 필요한지 확인하세요.
? 고려사항: Aptible AI 초기 사용자들과 대화할 때 많이 나오는 주제는 다음과 같습니다. 대부분의 엔지니어링 팀은 새로운 도구를 구현할 때 결국 보안 팀과 마주해야 하며, 데이터가 안전한지 확인하는 것이 중요합니다(특히 규제가 엄격한 업계에서 일하는 경우). 따라서 가장 먼저 해야 할 일은 조직의 AI 보안 정책을 아는 것입니다. 그런 다음 잠재적인 데이터 유출이나 외부 위협으로부터 보호하기 위해 수행할 수 있는 몇 가지 작업이 있습니다.
⚒️ 우리가 구축한 것: 우선 우리는 데이터를 학습하지 않는 모델을 사용합니다. 우리는 자체 호스팅이든 다른 것이든 보안과 관련하여 고객이 필요로 하는 것이 무엇인지에 대해 여전히 많은 것을 발견하고 있습니다! 계속 지켜봐 주시기 바랍니다.
? 프로 팁: AI에 액세스 권한을 부여하거나 프롬프트에 포함하는 데이터에 주의하세요. 특히 해당 데이터가 최종 사용자와 공유되어서는 안 되는 경우에는 더욱 그렇습니다! 로그와 같이 예측할 수 없는 데이터를 포함해야 하는 경우 Nightfall과 같은 도구를 사용하여 LLM 및 최종 사용자에게 전달된 내용이 삭제되었는지 확인하는 것이 좋습니다
아, 그리고 당연히 사용이 가능해야 합니다!
? 고려사항: 에이전트를 어떻게 사용할 계획인가요? UI가 있어야 하나요? 조직 전체에서 사용되나요?
봇 주변의 UX에 관해서는 바퀴를 재발명하는 데 시간을 소비할 필요가 없을 것입니다. Chainlit, Gradio 및 Streamlit과 같은 프레임워크는 사용자 인터페이스를 구축하거나 Slack과 같은 다른 워크플로 도구와 통합하기 위한 기본 제공 도구를 제공합니다. 에이전트로부터 좋은 답변을 얻는 데 집중할 수 있도록 다음 도구 중 하나를 사용하여 시작하세요!
⚒️ 우리가 구축한 것: 우리 Agent는 사건 대응을 위해 특별히 구축되었고 Slack 내에서 사건을 처리하기 때문에 주로 Slack을 UI로 사용합니다. 하지만 여기에는 한계가 있으므로 이를 해결하기 위해 최선을 다합니다(예: ChatGPT에서 볼 수 있듯이 에이전트가 입력을 모방하여 응답하는 것을 표시하는 대신 봇은 Slack의 질문에 ? 이모티콘으로 반응합니다). 또한 구성, 보고, 감사 및 분석을 위한 웹 UI도 설계했습니다.
? 전문가 팁: 필요한 경우 다른 UX로 쉽게 리팩터링할 수 있도록 LLM 코드를 최대한 분리하여 유지하세요.
자, 이제 모델, 기술, 프레임워크에 대한 이론적인 이야기로 넘어가겠습니다! 손을 더럽혀 나만의 에이전트를 구축할 시간입니다.
AI 구축의 끝없는 토끼굴을 탐구하기 전에 대화 보조 인터페이스 구축을 위한 인기 프레임워크인 Chainlit을 설정하여 성공을 위한 준비를 하겠습니다.
Chainlit은 LLM과 상호작용하기 위한 ChatGPT와 유사한 사용자 인터페이스뿐만 아니라 스레드, 메시지, 단계와 같은 대화 상호 작용을 모델링하기 위한 독보적인 빌딩 블록 세트를 제공합니다.
또한 Slack 및 Teams와 같은 인기 있는 채팅 도구는 물론 React 및 FastAPI와 같은 인기 도구와 인터페이스하기 위한 라이브러리와의 기본 통합을 제공하므로 원하는 경우 더 큰 애플리케이션으로 구축할 수 있습니다. .
간단히 말하면, Chainlit은 우리가 UI와 구성을 조작하는 대신 AI 어시스턴트를 개발하고 사용자로부터 피드백을 받는 데 집중할 수 있도록 많은 스캐폴딩과 번거로운 작업을 제거할 것입니다.
이 실습이 끝나면 귀하가 말한 내용을 간단히 에코하는 Chainlit 애플리케이션이 작동하게 됩니다. 다음 글에서는 AI 통합에 대해 살펴보겠습니다.
시작하기 전에 몇 가지 사항을 설정해야 합니다.
설정이 완료되면 계속하세요.
먼저 프로젝트를 설정하고 Chainlit을 종속성으로 추가합니다.
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
다음으로, 다음 콘텐츠로 프로젝트 루트에 app.py 파일을 만듭니다.
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
위 코드는 Chainlit에 handler_message 함수를 등록하여 메시지가 수신될 때마다 이 함수가 실행되도록 합니다.
현재 우리 함수는 "Received: "라는 접두어가 붙은 메시지를 사용자에게 간단히 에코합니다.
마지막으로 돌려보세요! 변경 시 --watch를 사용하여 코드를 핫 리로드할 수 있습니다.
poetry run chainlit run app.py --watch
이 명령을 실행하면 Chainlit 앱이 시작되고 브라우저에서 해당 UI가 열리며, 여기에서 메시지를 보내고 응답을 받을 수 있습니다.
Chainlit 앱을 스캐폴드하면 LLM에 연결하여 대화하고 인간과 같은 응답을 얻을 수 있습니다.
단순화를 위해 OpenAI의 호스팅 gpt-4o 모델을 사용하겠지만, 다른 공급자를 사용하는 것은 단지 구문 문제일 뿐입니다.
이 기사가 끝나면 ChatGPT와 상호 작용하는 방식과 유사하게 gpt-4o 모델에 메시지를 표시하고 응답을 받을 수 있습니다. 또한 후속 질문을 할 수 있도록 봇이 대화 컨텍스트를 유지하는지 확인하겠습니다.
시작하기 전에 다음이 필요합니다.
OpenAI 계정 및 API 키
먼저 OpenAI의 API와 인터페이스하도록 API 클라이언트를 구성하겠습니다. app.py 상단에 다음 코드를 추가하세요.
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
다음으로 사용자의 메시지를 OpenAI로 보내고 단순히 에코하는 대신 응답을 받도록 handler_message 함수를 업데이트해야 합니다. Handle_message 함수를 다음 함수로 바꾸세요:
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
이제 애플리케이션을 실행하면(또는 --watch 플래그를 사용하여 실행 상태로 두면) 질문을 하고 응답을 받을 수 있습니다.
좀 더 실험해보고 후속 질문을 해보면 봇이 사용자가 말한 내용을 '기억'하지 않는다는 사실을 알아차렸을 것입니다. 예:
이러한 현상은 우리가 메시지를 보낼 때마다 기본적으로 "대화"라는 개념이 없는 LLM에 해당 메시지 하나만 보내기 때문에 발생합니다.
이 기억상실증을 치료하려면 새 메시지를 보낼 때마다 대화의 모든 메시지를 보내야 합니다.
Chainlit은 지금까지 교환된 모든 메시지를 OpenAI(및 대부분의 다른 공급자)가 기대하는 형식으로 편리하게 제공하는 cl.chat_context.to_openai() 도우미를 제공하여 이를 쉽게 수행합니다.
최신 메시지 앞에 과거 메시지를 추가하도록 handler_message 함수를 업데이트하세요.
poetry run chainlit run app.py --watch
이제 후속 질문을 할 수 있습니다!
파트 1의 처음 몇 단계를 완료한 후, 긴 응답이 필요한 질문을 하면 내용이 표시되기까지 지연이 발생한다는 것을 눈치채셨을 것입니다.
이로 인해 사용자 경험이 저하될 수 있으므로(특히 3부 후반부에서 장기 실행 도구 호출을 추가하기 시작할 때) 이를 수정해 보겠습니다.
이 단계가 끝나면 ChatGPT와 유사하게 봇이 실시간으로 '입력'하는 것을 볼 수 있습니다.
실시간 메시지 업데이트를 받으려면 '스트림'을 사용하도록 구현을 업데이트해야 합니다. 기본적으로 메시지를 받을 때마다 빈 메시지로 즉시 응답하고, LLM으로 스트림을 시작하며, 스트림에서 새로운 응답 청크를 받을 때마다 빈 메시지를 업데이트합니다.
복잡하게 들릴 수도 있지만 의외로 쉽습니다! 다음과 같이 handler_message 함수를 업데이트하세요.
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
?? 지금까지의 전체 코드는 다음과 같습니다.
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
이제 질문을 하면 봇이 실시간으로 '입력'하는 모습을 볼 수 있습니다!
이 시점에서 우리는 ChatGPT의 경량 복제본을 구축했습니다. 멋지지만 우리가 정말로 원하는 것은 특정 작업을 수행하는 데 도움을 주는 보조자입니다. 이 경우 SRE처럼 사고 문제를 해결하는 보조자가 필요합니다.
목표어시스턴트 및 스레드 만들기
대신 애플리케이션이 처음 시작될 때 한 번만 실행되는 또 다른 Chainlit 후크인 on_chat_start를 사용하여 어시스턴트를 설정하겠습니다.
app.py에 다음을 추가하세요.
poetry run chainlit run app.py --watch
참고: handler_message의 메시지 기록에 초기 시스템 유형 메시지를 제공하여 어시스턴트에게 사용자 정의 시스템 프롬프트를 제공하는 것이 기술적으로 가능합니다. 그러나 우리는 가까운 미래에 사용할 수 있는 여러 가지 다른 기능을 잠금 해제하기 때문에 맞춤형 지침을 갖춘 어시스턴트로 리팩터링하고 있습니다.
Assistant를 사용하기 위한 메시지 처리 리팩터링먼저 새로운 Assistant 객체에 대화 중에 발생하는 다양한 이벤트를 처리하는 방법을 알려주는 AssistantEventHandler가 필요합니다.
app.py에 다음을 추가하세요.
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[{"content": message.content, "role": "user"}], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
지금까지의 전체 코드는 다음과 같습니다.
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
이제 어시스턴트와 스레드를 사용하고 있으므로 동작 사용자 정의를 시작할 수 있습니다. 먼저 어시스턴트가 사용 사례에 더 적합한 응답을 제공할 수 있도록 일부 내부 문서에 대한 액세스 권한을 부여하겠습니다.
이 섹션이 끝나면 프롬프트에 응답할 때 파일 모음(예: SRE 런북 및 기타 내부 문서)을 검색하는 기능을 봇에 부여하게 됩니다.
간단함을 위해 이를 벡터 저장소에 업로드되어 어시스턴트에 제공되는 파일로 가득 찬 폴더로 구현하겠습니다.
가장 먼저 해야 할 일은 벡터 스토어를 만들어 어시스턴트에게 제공하는 것입니다.
먼저 다음을 포함하도록 handler_chat_start 함수의 시작 부분을 업데이트하세요.
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
다음으로 client.beta.assistants.update()에 대한 호출을 업데이트하여 어시스턴트에게 벡터 저장소에 대한 액세스 권한을 부여하고 file_search 도구를 활성화합니다.
poetry run chainlit run app.py --watch
마지막으로 어시스턴트가 프롬프트에 응답할 때 참조할 문서를 업로드해야 합니다.
먼저 문서를 저장할 폴더를 만들어야 합니다.
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
다음으로 문서를 수집하여 해당 폴더에 넣습니다. 테스트 목적으로 다음 가짜 문서를 내 폴더에 추가했습니다.
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[{"content": message.content, "role": "user"}], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
마지막으로 이전에 생성한 벡터 저장소에 문서를 자동으로 업로드하도록 handler_chat_start 함수를 업데이트하겠습니다. 벡터 저장소를 생성한 위치 바로 뒤에 다음 코드를 추가합니다.
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[ # Prepend all previous messages to maintain the conversation. *cl.chat_context.to_openai(), {"content": message.content, "role": "user"} ], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
ℹ️ 참고: 현재는 .md 파일만 지원하지만 OpenAI는 다양한 파일 형식을 지원하므로 glob 패턴을 사용 사례에 적합한 대로 자유롭게 업데이트하세요!
이렇게 하면 ./docs 폴더의 모든 파일이 자동으로 업로드되어 벡터 스토어에 추가됩니다.
파일 검색은 특히 대규모 데이터 세트의 경우 시간이 걸릴 수 있습니다. 이러한 경우에는 사용자에게 무슨 일이 일어나고 있는지 알려 사용자가 좌절하지 않도록 할 수 있습니다.
다행히도 Chainlit은 사용자에게 백그라운드에서 무슨 일이 일어나고 있는지 알려주는 데 사용할 수 있는 Step 클래스를 제공하여 이를 쉽게 수행합니다. 이전에 구축한 MessageEventHandler와 함께 Step 클래스를 사용하고 도구가 호출될 때마다 표시기를 추가할 수 있습니다.
MessageEventHandler에 다음을 추가하세요.
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Send an empty initial message that we can update with a streaming # response. message = cl.Message(content="") await message.send() # Stream the response from the LLM stream = await client.chat.completions.create( messages=[ # Prepend all previous messages to maintain the conversation. *cl.chat_context.to_openai(), {"content": message.content, "role": "user"} ], model="gpt-4o", stream=True, ) # Update the existing (initially-empty) message with new content # from each "chunk" in the stream. async for chunk in stream: if token := chunk.choices[0].delta.content: await message.stream_token(token) # Send a final update to let the message know it's complete. await message.update()
이제 자신만의 문서를 업로드했으므로 사용 사례에 더욱 구체적인 질문을 던져 결과를 확인해 보세요!
테스트 사례에서는 고객 데이터베이스의 높은 CPU 사용률에 대한 질문을 받았을 때 런북을 올바르게 참조했습니다.
?? 참고로 지금까지의 전체 코드는 다음과 같습니다.
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
이제 에이전트는 선별된 내부 문서에서 데이터를 검색할 수 있으며, 이는 좋은 문서가 있는 경우 유용합니다. 그러나 사고 관리에서는 경고 검색, 로그 읽기, 지표 해석 등 문서에서 다루지 않은 사항을 조사하는 데 많은 시간을 소비하는 경우가 많습니다.
이러한 목적을 위해 우리는 어시스턴트에게 외부 API를 호출하고 더 광범위하게는 우리가 정의한 기능을 실행할 수 있는 기능을 제공하여 필요에 따라 더 많은 컨텍스트를 수집할 수 있도록 하려고 합니다.
이를 위해 모델의 '함수 호출' 기능을 활용하여 정의한 함수를 실행하겠습니다.
이 섹션이 끝나면 메시지에 응답할 때 정보를 검색하기 위해 외부 도구(가짜 PagerDuty 도구)를 사용할 수 있는 기능을 봇에 부여하게 됩니다.
먼저 app.py에 get_pagerduty_alert_details라는 새 함수를 추가해 보겠습니다.
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
다음으로 LLM에 도구 호출 방법을 알려야 합니다. OpenAI는 JSONSchema 형식의 도구 정의를 기대합니다.
이미 가지고 있는 file_search 도구 뒤에 새 도구 정의를 포함하도록 client.beta.assistants.update()에 대한 호출을 업데이트하세요.
poetry run chainlit run app.py --watch
우리의 MessageEventHandler는 현재 앞뒤로 메시지 이벤트를 처리하지만 호출 도구에는 몇 가지 특별한 처리가 필요합니다.
사용자의 프롬프트에 응답할 때 LLM은 호출해야 하는 도구(있는 경우)를 결정하고 응답 페이로드에 하나 이상의 "도구 호출" 정의를 반환하고 해당 응답에 "조치가 필요함"을 알려줍니다. 실제로 함수를 실행하려면 이러한 "작업 필요" 응답을 처리해야 합니다.
함수 호출을 실행하고 실행 중인 스레드에 결과를 추가하기 위한 새로운 handler_requires_action 메서드와 함께 on_event 메서드를 구현하도록 MessageEventHandler 클래스를 업데이트하면 됩니다.
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
해당되는 경우 귀하가 제공한 도구를 사용해 봐야 한다는 점을 LLM에 상기시키는 것이 도움이 될 수 있습니다. 프롬프트 끝에 다음과 같은 줄을 추가하세요.
해당하는 경우 제공된 도구를 사용하여 사건에 대한 추가 맥락을 수집하세요.
도구를 구성하면 프롬프트에 PagerDuty 링크를 포함할 수 있으며 LLM은 해당 도구를 사용하여 답변하기 전에 컨텍스트를 수집합니다.
?? 전체 코드는 다음과 같습니다.
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
이제 SRE 팀을 위한 유용한 AI 에이전트를 구축할 준비가 모두 완료되었습니다! 이 가이드에서 다룬 내용에 대해 궁금한 점이 있으면 문의해 주세요. 기꺼이 도와드리겠습니다. 그동안 누락된 내용이나 AI Agent와 관련하여 배우고 싶은 내용이 있으면 알려주세요!
Aptible AI를 직접 구축하기보다 직접 Aptible AI를 사용해 보고 싶다면 www.aptible.ai를 방문하여 가입하세요.
위 내용은 가이드: SRE 팀용 AI 에이전트를 구축하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!