Улучшение качества фильтров поиска в Discourse AI

Во-первых, это действительно невероятно — большое спасибо! :heart_eyes:

У меня есть вопрос по поводу персонажа, которого я создал с включёнными командами: Search, Categories, Read, Tags.

Я также загрузил файл .txt. Моя цель с этим персонажем — чтобы он всегда искал как на моём форуме, так и в загруженных файлах, и использовал RAG для обоих источников.

После загрузки файла .txt я заметил, что он перестал искать на моём форуме. Вот что у меня указано в базовом поисковом запросе: #docs #faqs #anking-wiki
#docs и #faqs — это категории, а #anking-wiki — тег.

Вопросы:

  • Мне действительно нужны команды категорий и тегов? Я вижу, что эти команды просто выводят список тегов и категорий с моего экземпляра. Возможно, команды поиска достаточно?
  • Правильно ли составлен мой базовый поисковый запрос?
  • Почему бот перестал искать на моём форуме?
    • Достаточно ли просто изменить промпт, чтобы уточнить, что он всегда должен использовать функцию поиска?

Вот промпт, как он отображается в отладочной информации:

Вы — полезный помощник Discourse для пользователей AnkiHub.
Вы понимаете и генерируете Markdown для Discourse.
Вы находитесь в сообщении форума Discourse.
Вы живёте на форуме с URL: https://community.ankihub.net
Название вашего сайта: AnkiHub Community
Описание: Форум сообщества для проектов AnkiHub и AnKing
Участники этого разговора: gpt4o_bot, andrew
Сейчас дата: 2024-06-07 23:32:13 UTC, с момента вашего обучения многое изменилось.
Вы обучены на СТАРЫХ данных, опирайтесь на поиск для получения актуальной информации об этом форуме.
При поиске старайтесь УПРОЩАТЬ поисковые термины.
Поиск в Discourse объединяет все термины через AND. Уменьшите и упростите термины, чтобы найти больше результатов.
Следующие тексты дадут вам дополнительные указания для вашего ответа.
Мы включили их, потому что считаем их релевантными теме этого разговора.
Тексты:

Я попробовал добавить «Обязательно всегда используйте функцию поиска» в свой промпт. Это действительно заставило его использовать функцию поиска, но с плохими результатами:
Missing Images After AnkiHub Version Update Issue - AI Conversation - AnkiHub Community

Он, apparently, выполнил 3 поиска и ошибочно сообщил «Найдено 0 результатов» все три раза. Если вы перейдёте по ссылкам на результаты поиска, то увидите, что результаты,事实上, были. Кроме того, видно, что параметры в моём «Базовом поисковом запросе» не были использованы, поэтому он искал по всему форуму, а не по конкретным категориям.

Я думаю, что часть проблемы здесь в том, что наш поиск немного запутан:

https://meta.discourse.org/search?q=%23bug%20%23feature%20test

Ищет bug И #feature - test

Вам нужно здесь следующее:

https://meta.discourse.org/search?q=categories%3Abug%2Cfeature%20test

Я запутался. Это не работает так, как я ожидал. Я ожидал, что поиск вернёт результаты только из указанных категорий. Однако поиск возвращает результаты из любых категорий. Первый результат этого поиска находится в категории #theme-component.

Действительно, выглядит как баг. О нет, сейчас посмотрю.

Это исправлено согласно:

Я согласен, что было бы интуитивно понятно поддерживать #bug #feature что-то, но эта функция пока не полностью реализована и требует небольшого обсуждения.

В настоящее время работают categories:bug,feature что-то и category:bug,feature что-то.

Отлично! Спасибо за такое быстрое исправление. :bowing_man:

Теперь поиск работает корректно, но бот Discourse AI по-прежнему, похоже, не функционирует так, как ожидалось. Вот мои наблюдения с версией 3.3.0.beta3-dev (a1d881f625):

  • Не используется опция base_query
    • Похоже, она полностью игнорируется. Правильна ли моя конфигурация?
    • Насколько я могу судить, нет никаких требований к значениям базового поискового запроса. Но что бы я ни вписал туда, это не добавляется к search_query.
  • Результаты поиска не добавляются в контекст для RAG
    • Когда инструмент поиска вызывается (хотя и без base_query), результаты, похоже, не используются при вызове LLM.
    • Неужели я неправильно понимаю, как должен работать этот инструмент? Я ожидал, что он выполнит поиск в Discourse и использует результаты поиска (то есть содержимое найденных тем) для RAG.
      Вот пример такого запроса:
