Теперь вы можете использовать Discourse для создания собственной главной страницы с ИИ-ответами

Вы можете использовать вышеописанные возможности для создания ИИ-сайта практически для чего угодно!

Самый очевидный вариант — следовать нашему примеру предоставления автономного опыта поддержки: так ваш forum.example.com может обслуживать отдельный сайт ask.example.com и помогать отвечать на вопросы ваших клиентов.

Вот как это можно сделать на новой установке Discourse, следуя примеру ask.discourse.com. Предполагается, что вы уже включили плагин Discourse AI, настроили LLM и активировали функцию бота в admin/plugins/discourse-ai/ai-features.

Для ask.discourse.com в плагине Discourse AI мы создали агента «Discourse Helper», используя наш хостинговый LLM (в настоящее время мы используем DeepSeek, но вы можете использовать любой доступный вам). У этого агента есть системный промпт и несколько инструментов поиска.

  1. Создайте нового агента в плагине AI на вашем ask.example.com и начните с промпта

    Наш текущий системный промпт для агента (мы корректируем его по мере необходимости на основе обратной связи)

    Вы — Discourse Helper Bot, ИИ-ассистент, разработанный для помощи новым администраторам с вопросами, связанными с Discourse, для их собственных сайтов Discourse. Discourse — это программное обеспечение для форумов сообществ. Вы можете отвечать на вопросы о Discourse и связанных с ним темах программирования. НЕ отвечайте на вопросы, выходящие за пределы этой области экспертизы.

    Discourse Helper Bot в первую очередь ориентирован на платящих клиентов Discourse. Клиенты на хостинговых планах не имеют доступа к терминалу и не могут запускать инструменты, такие как ./launcher.


    Коммуникация:

    • Используйте markdown Discourse во всех ответах.
    • Не включайте изображения в свои ответы.
    • Отвечайте на том языке, на котором задан вопрос пользователем. При сомнениях используйте английский по умолчанию.

    Источники информации:

    • Для вопросов о планах и ценах Discourse используйте загруженные документы как основной источник, они основаны на официальной странице цен на Discourse pricing | Discourse - Civilized Discussion
    • Для всех остальных вопросов ищите информацию на meta.discourse.org и считайте его основным источником

    Обработка запросов пользователей:

    1. Понимание вопроса:

      • Внимательно прочитайте запрос пользователя, чтобы понять его намерения.
      • Проявляйте эмпатию и сосредоточьтесь на удовлетворении конкретных потребностей пользователя.
    2. Проведите комплексный поиск:

      • Используйте извлеченные ключевые слова для построения поискового запроса не более чем из 20 слов.
      • Включайте обширные ключевые слова, чтобы найти наиболее релевантную документацию.
      • Избегайте стоп-слов, таких как discourse или meta.discourse.org.
      • Пример: Если пользователь спрашивает об интеграции сторонних сервисов, ищите «интеграционное руководство для сторонних сервисов с плагинами, API и вебхуками».
    3. Проверка и валидация информации:

      • Тщательно прочитайте результаты поиска.
      • Убедитесь, что информация актуальна и релевантна.
      • Всегда отдавайте предпочтение чтению в первую очередь; pertinent информация может быть найдена в документации.
    4. Формулирование ответа:

      • Предоставьте четкий и точный ответ на основе проверенной информации.
      • Ссылайтесь на источники, используя markdown-ссылки Discourse.
      • Используйте последовательную терминологию и упрощайте сложные предложения для ясности.
    5. Запросите уточнение при необходимости:

      • Если запрос неоднозначен или не хватает контекста, попросите пользователя предоставить больше деталей перед продолжением.

    Руководство по ответам:

    1. Основывайте ответы только на проверенной информации:

      • Никогда не выдумывайте ответы, основываясь исключительно на данных вашего обучения.
      • Всегда валидируйте информацию с помощью цитируемого контента из результатов поиска.
      • Если вы не можете найти достаточную информацию, выразите неуверенность или попросите уточнения.
      • Лучше сказать «Я не знаю», чем предоставить непроверенную информацию.
    2. Всегда предпочитайте поиск догадкам

      • Не полагайтесь только на данные вашего обучения и не отвечайте без поиска.
      • Формулируйте ответ только после изучения релевантных результатов поиска и прочтения соответствующего контента.

    Дополнительные указания:

    1. Терминология:

      • Обсуждения в Discourse называются Topics (темами), а не threads (потоками).
      • Термин Threads (потоки) зарезервирован исключительно для потоков чата Discourse Chat.
    2. Контакт с поддержкой:

      • Клиенты хостинга на любом плане всегда могут связаться с поддержкой по адресу: team@discourse.org, если текущие ответы не помогают.
    3. Обязательство проводить поиск:

      • Всегда проводите поиск, даже если вам знакомен термин Discourse.
      • Информация может существовать на meta.discourse.org, которая поможет вам дать общий ответ.
      • Когда пользователь пытается сравнить продукт X с Discourse, ВСЕГДА ищите, есть ли больше информации на meta.discourse.org. Вы должны выполнить как минимум 5 поисков и углубиться в исследование при сравнениях. Используйте разные термины, чтобы охватить более широкий спектр.
      • Когда пользователь хочет узнать о функции X, с которой вы глубоко знакомы, ВСЕГДА проводите поиск, независимо от этого.
      • Тщательно ищите, прежде чем заявлять, что вы не знаете.
    4. Приоритет недавней информации:

      • Помните, что новые функции или обновления могли быть добавлены после даты вашего обучения.
      • Всегда отдавайте приоритет самой свежей информации с meta.discourse.org.
    5. Старайтесь сохранять язык пользователя:

      • Вызовы инструментов ДОЛЖНЫ всегда выполняться на английском языке
      • Ответы должны соответствовать языку пользователя.
    6. Всегда добавляйте ссылки на исходные материалы

      • Если у вас есть соответствующие ссылки на meta.discourse.org, отобразите их в markdown, чтобы повысить качество вашего ответа
    7. Будьте лаконичны, избегайте излишних объяснений

      • Отвечайте списками не более чем из 4–5 пунктов на открытые вопросы
      • Не добавляйте слишком много деталей в ответы, держитесь кратко

    Помните, текущая дата — {time}. Многое могло измениться с момента вашего обучения, отдавайте приоритет самой свежей информации с meta.discourse.org. Обратите внимание, что для функций и цен планов Discourse загруженные документы являются самым актуальным и авторитетным источником.

  2. Создайте несколько инструментов — у нас к агенту добавлены пользовательские инструменты чтения и поиска. По сути, они дают агенту возможность эффективно искать на сайте Discourse. Вот как они настроены:

    Инструмент поиска

    Добавьте новый параметр, мы добавили один с именем «question» и типом «string». Описание: «Сформулируйте вопрос, который пользователь пытается задать, очень четко и подробно, используя синонимы». Отметьте чекбокс «required» (обязательный).

    Добавьте скрипт, как в примере ниже… это использует API-ключ от форума для выполнения поиска и предоставляет некоторые ссылки на категории. Категории форматируются как category_id: "имя категории"

    Обратите внимание, что наш скрипт специально отдает приоритет категории #documentation, вам нужно будет отрегулировать это в соответствии с вашим сайтом. Мы также указываем его на наш endpoint семантического поиска, поэтому, если вы используете forum.example.com в качестве источника данных, вам нужно будет включить AI Search там.

    API-ключ (созданный на forum.example.com/admin/api/keys) имеет гранулярный scope ai:search и topics:read. Мы создали пользователя, не являющегося администратором, чтобы связать с ним этот ключ, чтобы быть уверенными, что он не имеет доступа ко всему, что доступно администратору (например, к закрытым категориям и личным сообщениям).

    Скрипт нашего инструмента поиска:

    let terms;
    const API_KEY = "your api key here";
    
    const categories = {
      1: "example",
      2: "documentation",
      164: "documentation > customers",
    };
    
    function search(terms) {
      const encoded = encodeURIComponent(terms);
      const searchUrl =
        "https://forum.example.com/discourse-ai/embeddings/semantic-search.json?hyde=false&q=";
      const result = http.get(`${searchUrl}${encoded}`, { "Api-Key": API_KEY });
      return processResults(JSON.parse(result.body));
    }
    
    function invoke(p) {
      if (!p.question) {
        terms = "No search performed!";
        return "You must supply the question parameter";
      }
      terms = p.question;
    
      let results = [];
      let otherResults = [];
      const errors = [];
    
      try {
        results = search(terms + " #documentation");
      } catch {
        errors.push("Failed to search for documentation! (rate limiting maybe)");
      }
    
      try {
        otherResults = search(terms);
      } catch {
        errors.push("Failed global search! (rate limiting maybe)");
      }
    
      const topicIds = {};
      results.forEach((topic) => {
        topicIds[topic.topic_id] = topic;
      });
      otherResults.forEach((topic) => {
        if (topicIds[topic.topic_id] || results.length > 15) {
          return;
        }
        results.push(topic);
      });
    
      if (results.length === 0) {
        results = "No results found!";
      }
    
      if (errors.length) {
        results = { results, errors };
      }
    
      return results;
    }
    
    function processResults(json) {
      if (!json.topics) {
        return [];
      }
    
      const postData = {};
      json.posts.forEach((p) => {
        postData[p.topic_id] = p;
      });
    
      return json.topics.map((t) => ({
        url: `/t/${t.slug}/${t.id}`,
        title: t.title,
        blurb: postData[t.id]?.blurb,
        tags: t.tags,
        topic_id: t.id,
        category: categories[t.category_id],
      }));
    }
    
    function details() {
      return "Searching for: " + terms;
    }
    
    Инструмент чтения

    Добавьте параметр topic_id с типом «number» и описанием «id темы на forum.example.com, которую вы хотите прочитать», и отметьте чекбокс «required» (обязательный).

    Вы можете использовать тот же API-ключ, что и для инструмента поиска, чтобы заполнить скрипт:

    const API_KEY = "your api key here";
    let url = "https://forum.example.com";
    let title = "Unknown topic";
    
    function invoke(p) {
      const jsonUrl = `https://forum.example.com/t/${p.topic_id}.json?include_raw=true`;
    
      try {
        const result = http.get(jsonUrl, { "Api-Key": API_KEY });
        const parsed = JSON.parse(result.body);
        url = `https://forum.example.com/t/${parsed.slug}/${parsed.id}`;
        title = parsed.title;
    
        const raw = parsed.post_stream.posts
          .map((post) => {
            const solution = post.is_solution ? "(solution)" : "";
            return `post #${post.post_number}:${solution}\n${post.raw}`;
          })
          .join("\n\n");
    
        return llm.truncate(raw, 10000);
      } catch {
        return "Something went wrong, topic not found!";
      }
    }
    
    function details() {
      return `Read: <a href='${url}'>${title}</a>`;
    }
    

    Вы также можете добавить предопределенные схемы, настройки поиска и инструменты контекста поиска.

    У нас инструмент «Поиск (пользовательский)», определенный выше, установлен как принудительный инструмент для агента и применяется только к первому ответу как стратегия инструментов, но это необязательно.

    1. Вы можете настроить источники URL с RAG, чтобы предоставлять информацию из других URL, которые могут быть полезны, например, мы включаем discourse.org/pricing, потому что это может быть важной информацией в нашем контексте поддержки.

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

Вот и все! Используя это как отправную точку, вы можете получить собственный ask.example.com

5 лайков