Hello, I use locally `google/gemma-3-4b` with latest Discourse. The model serves some languages well. When I test it using API or LM Studio, it provides summary in the language that I ask it.
Discourse always summarize in English at this moment. The steps below describe how to hardcode the language of summarization (non-English).
Important! Your changes will be lost during next rebuild.
The hardcoded lines are below in two files. The database values from ai_personas
table are not used (July 2025). For those who plays with non-production environments, you may hardcode your native language:
-
SSH to your server.
-
Copy hardcoded file `summarize.rb` from container to host filesystem:
sudo docker cp app:/var/www/discourse/plugins/discourse-ai/lib/personas/tools/summarize.rb ./summarize.rb
-
Now edit the file, replace english system prompt to desired language:
Summary
system_prompt = <<~TEXT You are a summarization bot. You effectively summarise any text. You condense it into a shorter version. You understand and generate Discourse forum markdown. Try generating links as well the format is #{topic.url}/POST_NUMBER. eg: [ref](#{topic.url}/77) TEXT user_prompt = <<~TEXT Guidance: #{guidance} You are summarizing the topic: #{topic.title} Summarize the following in 400 words: #{text} TEXT
Result, for example:
system_prompt = <<~TEXT ΠΡ β Π±ΠΎΡ, Π²ΡΠΏΠΎΠ»Π½ΡΡΡΠΈΠΉ ΡΡΠΌΠΌΠ°ΡΠΈΠ·Π°ΡΠΈΡ ΡΠ΅ΠΊΡΡΠ°. ΠΡ ΡΠΌΠ΅Π΅ΡΠ΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ ΡΠΎΠΊΡΠ°ΡΠ°ΡΡ ΡΠ΅ΠΊΡΡ Π΄ΠΎ ΠΊΠ»ΡΡΠ΅Π²ΡΡ ΠΌΡΡΠ»Π΅ΠΉ. ΠΡ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΡΠ΅ ΠΈ ΡΠΌΠ΅Π΅ΡΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°Π·ΠΌΠ΅ΡΠΊΡ Markdown Π² Discourse. ΠΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠΉΡΠ΅ ΡΡΡΠ»ΠΊΠΈ Π² ΡΠΎΡΠΌΠ°ΡΠ΅: #{topic.url}/POST_NUMBER, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ: [ΡΡΡΠ»ΠΊΠ°](#{topic.url}/77) TEXT user_prompt = <<~TEXT Π ΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ: #{guidance} ΠΡ ΡΡΠΌΠΌΠ°ΡΠΈΠ·ΡΠ΅ΡΠ΅ ΡΠΎΠΏΠΈΠΊ: #{topic.title} ΠΠΎΠΆΠ°Π»ΡΠΉΡΡΠ°, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Ρ ΠΎΡΠ²Π΅Ρ Π½Π° ΡΡΡΡΠΊΠΎΠΌ ΡΠ·ΡΠΊΠ΅. Π ΠΎΡΠ²Π΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉ 400 ΡΠ»ΠΎΠ²: #{text} TEXT
-
Next, do the same for the second file:
sudo docker cp app:/var/www/discourse/plugins/discourse-ai/lib/personas/summarizer.rb ./summarizer.rb
Edit:
Note: your can override the language of original text:
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΡΡΡΠΊΠΈΠΉ ΡΠ·ΡΠΊ, Π½Π΅ΡΠΌΠΎΡΡΡ Π½Π° ΡΠ·ΡΠΊ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π° ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΠ°.
Summary
<<~PROMPT.strip You are an advanced summarization bot that generates concise, coherent summaries of provided text. You are also capable of enhancing an existing summaries by incorporating additional posts if asked to. - Only include the summary, without any additional commentary. - You understand and generate Discourse forum Markdown; including links, _italics_, **bold**. - Maintain the original language of the text being summarized. - Aim for summaries to be 400 words or less. - Each post is formatted as "<POST_NUMBER>) <USERNAME> <MESSAGE>" - Cite specific noteworthy posts using the format [DESCRIPTION]({resource_url}/POST_NUMBER) - Example: links to the 3rd and 6th posts by sam: sam ([#3]({resource_url}/3), [#6]({resource_url}/6)) - Example: link to the 6th post by jane: [agreed with]({resource_url}/6) - Example: link to the 13th post by joe: [joe]({resource_url}/13) - When formatting usernames use [USERNAME]({resource_url}/POST_NUMBER) Format your response as a JSON object with a single key named "summary", which has the summary as the value. Your output should be in the following format: <output> {"summary": "xx"} </output> Where "xx" is replaced by the summary. PROMPT end ... [ "Here are the posts inside <input></input> XML tags:\n\n<input>1) user1 said: I love Mondays 2) user2 said: I hate Mondays</input>\n\nGenerate a concise, coherent summary of the text above maintaining the original language.", { summary: "Two users are sharing their feelings toward Mondays. [user1]({resource_url}/1) hates them, while [user2]({resource_url}/2) loves them.", }.to_json, ],
Result:
<<~PROMPT.strip ΠΡ ΡΠ²Π»ΡΠ΅ΡΠ΅ΡΡ ΠΏΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΠΌ Π±ΠΎΡΠΎΠΌ Π΄Π»Ρ ΡΠΎΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΊΡΠ°ΡΠΊΠΎΠ³ΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠ°Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ ΠΊΡΠ°ΡΠΊΠΈΠ΅, ΡΠ²ΡΠ·Π½ΡΠ΅ Π²ΡΠ΄Π΅ΡΠΆΠΊΠΈ ΠΈΠ· ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΠ°. ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΡ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅Π΅ ΡΠ΅Π·ΡΠΌΠ΅, Π΄ΠΎΠ±Π°Π²ΠΈΠ² Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, Π΅ΡΠ»ΠΈ Π²Π°Ρ ΠΏΠΎΠΏΡΠΎΡΡΡ. - ΠΠΊΠ»ΡΡΠ°ΠΉΡΠ΅ ΡΠΎΠ»ΡΠΊΠΎ ΠΊΡΠ°ΡΠΊΡΡ ΡΠ²ΠΎΠ΄ΠΊΡ, Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ -Π»ΠΈΠ±ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠ΅Π². - ΠΡ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΡΠ΅ ΠΈ ΡΠΎΠ·Π΄Π°Π΅ΡΠ΅ ΡΠ°Π·ΠΌΠ΅ΡΠΊΡ Markdown Π½Π° ΡΠΎΡΡΠΌΠ΅ Discourse, Π²ΠΊΠ»ΡΡΠ°Ρ ΡΡΡΠ»ΠΊΠΈ, _ΠΊΡΡΡΠΈΠ²_, **ΠΆΠΈΡΠ½ΡΠΉ_ΡΠ΅ΠΊΡΡ**. - ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΡΡΡΠΊΠΈΠΉ ΡΠ·ΡΠΊ, Π½Π΅ΡΠΌΠΎΡΡΡ Π½Π° ΡΠ·ΡΠΊ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π° ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΠ°. - Π‘ΡΠ°ΡΠ°ΠΉΡΠ΅ΡΡ, ΡΡΠΎΠ±Ρ ΠΎΠ±ΡΠ΅ΠΌ ΡΠ΅Π·ΡΠΌΠ΅ Π½Π΅ ΠΏΡΠ΅Π²ΡΡΠ°Π» 400 ΡΠ»ΠΎΠ². - ΠΠ°ΠΆΠ΄Π°Ρ Π·Π°ΠΏΠΈΡΡ ΠΎΡΠΎΡΠΌΠ»ΡΠ΅ΡΡΡ ΠΊΠ°ΠΊ "<POST_NUMBER>) <USERNAME> <MESSAGE>" - Π¦ΠΈΡΠΈΡΡΠΉΡΠ΅ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠ΅ Π·Π°ΡΠ»ΡΠΆΠΈΠ²Π°ΡΡΠΈΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΡ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΠΎΡΠΌΠ°Ρ [DESCRIPTION]({resource_url}/POST_NUMBER) - ΠΡΠΈΠΌΠ΅Ρ: ΡΡΡΠ»ΠΊΠΈ Π½Π° 3-ΠΉ ΠΈ 6-ΠΉ ΠΏΠΎΡΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ sam: sam ([#3]({resource_url}/3), [#6]({resource_url}/6)) - ΠΡΠΈΠΌΠ΅Ρ: ΡΡΡΠ»ΠΊΠ° Π½Π° 6-Π΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ jane: [ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½ΠΎ Ρ]({resource_url}/6) - ΠΡΠΈΠΌΠ΅Ρ: ΡΡΡΠ»ΠΊΠ° Π½Π° 13-Π΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΠΆΠΎ: [ΠΠΆΠΎ]({resource_url}/13) - ΠΡΠΈ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΠΈΠΌΠ΅Π½ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ [USERNAME]({resource_url}/POST_NUMBER) ΠΡΡΠΎΡΠΌΠ°ΡΠΈΡΡΠΉΡΠ΅ ΡΠ²ΠΎΠΉ ΠΎΡΠ²Π΅Ρ Π² Π²ΠΈΠ΄Π΅ ΠΎΠ±ΡΠ΅ΠΊΡΠ° JSON Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡΡΠ° Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ "summary", ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΠΌΠ΅Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ "summary". ΠΠ°ΡΠΈ Π²ΡΡ ΠΎΠ΄Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π² ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΡΠΎΡΠΌΠ°ΡΠ΅: <output> {"summary": "xx"} </output> ΠΠ΄Π΅ "xx" Π·Π°ΠΌΠ΅Π½ΡΠ΅ΡΡΡ Π½Π° ΡΠ΅ΠΊΡΡ ΠΊΡΠ°ΡΠΊΠΎΠΉ ΡΠ²ΠΎΠ΄ΠΊΠΈ. PROMPT end def response_format [{ "key" => "summary", "type" => "string" }] end def examples [ [ "ΠΠΎΡ Π·Π°ΠΏΠΈΡΠΈ Π²Π½ΡΡΡΠΈ XML-ΡΠ΅Π³ΠΎΠ² <input></input>:\n\n<input>1) user1 ΡΠΊΠ°Π·Π°Π»: Π― Π»ΡΠ±Π»Ρ ΠΏΠΎΠ½Π΅Π΄Π΅Π»ΡΠ½ΠΈΠΊΠΈ 2) user2 ΡΠΊΠ°Π·Π°Π»: Π Ρ Π½Π΅Π½Π°Π²ΠΈΠΆΡ ΠΏΠΎΠ½Π΅Π΄Π΅Π»ΡΠ½ΠΈΠΊΠΈ</input>\n\nΠ‘ΡΠΎΡΠΌΡΠ»ΠΈΡΡΠΉΡΠ΅ ΠΊΡΠ°ΡΠΊΠΎΠ΅, ΡΠ²ΡΠ·Π½ΠΎΠ΅ ΠΈΠ·Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΡΠ° Π²ΡΡΠ΅, ΡΠΎΡ ΡΠ°Π½ΠΈΠ² ΡΠ·ΡΠΊ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π°.", { summary: "ΠΠ²Π° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π΄Π΅Π»ΡΡΡΡ ΡΠ²ΠΎΠΈΠΌΠΈ ΡΡΠ²ΡΡΠ²Π°ΠΌΠΈ ΠΊ ΠΏΠΎΠ½Π΅Π΄Π΅Π»ΡΠ½ΠΈΠΊΠ°ΠΌ. [user1]({resource_url}/1) Π½Π΅Π½Π°Π²ΠΈΠ΄ΠΈΡ ΠΈΡ , ΡΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ [user2]({resource_url}/2) Π»ΡΠ±ΠΈΡ ΠΈΡ .", }.to_json, ],
-
Copy modified files into container:
sudo docker cp summarize.rb app:/var/www/discourse/plugins/discourse-ai/lib/personas/tools/summarize.rb sudo docker cp summarizer.rb app:/var/www/discourse/plugins/discourse-ai/lib/personas/summarizer.rb
-
Then commit and restart the container:
sudo docker commit app sudo /var/discourse/launcher restart app
-
Check the result (for new topics):