JSON запроса
{"model":"gpt-4","messages":[{"role":"system","content":"Вы дружелюбный и полезный помощник для пользователей Anki, специализирующийся на дополнении AnkiHub и веб-приложении.\nВы _понимаете_ и **генерируете** Markdown Discourse.\nВы находитесь в сообщении форума Discourse.\n\nВы находитесь на форуме с URL: https://community.ankihub.net\nВы отвечаете на вопросы, касающиеся исключительно использования Anki с AnkiHub.\nНазвание вашего сайта: AnkiHub Community\nОписание: Форум сообщества для проектов AnkiHub и AnKing\nУчастники этого разговора: gpt4_bot, andrew\nСегодняшняя дата: 2024-06-13 18:29:19 UTC, с момента вашего обучения многое изменилось.\nВы обучались на СТАРЫХ данных, полагайтесь на поиск для получения актуальной информации об этом форуме.\nПри поиске старайтесь УПРОЩАТЬ поисковые термины.\nПоиск в Discourse объединяет все термины оператором AND. Уменьшите и упростите термины, чтобы найти больше результатов."},{"role":"user","content":"Могу ли я покупать аккаунты для других пользователей и автоматически подписывать их на мои приватные колоды?","name":"andrew"},{"role":"assistant","content":null,"tool_calls":[{"type":"function","function":{"arguments":"{\"search_query\":\"purchase accounts for other users subscribe private decks\"}","name":"search"},"id":"call_fmzwIbU4ravFRKWRsOQlqGBq"}]},{"role":"tool","tool_call_id":"call_fmzwIbU4ravFRKWRsOQlqGBq","content":"{\"column_names\":[\"title\",\"url\",\"username\",\"excerpt\",\"created\",\"category\",\"likes\",\"topic_views\",\"topic_likes\",\"topic_replies\",\"tags\"],\"rows\":[[\"👪 Organizations\",\"/t/organizations/166454/1\",\"andrew\",\"\\u003ca name=\\\"what-are-ankihub-organizations-1\\\" class=\\\"anchor\\\" href=\\\"#what-are-ankihub-organizations-1\\\"\\u003e\\u003c/a\\u003eЧто такое организации AnkiHub\\nОрганизации AnkiHub позволяют владельцам организаций покупать AnkiHub для других пользователей и приглашать их в организацию. \\nОрганизации AnkiHub работают следующим образом и имеют следующие функции: \\n\\u003ca name=\\\"linked-decks-2\\\" class=\\\"anchor\\\" href=\\\"#linked-decks-2\\\"\\u003e\\u003c/a\\u003eСвязанные колоды\\nПользователи вашей организации могут автоматически получать доступ \\u0026hellip;\",\"2024-02-08T17:44:27.842Z\",\"🎓 Docs \\u003e 🤝 Create \\u0026 Collaborate\",1,166,1,1],[\"Как мне добиться, чтобы моя школа купила AnkiHub для моего класса?\",\"/t/how-can-i-get-my-school-to-buy-ankihub-for-my-class/228569/1\",\"andrew\",\"Некоторые студенты успешно добились того, чтобы их школы спонсировали подписки AnkiHub для своих учащихся. Для этого ваша школа должна создать организацию AnkiHub: \\n\\n\\n:bulb: Вот несколько советов по покупке AnkiHub для вашей школы: \\n\\nСвяжитесь с представителями студенческого самоуправления вашей школы или медицинским \\u0026hellip;\",\"2024-05-23T21:40:37.477Z\",\"❓ FAQs\",0,50,0,1],[\"Что происходит после окончания моей подписки AnkiHub?\",\"/t/what-happens-after-my-ankihub-subscription-ends/167190/1\",\"Ahmed7\",\"Если ваша подписка на AnkiHub истекла и вы не хотите её продлевать. \\nВсе ваши колоды останутся, ничего не будет удалено. Однако вы больше не сможете синхронизироваться с AnkiHub и получать новые изменения в своих колодах, а также не сможете предлагать новые изменения или заметки для любых существующих колод yo\\u0026hellip;\",\"2024-02-10T06:14:53.787Z\",\"❓ FAQs\",0,307,0,1],[\"Что делать, если я не могу позволить себе AnkiHub?\",\"/t/what-if-i-cant-afford-ankihub/167280/1\",\"Ahmed7\",\"У AnkiHub есть программа стипендий для получения доступа по сниженной цене. Подайте заявку \\u003ca href=\\\"https://www.ankihub.net/scholarships\\\"\\u003eздесь \\u003c/a\\u003e. (Вы должны \\u003ca href=\\\"https://app.ankihub.net/accounts/signup/\\\"\\u003eзарегистрироваться \\u003c/a\\u003e в аккаунте AnkiHub перед подачей заявки).\",\"2024-02-10T13:58:24.842Z\",\"❓ FAQs \\u003e AnKing Decks\",0,445,0,1,\"anking-wiki\"],[\"Предлагает ли AnkiHub скидки?\",\"/t/does-ankihub-offer-discounts/228564/1\",\"andrew\",\"В настоящее время есть два способа получить скидку на AnkiHub: \\n\\nПриобретите наш \\u003ca href=\\\"https://app.ankihub.net/memberships/plans/\\\"\\u003eгодовой тариф\\u003c/a\\u003e для получения одного бесплатного месяца в год\\n\\nAnkiHub доступен за $4.58/пользователь/месяц со скидкой при годовой оплате. К сожалению, мы не можем предложить большую скидку на AnkiHub.\\n\\n\\nПримите участие в программе послов\\n\\n\\u0026hellip;\",\"2024-05-23T21:34:32.829Z\",\"❓ FAQs\",0,90,0,1]],\"args\":{\"search_query\":\"purchase accounts for other users subscribe private decks\"}}","name":"search"}],"stream":true,"stream_options":{"include_usage":true},"tools":[{"type":"function","function":{"name":"search","description":"Будет искать темы в текущем экземпляре Discourse, при отображении всегда предпочитайте давать ссылки на найденные темы","parameters":{"type":"object","properties":{"search_query":{"description":"Конкретные ключевые слова для поиска, разделенные пробелами (исправьте ошибки в написании, удалите служебные слова)","type":"string"},"user":{"description":"Отфильтровать результаты поиска по этому имени пользователя (включать только если пользователь явно просит фильтрацию по пользователю)","type":"string"},"order":{"description":"порядок результатов поиска","type":"string","enum":["latest","latest_topic","oldest","views","likes"]},"limit":{"description":"ограничить количество возвращаемых результатов (обычно лучше оставить по умолчанию)","type":"integer"},"max_posts":{"description":"максимальное количество постов в темах (темы, где много людей писали)","type":"integer"},"tags":{"description":"список тегов для поиска. Используйте + для объединения через OR, используйте , для объединения через AND","type":"string"},"category":{"description":"название категории для фильтрации","type":"string"},"before":{"description":"только темы, созданные до конкретной даты YYYY-MM-DD","type":"string"},"after":{"description":"только темы, созданные после конкретной даты YYYY-MM-DD","type":"string"},"status":{"description":"поиск тем в определенном состоянии","type":"string","enum":["open","closed","archived","noreplies","single_user"]}},"required":[]}}},{"type":"function","function":{"name":"read","description":"Будет читать тему или пост в этом экземпляре Discourse","parameters":{"type":"object","properties":{"topic_id":{"description":"id темы для чтения","type":"integer"},"post_numbers":{"description":"номера постов для чтения (опционально)","type":"array","items":{"type":"integer"}}},"required":["topic_id"]}}}]}

