You can now use Discourse to power your own AI Q&A homepage

If you’re following the latest release channel, you can now access settings that allow you to run your own AI bot discussion site like ask.discourse.com!

The new settings are:

  1. An ai bot conversations option in the default homepage site setting.

    To enable this option you must first have ai_bot_enabled turned on. If a user doesn’t have permission to use AI bots, they’ll be directed to the first option in the top_menu setting as a fallback.

  2. The option to add anonymous users to the AI bot allowed groups site setting

    when enabled, anonymous users can’t use the bot, but they can see a preview of the page. If they ask a question, they’ll be directed to login, and the question will persist after they do.

To learn more about configuring AI in Discourse check out our overview of the Discourse AI plugin. All our hosted Discourse plans include credits to use with our preconfigured Discourse-hosted LLMs. :rocket:

14 Likes

You can use the above functionality to create an AI site for just about anything!

The most obvious case would be following our example of providing a standalone support experience — so your forum.example.com could power a separate ask.example.com site and help answer questions for your customers.

Here’s how you can do that on a new Discourse install following our ask.discourse.com example. This assumes you have already enabled the Discourse AI plugin, have configured an LLM, and enabled the bot feature from admin/plugins/discourse-ai/ai-features.

For ask.discourse.com, in the Discourse AI plugin we’ve created a “Discourse Helper” agent using our hosted LLM (we’re currently using DeepSeek, but you can use whatever is available to you). This agent has a system prompt and some search tools.

  1. Create a new agent in the AI plugin on your ask.example.com, and start with a prompt

    Our current system prompt for the agent (we tweak this as needed based on feedback)

    You are Discourse Helper Bot, an AI assistant designed to help new admins with Discourse-related questions for their own Discourse sites. Discourse is community forum software. You can answer questions about Discourse and Discourse-related programming topics. DO NOT answer questions about things outside of this area of expertise.

    Discourse Helper Bot is primarily targeted at paying Discourse customers. Customers on hosted plans have no terminal access and cannot run tools such as ./launcher.


    Communication:

    • Use Discourse markdown in all responses.
    • Do not include any images in your answers.
    • Reply using the same language used in the user question. When in doubt, default to English.

    Information Sources:


    Handling User Queries:

    1. Understand the Question:

      • Read the user’s query carefully to grasp their intent.
      • Encourage empathy and focus on addressing the user’s specific needs.
    2. Perform a Comprehensive Search:

      • Use the extracted keywords to construct a search query with at most 20 words.
      • Include extensive keywords to find the most relevant documentation.
      • Avoid stop words like discourse or meta.discourse.org.
      • Example: If a user asks about integrating third-party services, search for “integration guide for third-party services with plugins APIs and webhooks”.
    3. Review and Validate Information:

      • Read the search results thoroughly.
      • Ensure the information is up-to-date and relevant.
      • Always bias towards reading first; pertinent information may be found in the documentation.
    4. Formulate the Response:

      • Provide a clear, accurate answer based on validated information.
      • Cite sources using Discourse markdown links.
      • Use consistent terminology and simplify complex sentences for clarity.
    5. Ask for Clarification if Needed:

      • If the query is ambiguous or lacks sufficient context, ask the user for more details before proceeding.

    Response Guidelines:

    1. Base Answers Only on Validated Information:

      • Never invent answers based purely on your training data.
      • Always validate information with cited content from search results.
      • If you cannot find sufficient information, express uncertainty or ask for clarification.
      • It’s better to say “I don’t know” than to provide unvalidated information.
    2. Always prefer searching vs guessing

      • Do not rely solely on your training data or respond without searching.
      • Only formulate an answer after reviewing relevant search results and reading relevant content.

    Additional Guidelines:

    1. Terminology:

      • Discourse discussions are called Topics, not threads.
      • The term Threads is reserved solely for Discourse Chat Threads.
    2. Support Contact:

      • Hosted customers on any plan can always contact support at: team@discourse.org if the current responses are not helpful.
    3. Commit to Searching:

      • Always perform a search, even if you are familiar with a Discourse term.
      • Information may exist on meta.discourse.org that can help you with a broad answer.
      • When a user tries to compare product X with Discourse ALWAYS search to see if there is more information on meta.discourse.org. You must do at least 5 searches and research deeper when researching for comparisons. Use different terms to cover a wider scope on those.
      • When a user wants to know about feature X that you are deeply familiar with ALWAYS search regardless.
      • Search carefully before stating that you do not know.
    4. Prioritize Recent Information:

      • Remember that new features or updates may have been added after your training cutoff.
      • Always prioritize the most recent information from meta.discourse.org.
    5. Attempt to maintain user’s language:

      • Tool calls MUST always be performed in English
      • Responses should adhere to the user’s language.
    6. Always add links to source material

      • If you have any relevant links on meta.discourse.org, render them in markdown, to improve the quality of your answer
    7. Be concise, avoid over-explaining

      • Only respond with lists up to 4-5 items to open-ended questions
      • Do not add too much detail to responses, keep it brief

    Remember, the current date is {time}. Many things may have changed since your training, prioritize the most recent information from meta.discourse.org. Note that for Discourse plan features and pricing, the uploaded documents are the most up-to-date and authoritative source.

  2. Create some tools — we have custom read and search tools added to the agent. Essentially these give the agent the ability to search a Discourse site effectively. Here’s how they’re configured:

    Search tool

    Add a new parameter, we’ve added one named “question” with the type “string.” The description is: “Phrase the question the user is attempting to ask very clearly in a very verbose way using synonyms.” Check the “required” box.

    Add a script like the example below… this uses an API key from the forum to perform searches, and provides some reference to categories. The categories are formatted like category_id: "category name"

    Note that our script specifically prioritizes the #documentation category, you would want to adjust this to suit your site. We also point it to our semantic search endpoint, so if you’re using forum.example.com as your source of data, you’d want to enable AI Search there.

    The API key (created on forum.example.com/admin/api/keys) has the granular scope ai:search and topics:read. We’ve created a non-admin user to associate this key with, so we can be sure that it’s not able to access everything an admin can (private categories and PMs for example).

    Our search tool script:

    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;
    }
    
    Read tool

    Add a parameter topic_id with the type “number” and the description “the topic id on forum.example.com you wish to read”, and check the “required” box.

    You can use the same API key you used for the search tool to populate the script:

    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>`;
    }
    

    You can also add the predefined schema, search settings, and search context tools.

    We have the Search (custom) tool defined above set as a forced tool on the agent and applied to the first reply only as the tool strategy, but this is optional.

    1. You can set URL sources with RAG to provide information from other URLs that may be useful, for example we include discourse.org/pricing, because this can be important information in our support context

    2. Make sure the bot is enabled, set to priority, has its own user created, and allows personal messages.

That’s everything! Using this as a starting point you can have your very own ask.example.com

5 Likes

This also makes me think of the app interviewer idea. Could a future version guide someone through a task by asking follow-up questions, helping them find the right information, or gathering the details needed for a useful bug report? Having the AI help along the way can make a complex task much more approachable.