답변에서 연속 사용할 수 있는 최대 도구 수

안녕하세요 :wave:

웹숍에서 정보를 수집하기 위한 커스텀 도구를 두 개 만들었습니다. 수집하는 정보는 웹숍 이름, 제품 링크, 가격 및 재고 정보입니다. 이 정보들을 수집한 후 결과를 표로 나열합니다.

  1. 이를 위해 내장된 Google 검색 도구와 유사하지만, 결과 수를 제한할 수 있고 이 도구에서만 사용되는 별도 프로그래밍 가능한 검색을 만들 수 있는 커스텀 Google 검색 도구를 만들었습니다. 이는 결과가 관련 있는 웹숍만 포함되도록 하는 것이 필요했기 때문에 필요했습니다.

  2. 두 번째 커스텀 도구는 Discourse 웹 브라우징 도구와 유사하지만, 웹숍에 맞게 특별히 최적화했습니다. 먼저 <script type="application/ld+json"> 내에 위치하는 JSON 기반 schema.org 형식의 "Offer 또는 Product"를 검색하고, 그 안에서 필요한 데이터(가격, 재고 정보)를 검색합니다. 결과가 없으면 itemtype 기반으로 동일한 데이터를 검색을 시작합니다. 이것으로도 결과가 없으면, 웹 브라우저 도구가 기본적으로 수행하는 동작인 페이지의 주요 내용을 검토하여 필요한 정보를 검색하는 과정으로 넘어갑니다. 이 도구에 내장된 또 다른 중요한 기능은 토큰 제한입니다. 브라우징 중에 최대 토큰 제한을 설정할 수 있으며, 현재 3000으로 설정되어 있습니다.

하지만 이 주제를 작성한 이유는 도구 사용에 어떤 제한이 있는지 궁금해서입니다. 5회 도구 사용 후 프로세스가 중단되는 것을 발견했습니다. 이것이 제가 커스텀 검색에서 결과 제한을 만든 다른 이유이기도 합니다. 브라우저 도구가 성공적으로 실행되도록 4로 설정했습니다. 5로 설정하면 브라우저 도구가 5번째 도구 사용 시 실패합니다. :arrow_down_small:

예를 들어: 답변에서 Google 검색 1회와 웹 브라우저 5회를 연속으로 수행한 후 /logs에서 경고를 받습니다.

Message (3 copies reported)

DiscourseAi: Tool not found: tool-name

Backtrace

