AI 봇 - 사용자 지정 도구

:bookmark: 이 가이드는 Discourse AI 플러그인 내에서 사용자 정의 AI 도구를 생성, 구성 및 통합하는 방법을 설명합니다. 이를 통해 관리자는 사용자 정의 JavaScript 함수를 사용하여 봇의 기능을 확장할 수 있습니다.

:person_raising_hand: 필요한 사용자 권한: 관리자

도구(Tools)는 AI 봇이 텍스트 기반 응답을 넘어 특정 작업을 수행하거나 정보를 검색할 때 사용할 수 있는 프로그래밍 가능한 기능입니다. 이러한 도구는 봇이 외부 API와 상호작용하거나 데이터를 조작하거나 추가 기능을 실행하여 기능을 확장할 수 있도록 하는 스크립트 또는 통합입니다.

요약

이 문서에서는 다음 내용을 다룹니다:

  • 새로운 사용자 정의 AI 도구 생성
  • 도구 매개변수 및 스크립트 구성
  • 도구 스크립트에서 사용 가능한 API
  • 사용자 정의 도구를 AI 페르소나와 통합하기
  • 사용자 정의 도구 테스트 및 문제 해결

새로운 사용자 정의 AI 도구 생성

새로운 AI 도구를 생성하려면:

  1. 관리 패널 > 플러그인 > Discourse AI > 도구로 이동하세요.
  2. "새 도구"를 클릭하세요. (옵션을 학습하기 위해 기존 프리셋을 사용할 수 있습니다.)
  3. 다음 필드를 입력하세요:
    • 이름(Name): LLM에게 표시되는 도구의 이름
    • 설명(Description): LLM에게 표시되는 도구의 설명
    • 요약(Summary): 사용자를 돕기 위해 도구가 수행하는 작업의 요약 (세부 정보에 표시됨)
    • 매개변수(Parameters): LLM에게 표시되는 도구가 필요한 입력값 정의
    • 스크립트(Script): 도구를 구동하는 JavaScript 코드
  4. "저장"을 클릭하세요.

도구 스크립트 구성

사용 가능한 API