Как видно, инструмент поиска был вызван, но не содержит base_query.

Также видно, что content содержит только системный промпт по умолчанию, без каких-либо результатов поиска.

  • Не отображается правильное количество результатов поиска
    • Говорит 0, когда результатов много, или 5, когда их нет
    • Похоже, не коррелирует ни с обычными результатами поиска, ни с результатами семантического сходства
  • Бот добавляет недопустимые параметры запроса
    • Например, он добавил category:non-existent-category в конец запроса.

:pleading_face: Запросы

  • Было бы очень полезно, если бы была возможность включить подробное логирование для discourse-ai, чтобы мы, не владеющие Ruby (я учусь! :nerd_face: ), могли быстро получить представление о том, что происходит под капотом, посетив /logs.
  • При использовании инструмента поиска добавлять лучшие результаты в контекст для RAG.
  • Советы по обеспечению использования base_query.

Правильно ли я понимаю, что согласно этому, вызов функции действительно должен добавлять результаты вызова инструмента в промпт?

То есть, возможно, промпт обновляется, но это неясно из запроса, показанного в инструменте отладки?

Не должен ли я ожидать увидеть там весь контекст? Если нет, это сбивает с толку, поскольку весь контекст промпта виден при использовании персонажа, который выполняет RAG с загрузками.