/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:130:in `block in warn'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:130:in `warn'
/var/www/discourse/plugins/discourse-ai/lib/ai_bot/bot.rb:158:in `block in reply'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/base.rb:190:in `block (5 levels) in perform_completion!'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/base.rb:190:in `each'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/base.rb:190:in `block (4 levels) in perform_completion!'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/base.rb:178:in `each'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/base.rb:178:in `block (3 levels) in perform_completion!'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-protocol-0.2.2/lib/net/protocol.rb:535:in `call_block'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-protocol-0.2.2/lib/net/protocol.rb:526:in `<<'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-protocol-0.2.2/lib/net/protocol.rb:162:in `read'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http/response.rb:631:in `read_chunked'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http/response.rb:595:in `block in read_body_0'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http/response.rb:588:in `inflater'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http/response.rb:593:in `read_body_0'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http/response.rb:363:in `read_body'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/base.rb:173:in `block (2 levels) in perform_completion!'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http.rb:2433:in `block in transport_request'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http/response.rb:320:in `reading_body'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http.rb:2430:in `transport_request'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http.rb:2384:in `request'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/patches/net_patches.rb:19:in `block in request_with_mini_profiler'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/mini_profiler/profiling_methods.rb:50:in `step'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/patches/net_patches.rb:18:in `request_with_mini_profiler'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/base.rb:116:in `block in perform_completion!'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http.rb:1632:in `start'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-http-0.6.0/lib/net/http.rb:1070:in `start'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/base.rb:99:in `perform_completion!'
/var/www/discourse/plugins/discourse-ai/lib/completions/endpoints/open_ai.rb:40:in `perform_completion!'
/var/www/discourse/plugins/discourse-ai/lib/completions/llm.rb:279:in `generate'
/var/www/discourse/plugins/discourse-ai/lib/ai_bot/bot.rb:115:in `reply'
/var/www/discourse/plugins/discourse-ai/lib/ai_bot/playground.rb:477:in `reply_to'
/var/www/discourse/plugins/discourse-ai/app/jobs/regular/create_ai_reply.rb:18:in `execute'
/var/www/discourse/app/jobs/base.rb:316:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
/var/www/discourse/app/jobs/base.rb:303:in `block in perform'
/var/www/discourse/app/jobs/base.rb:299:in `each'
/var/www/discourse/app/jobs/base.rb:299:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:202:in `execute_job'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:170:in `block (2 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:177:in `block in invoke'
/var/www/discourse/lib/sidekiq/pausable.rb:132:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:179:in `block in invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:182:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:169:in `block in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_retry.rb:113:in `local'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq.rb:44:in `block in <module:Sidekiq>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:263:in `stats'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_logger.rb:13:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_retry.rb:80:in `global'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:124:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_logger.rb:39:in `prepare'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:123:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:168:in `process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:78:in `process_one'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:68:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/component.rb:8:in `watchdog'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/component.rb:17:in `block in safe_thread'

정확한 원인을 알지 못하지만, 아마도 제한 때문일 것입니다. 그렇다면 답변 내에서 도구의 연속 사용 횟수 제한을 설정할 수 있도록 페르소나 또는 커스텀 도구에 설정을 추가할 수 있는 가능성이 있을까요?

수정: 이것이 아마도 그 제한일 것 같은 것을 찾았습니다. 위에서 언급한 설정으로 오버라이드할 수 있는 기능이 있다면 좋겠습니다.

감사합니다 :slightly_smiling_face:

Discourse 웹 브라우징 도구가 무엇이며, 어디서 찾을 수 있거나 구할 수 있나요?!

AI가 사용할 수 있는 도구를 가리키는 것 같습니다. 따라서 AI 페르소나를 편집할 때 이를 활성화할 수 있습니다.

아직 이 문제를 겪어본 적은 없지만, 만약 정말로 하드코딩된 제한이라면 이를 오버라이드할 수 있다면 정말 좋겠네요!

플러그인이 기본적으로 제공하는 페르소나 중에는 “Researcher”가 있습니다. 작동 방식을 확인해 보실 수 있습니다 :slight_smile:

어떤 LLM을 사용하시나요?

LLM이 단일 응답에서 5개 이상의 함수 호출을 반환하나요? 즉, 병렬 함수 호출을 수행하는 건가요?

해당 LLM 응답을 공유해 주실 수 있을까요?

GPT4o, GPT4o Mini, Gemini Flash 2를 사용하고 있습니다. 솔직히 많은 LLM을 시도해 봤습니다. :grin:

네, Forced Tools를 설정하고 Persona에 시스템 메시지를 추가하여 항목을 확인하도록 했을 때 발생합니다. 예를 들어 "구글 검색에서 찾은 모든 웹사이트를 방문하라"와 같은 경우입니다. 제 사용 사례에 있어서는 이것이 필요합니다.

공개하기에 부적절한 내용일 수 있으므로 개인 메시지로 예를 보내드리겠습니다. 해당 예시에서는 봇이 Gemini Flash 2를 사용하여 Google Search와 Web Browser를 활용하고 있습니다.

여기서 버그가 무엇인지 파악하는 것 같습니다… 일반적으로 max_tools는 도구 호출이 포함된 긴 체인을 방지하기 위해 존재했지만, 아마도 두 가지 다른 종류의 'max’가 있을 것입니다:

  • 응답하기 전에 LLM과 왕복하는 최대 횟수
  • 도구 호출의 최대 횟수 (훨씬 더 높을 수 있음)
  • 도구가 컨텍스트에 삽입할 수 있는 최대 양 (예: 3회의 도구 호출로 컨텍스트가 가득 차고, 그 후 2회의 추가 호출로 인해 모델이 이전 2회의 도구 응답을 잊어버리는 경우)

이 문제에 대해 생각해 보겠습니다. 해결 가능합니다.

최근에 숫자를 크게 올렸는데, 지금은 어때 보여?