도구 스크립트에서 다음 API에 접근할 수 있습니다:

  1. HTTP 요청:

    http.get(url, options)
    http.post(url, options)
    http.put(url, options)
    http.patch(url, options)
    http.delete(url, options)
    

    이를 사용하여 외부 서비스와 상호작용합니다. options를 사용하여 HTTP 헤더와 본문을 지정할 수 있습니다:

    http.get(url, { headers: { "Authorization": "Bearer key" } })
    http.post(url, { headers: { "Content-Type": "application/json" }, body: { key: "value" } })
    http.patch(url, { headers: { "Authorization": "Bearer key" }, body: "some body" })
    http.delete(url, { headers: { "Authorization": "Bearer key" } })
    http.put(url, { headers: { "Authorization": "Bearer key" }, body: "some body" })
    

    모든 HTTP 메서드는 { status: number, body: string }을 반환합니다.

  2. LLM(언어 모델) 통합:

    llm.truncate(text, length)
    

    구성된 LLM의 토크나이저를 기반으로 텍스트를 지정된 토큰 길이로 잘라냅니다.

    llm.generate(prompt, options)
    

    구성된 LLM을 사용하여 텍스트를 생성합니다. 프롬프트는 간단한 문자열이거나 { messages: [{ type: "system", content: "..." }, { type: "user", content: "..." }] }와 같은 구조화된 객체일 수 있습니다. 옵션에는 JSON 출력을 요청하고 자동으로 파싱하기 위한 json: true를 포함하여 temperature, top_p, max_tokens, stop_sequences가 있습니다.

  3. 사용자 정의 업로드 통합 (RAG)

    index.search(query, { filenames: ["file.pdf"], limit: 10 })
    

    이 도구에 연결된 인덱싱된 RAG 문서 단편을 검색합니다. 관련성 순서대로 Array<{ fragment: string, metadata: string | null }>를 반환합니다. 기본 제한은 10이며, 최대 200입니다.

    index.getFile(filename)
    

    정확한 파일명을 사용하여 업로드된 RAG 파일의 전체 내용을 가져옵니다. 전체 텍스트를 반환하거나, 찾지 못하면 null을 반환합니다.

  4. 업로드 지원

    upload.create(filename, base_64_content)
    

    새로운 업로드를 생성합니다. { id: number, url: string, short_url: string }을 반환합니다.

    upload.getUrl(shortUrl)
    

    짧은 URL(예: upload://12345)을 입력하면 전체 CDN 친화적 URL을 반환합니다.

    upload.getBase64(uploadIdOrShortUrl, maxPixels)
    

    기존 업로드의 base64 인코딩된 내용을 가져옵니다. 업로드 ID(숫자) 또는 짧은 URL(문자열)을 허용합니다. 이미지 자동 리사이징을 위한 선택적 maxPixels 매개변수(기본값: 10,000,000)가 있습니다.

  5. 실행 체인 제어

    chain.setCustomRaw(raw)
    

    봇의 게시글 최종 원본(raw) 내용을 설정하고 도구 실행 체인을 중단합니다. 전체 응답을 직접 생성하는 도구(예: 이미지 생성 도구)에 유용합니다.

  6. 비밀 정보(Secrets) 관리

    secrets.get(alias)
    

    주어진 별칭에 바인딩된 자격 증명 값을 반환합니다. 별칭은 도구의 비밀 계약 구성에서 정의되며 관리 패널의 AI Secrets에 바인딩됩니다. 별칭이 선언되지 않았거나, 바인딩되지 않았거나, 자격 증명이 누락된 경우 오류를 발생시킵니다.

    const apiKey = secrets.get("my_api_key");
    
  7. Discourse 통합

    도구는 Discourse 데이터와 직접 상호작용할 수 있습니다:

    discourse.baseUrl              // 사이트의 기본 URL
    discourse.search(params)       // Discourse 검색 수행
    discourse.getPost(post_id)     // 게시글 세부 정보 가져오기 (원본 내용 포함)
    discourse.getTopic(topic_id)   // 주제 세부 정보 가져오기 (태그, 카테고리 등)
    discourse.getUser(id_or_username)  // 사용자 세부 정보 가져오기
    discourse.createTopic(params)  // 새 주제 생성
    discourse.createPost(params)   // 새 게시글/답글 생성
    discourse.editPost(post_id, raw, options)    // 게시글 내용 편집
    discourse.editTopic(topic_id, updates, options) // 주제 속성 편집 (태그, 카테고리, 가시성)
    discourse.createChatMessage(params) // 채팅 메시지 보내기
    discourse.createStagedUser(params)  // 스테이징된 사용자 생성
    discourse.getAgent(name)       // 다른 AI 에이전트 가져오기 (respondTo 메서드 포함)
    discourse.updateAgent(name, updates) // AI 에이전트 구성 업데이트
    discourse.getCustomField(type, id, key)      // 게시글/주제/사용자의 사용자 정의 필드 읽기
    discourse.setCustomField(type, id, key, value) // 게시글/주제/사용자의 사용자 정의 필드 설정
    
  8. 컨텍스트 객체

    context 객체는 도구가 실행되는 위치에 대한 정보를 제공합니다:

    • 봇 대화 컨텍스트: context.post_id, context.topic_id, context.private_message, context.participants, context.username, context.user_id
    • 채팅 컨텍스트: context.message_id, context.channel_id, context.username
    • 자동화 컨텍스트: context.post_id, context.topic_id, context.username, context.user_id, context.feature_name, context.feature_context
    • 공통 속성: context.site_url, context.site_title, context.site_description

필수 함수

스크립트는 다음을 구현해야 합니다:

  • invoke(params): 도구가 호출될 때 실행되는 주요 함수

선택적으로 다음을 구현할 수 있습니다:

  • details(): 도구 실행을 설명하는 문자열(기본 HTML 포함 가능)을 반환하며, 채팅 인터페이스에 표시됩니다.
  • customSystemMessage(): 프롬프트 조립 시(도구 호출 시에는 아님) 호출됩니다. 시스템 프롬프트에 추가될 문자열을 반환하거나, 건너뛰려면 null/undefined를 반환합니다. context, discourse, index 객체에 접근할 수 있습니다.

예제 스크립트:

function invoke(params) {
  let result = http.get("https://api.example.com/data?query=" + params.query);
  return JSON.parse(result.body);
}

function details() {
  return "Fetched data from Example API";
}

제한 사항 및 보안

  • 실행 시간 초과: 스크립트 처리 시간의 기본 시간 초과는 2000ms입니다. 외부 HTTP 요청(http.*) 및 LLM 호출(llm.generate) 동안 타이머가 일시 정지되므로, 스크립트 자체의 처리 시간만 계산됩니다.
  • 메모리: 최대 10MB V8 힙 제한
  • HTTP 요청: 도구 실행당 최대 20개 요청
  • 샌드박스 환경: 스크립트는 제한된 V8 JavaScript 환경(MiniRacer를 통해)에서 실행됩니다. 브라우저 전역 변수, 호스트 파일 시스템 또는 서버 측 라이브러리에 대한 접근이 없습니다. 네트워크 요청은 Discourse 백엔드를 통해 프록시됩니다.

도구 테스트

LLM이 제공받을 결과가 기대와 일치하는지 확인하기 위해 만든 도구를 테스트해야 합니다.

도구를 AI 페르소나와 통합하기

사용자 정의 도구를 AI 페르소나에 추가하려면:

  1. 관리 패널 > 플러그인 > Discourse AI > 페르소나로 이동하세요.
  2. 기존 페르소나를 편집하거나 새 페르소나를 생성하세요.
  3. “도구” 섹션에서 내장 도구와 함께 사용자 정의 도구가 목록에 표시됩니다.
  4. 페르소나에 추가할 사용자 정의 도구를 선택하세요.

실제 사용 중인 사용자 정의 도구

LLM에 사용자 정의 도구를 제공하면 대화의 질을 높이기 위해 이를 사용할 수 있습니다.

문제 해결

도구가 기대대로 작동하지 않는 경우:

  1. 입력값에 대해 기대하는 대로 작동하는지 확인하기 위해 테스트 인터페이스를 사용하세요.
  2. 그룹이 ai_bot_debugging_allowed_groups에 있는지 확인하세요. 이 그룹의 멤버는 봇 전사(transcripts)에 대한 전체 접근 권한을 가지며,在那里 AI 로그를 볼 수 있습니다.
  3. 예상치 못한 일이 발생하면 https://SITENAME/logs를 방문하여 오류를 확인하세요.

추가 리소스

14개의 좋아요

저는 Discourse에서 AI 페르소나를 위한 도구를 구축하기 시작한 지 얼마 되지 않았습니다. 이 분야에 정말 집중할 수 있도록 하기 위해서이기도 하고, 유용하고 공개된 API가 정말 많기 때문에 이 작업이 매우 유용할 것 같아서입니다!

예를 들어, 다음과 같은 결과를 얻고 있습니다:

포커 전략을 통한 의사결정 이해 AI

maiki:

Breath of the Wild에 대한 정보 카드를 만들어 줘.

gpt-4o:

다음은 "젤다의 전설: 브레스 오브 더 와일드"에 대한 정보 카드입니다:


제목: 젤다의 전설: 브레스 오브 더 와일드
개발사: 닌텐도
출판사: 닌텐도
출시일: 2017년 3월 3일
플랫폼: 닌텐도 스위치, Wii U
장르: 액션 어드벤처
모드: 싱글플레이어

줄거리:
방대한 오픈 월드를 배경으로, 플레이어는 깊은 잠에서 깨어난 링크를 조작하여 재앙 가논을 물리치고 하이랄 왕국을 구해야 합니다. 이 게임은 몰입감 있는 환경을 칭송받으며, 플레이어가 세계와 그 시스템과 자유롭게 상호작용하고 탐험할 수 있게 해줍니다.

수상 내역:
이 게임은 혁신적인 디자인, 방대한 세계, 그리고 매혹적인 게임플레이로 인해 다수의 상을 수상했으며, 그중에서도 여러 해의 게임(Game of the Year) 타이틀을 포함합니다.

추가 정보: Wikidata 항목


"브레스 오브 더 와일드"는 오픈 월드 게임을 재정의하고 탐험과 발견을 장려하는 매혹적인 경험을 제공한 것으로 유명합니다.

maiki:

동물의 숲: 뉴 호라이즌스에 대해서도 같은 방식으로 해줘.

gpt-4o:

다음은 "동물의 숲: 뉴 호라이즌스"에 대한 정보 카드입니다:


제목: 동물의 숲: 뉴 호라이즌스
개발사: 닌텐도
출판사: 닌텐도
출시일: 2020년 3월 20일
플랫폼: 닌텐도 스위치
장르: 소셜 시뮬레이션
모드: 싱글플레이어, 멀티플레이어

줄거리:
이 매력적인 소셜 시뮬레이션 게임에서 플레이어는 톰 노크에게 패키지 구매 후 무인도로 이사 오는 맞춤형 캐릭터의 역할을 맡습니다. 게임은 실시간 탐험, 자원 수집, 제작 및 커스터마이징을 허용하여 공동체적이고 이완적인 게임플레이 경험을 조성합니다.

수상 내역:
이 게임은 창의적인 자유도와 출시 시기에 대해 찬사를 받았으며, 전 세계적 팬데믹 기간 동안 소셜 게이밍에 기여한 점으로 인해 해의 게임 상을 비롯한 여러 상을 수상했습니다.

추가 정보: Wikidata 항목


"동물의 숲: 뉴 호라이즌스"는 어려운 시기에 스트레스 해소에 도움이 되는 몰입감 있는 소셜 기능과 게임플레이로 문화적 현상이 되었습니다.

maiki:

A Long Way from Chicago

gpt-4o:

다음은 책 "A Long Way from Chicago"에 대한 정보 카드입니다:


제목: A Long Way from Chicago
저자: Richard Peck
출판 연도: 1998
장르: 역사 소설, 청소년 소설
ISBN: 978-0141303529

줄거리:
뉴베리 온러(Honor) 수상작인 이 소설은 1920년대 후반부터 1930년대까지 조이(Joey)와 그의 여동생 메리 앨리스(Mary Alice)가 시카고에서 시골 일리노이 주로 거대하고 생동감 넘치는 할머니 도들(Grandma Dowdel)을 방문하기 위해 매년 여름 여행을 하는 과정을 연작 단편 형태로 다룹니다. 각 장은 대공황이라는 배경 속에서 삶의 교훈을 전하는 유머러스하고도 감동적인 에피소드를 제시합니다.

수상 내역:
이 책은 1999년 뉴베리 온러를 수상했으며, 20세기 초 시골 미국 생활을 묘사한 유머와 깊이로 인해 찬사를 받고 있습니다.

추가 정보: Wikidata 항목


이 책은 가족의 유대와 단순했던 시대의 본질을 포착한 향수 어린 그리고 따뜻한 스토리텔링으로 평가받고 있습니다.

maiki:

Thinking in Bets

gpt-4o:

이전에 "Thinking in Bets"의 Wikidata 항목을 찾았지만, 현재 Wikidata에서 더 구체적인 세부 정보를 직접 가져오지 못하고 있습니다. 그러나 이용 가능한 정보에 기반한 간략한 카드는 다음과 같습니다:


제목: Thinking in Bets: Making Smarter Decisions When You Don’t Have All the Facts
저자: Annie Duke
출판 연도: 2018
장르: 논픽션, 의사결정, 심리학
ISBN: 978-0735216358

줄거리:
이 책은 포커에서 얻은 통찰력을 활용하여 불확실성 하의 의사결정을 이해하는 데 도움을 줍니다. 전문 포커 플레이어이자 인지 심리학자인 애니 듀크(Annie Duke)는 더 현명한 의사결정을 내리고, 결과를 평가하며, 확률적 사고 방식을 채택하기 위한 프레임워크를 제시합니다.

추가 정보: Wikidata 항목


상세한 통찰력을 얻으려면 출판된 책에 관한 추가 자료나 데이터베이스를 확인하는 것을 고려해 볼 수 있습니다.


자, 그 부분은 괜찮은데, 이 설명을 발견했습니다…

…그리고 궁금해집니다: 효율적인 사용을 위해 프롬프트를 작성할 때 해당 도구를 직접 참조해야 할까요?

저의 프롬프트 작성 일반적 접근 방식은 시간이 지남에 따라 정교하게 다듬어 나간 후, AI 도구에서 채택하길 원하는 행동 패턴에 고정하는 것입니다. 그러나 예를 들어 Wikidata 엔티티를 조회할 때와 특정 엔티티의 모든 클레임(claims)을 나열할 때(두 가지 다른 API)와 같은 구체적인 지시사항을 추가할 수 있다면, 제가 의도한 대로 워크플로 전체가 흐르도록 정교하게 다듬을 수 있을 것 같습니다… :star_struck:

4개의 좋아요

실제로 도구에 대해 명확히 설명하고 시스템 프롬프트에 예시를 제공하는 것이 도움이 됩니다.

2개의 좋아요

사용자 정의 도구에서 관리자 설정을 통해 API 키와 OpenAI 프로젝트를 삽입할 수 있나요?

1개의 좋아요

사용자 정의 도구에서 REST 호출을 수행하고 모든 헤더를 지정할 수 있습니다.

2개의 좋아요

아까야 깨달았네 ㅋㅋ… 실수해서 미안

1개의 좋아요

페르소나에 몇 가지 문서를 업로드했고, 임베딩이 생성되어 이제 이를 통해 의미론적 검색(semantic search)을 수행할 수 있습니다. 하지만 일부 경우에는 의미론적 검색이 이상적이지 않아, 이를 개선하고 하이브리드 검색을 구현하고 싶습니다. 예를 들어, 기존 방식을 유지하면서 키워드 검색을 추가하는 방식입니다. 현재 이 작업을 하려면 커스텀 도구를 작성해야 하는 것이 맞나요?
문서를 주제로 게시하면 네이티브 Discourse 검색과 함께 바로 작동할 수 있다는 점은 알고 있습니다. 하지만 현재로서는 그 옵션이 없습니다.

커스텀 도구를 추가할 때 배열 매개변수를 사용하면 도구 스키마 오류가 발생합니다. 대화 시작 시 오류가 발생하며, 내용은 다음과 같습니다:

{
“error”: {
“code”: 400,
“message”: “* GenerateContentRequest.tools[0].function_declarations[3].parameters.properties[properties].items: missing field.\n”,
“status”: “INVALID_ARGUMENT”
}
}

시도해 본 내용:

  • properties라는 이름의 배열 타입 매개변수를 가진 커스텀 도구를 생성했습니다.
  • 매개변수 목록 UI에서는 items를 지정할 수 없습니다.
  • properties에 대해 items: { type: “string” }가 포함된 전체 도구 JSON을 내보낸 후 가져왔습니다.
  • 가져온 후, 해당 도구가 페르소나에 활성화되는 즉시 오류가 계속 발생합니다. 도구를 제거하면 봇은 정상적으로 작동합니다.

기대하는 동작:

매개변수 목록 UI에서 배열 항목 타입을 정의할 수 있어야 하거나, 가져오기 시 items가 반영되어 스키마가 유효하게 검증되어야 합니다.

혹시 이 문제를 경험하신 분이 계신가요? 알려진 제한 사항이 있거나, 배열 매개변수를 정의하기 위한 필수 UI 경로가 있는 건가요?

1개의 좋아요