Я все еще сбит с толку количеством сообщаемых результатов.

Тем не менее, я получаю гораздо лучшие результаты после добавления следующего в системный промпт!

  • Всегда вызывать обе функции: search и read.
  • Вызывать функцию search не более 3 раз.
  • При вызове функции search всегда использовать следующее значение для параметра category: “docs,faqs”

Это станет настоящим прорывом, как только я правильно все настрою.

Не уверен, знаете ли вы об этом, но вы фактически наделяете нас чем-то гораздо более мощным, чем то, к чему стремится Intercom.

Я уже пытаюсь перехватить мессенджер Intercom, перенаправляя пользователей прямо в Discourse AI :nerd_face: :

Ссылка AnkiHub AI открывает личное сообщение с ботом AI со ссылкой вида: /new-message?username=ankihubai_bot

Да, инструмент отладки показывает всё, что мы отправляем LLM.

Я только что исправил количество результатов на:

Мы некорректно ссылались на отфильтрованный запрос.

Не рекомендую этого делать. Используйте base_query — только что проверил, всё работает отлично: categories:docs,faqs


Также не рекомендую использовать GPT-4 в последнее время. Лучше используйте GPT-4o или Turbo — они намного дешевле и быстрее.

Просто уточняю… Вы включили

ai_bot_debugging_allowed_groups, чтобы видеть кнопку отладки?

Да. Я отправлю вам личное сообщение с короткой демонстрацией экрана, чтобы показать, что результаты вызова функции read не используются в промпте.

Также я заметил, что функция read никогда не вызывается, если я не добавлю примечание в системный промпт: «всегда вызывай функцию read». Было бы здорово, если бы у нас был больший контроль над вызовом функций. Например, установить tool_choice: "required" в случае с OpenAI.

Я только что снова попробовал с этим базовым запросом, и были использованы правильные параметры поиска. Это первый раз, когда я вижу, что это работает. :person_shrugging:

Я знаю, я просто экспериментирую с разными моделями на данный момент :smile: Мне было интересно, решит ли GPT4 делать другие вызовы функций. Haiku звучит очень многообещающе.

Спасибо большое.

Да, всё верно: инъекция системного промпта происходит только если у персонажа есть загрузки. Если загрузок нет, мы ничего не внедряем.

Без загрузок мы не используем безусловную инъекцию системного промпта, а полагаемся на вызовы инструментов и их результаты — вы можете увидеть их при прокрутке.

Режим без инструментов, ориентированный на темы, безусловно интересен, но он будет потреблять довольно много токенов. Основная сложность — извлечь нужный контент из темы.

Например, если тема занимает 5000 токенов, какие именно токены мы выберем? Как определить правильные токены?

На данный момент мы внедряем только N токенов на тему, в зависимости от используемой модели эмбеддингов.

Поэтому нам нужно либо начать внедрять больше фрагментов на тему, либо разработать алгоритм, который определит, какая часть темы наиболее интересна.

Я запутался. Если результаты вызова инструмента чтения не используются для RAG, то зачем вообще вызывать этот инструмент? Я вижу, что результаты вызова инструмента чтения помещаются в raw context, но кажется, что LLM никак их не использует.

Мой желаемый сценарий использования прост: включить RAG для подмножества тем согласно base_query.

Думаю, лучше не полагаться на Discourse в вопросах разбиения тем на несколько чанков с собственными эмбеддингами. Вместо этого я хочу сам отвечать за создание моих Документов и FAQ, оптимизированных для RAG. То есть, весь основной пост темы должен быть пригоден для эмбеддинга. Речь идёт о вики-темах, ответы на которые можно и нужно игнорировать.

ada-002 имеет максимальный вход в 8191 токен, чего вполне достаточно для любого хорошо написанного документа или FAQ-темы. Такие темы должны быть значительно меньше этого лимита. Voyage AI поддерживает гораздо большую длину контекста — 16000 токенов.

А как насчёт чего-то столь же простого, как это:

  • (токены в системном промпте - токены в сообщении пользователя) = общее количество оставшихся доступных токенов
  • внедрить в промпт как можно больше тем, исходя из общего количества оставшихся доступных токенов
    • использовать только первый пост в найденных темах

Думаю, краткосрочным обходным решением могло бы быть следующее:

  • создать персону, использующую инструмент поиска
  • экспортировать все темы, которые можно найти с помощью инструмента поиска
    • мне не нужно будет разбивать эти документы на части, потому что:
      • мне не важны ответы в темах
      • основная вики-тема уже достаточно мала, чтобы эмбеддить её целиком.
  • Загрузить эти документы в персону для RAG.

Таким образом, персона будет действительно выполнять RAG с результатами поиска.

Надеюсь, это понятно! Дайте знать, если что-то неясно.

Когда вы читаете информацию, она вставляется в поток разговора.

Например:

  • Можешь прочитать X
  • Вызов инструмента read X
  • Результат инструмента «страница»
  • Ответ LLM

RAG — очень перегруженный термин, но в конечном итоге чтение темы добавляет её в контекст, и именно LLM отвечает за то, как её использовать; различные LLM могут использовать это лучше или хуже.

Например: [Untitled AI bot PM] - AI Conversation - Discourse Meta

Инструмент поиска уже вставляет фрагменты тем, поэтому одновременное использование его и RAG для одного и того же контента не имеет смысла.

То, что вы имеете в виду, я полагаю, это: «поиск предоставляет контекст, но недостаточно контекста».

Таким образом, одним из обходных путей является экспорт всех важных тем в файл, а затем использование его как RAG. Не используйте инструмент поиска.


Самое простое решение на данный момент:

categories:cat1,cat2,cat3 in:first

Это ограничит инструмент поиска только первыми постами.

Это очень эффективно, см.:

Это работает, потому что инструмент поиска вставляет в контекст следующее:


Я также хочу иметь безусловный режим «RAG», где можно выбрать вставку ещё большего объёма данных (например, найти 5 лучших документов и вставить до 5000 токенов на каждый документ, пытаясь найти наиболее релевантные разделы).

Это сложное изменение, мы дойдём до этого, но пока… поиск + чтение позволяют достичь значительных результатов.

Просто скажу… вы уже очень близки к тому моменту, когда нужно представить основные правила использования ИИ. У вас ведь уже есть похожие материалы по CSS и нескольким другим темам.

Понятно. Это имеет смысл. Из документации OpenAI по вызову функций:

Базовая последовательность шагов для вызова функций выглядит следующим образом:
1. Вызовите модель с запросом пользователя и набором функций, определённых в параметре functions.
2. Модель может выбрать вызвать одну или несколько функций; в этом случае содержимое будет строковым JSON-объектом, соответствующим вашей пользовательской схеме (примечание: модель может генерировать несуществующие параметры).
3. Разберите строку в JSON в вашем коде и вызовите вашу функцию с предоставленными аргументами, если они существуют.
4. Снова вызовите модель, добавив ответ функции как новое сообщение, и позвольте модели подвести итоги и сообщить их пользователю.

Критически важно: я не знал о шаге №4. Я не понимал, что результаты вызова инструмента добавляются в виде сообщений. Мне казалось, что решение о том, использовать ли результаты в последующих вызовах, полностью зависит от клиента! Поэтому я был сбит с толку, когда не увидел результатов вызова инструмента в самом промпте. :facepalm: Теперь всё это имеет гораздо больше смысла. Спасибо!

:+1: :pray: Похоже, единственный недостаток здесь в том, что ответы бота не будут включать эти красивые результаты поиска. Вы бы настоятельно рекомендовали использовать загрузку документов и инструмент поиска по какой-либо причине, даже если это будет немного избыточно? Мне интересно, перевесят ли преимущества получения результатов поиска в диалоге неудобства.

Вам нужно это протестировать, это может сработать, может дать неожиданные результаты, и многое зависит от используемой вами LLM.