AI-assisted authoring
The six DeepSeek helpers — the API key they need, what each one sends, the input bounds that stop a single request running up your bill, the one helper that puts your whole library in a prompt, and the batch-improve screen that overwrites published answers.
Six helpers, all backed by DeepSeek, all optional. They draft, improve and classify article content; none of them publishes anything. Every result lands in a form field for you to accept, edit or discard — except on the batch screen, which is covered at the end and behaves differently.
What they need
One environment variable:
DEEPSEEK_API_KEY="sk-…"Requests go to https://api.deepseek.com/v1/chat/completions using the
deepseek-chat model. There is no model selector, no temperature control and no
proxy setting — those are fixed per helper in code.
With no key set, every helper returns 500 with DeepSeek API key is not set.
A line is written to the backend log at boot, and that is the only advance warning.
No admin screen shows the integration's status, and the AI buttons are rendered
whether or not the key exists.
If a colleague reports "the AI thing is broken", check the key before anything else.
The key is shared platform-wide — it is not scoped to this addon. There is no
usage counter, no spend cap and no per-user quota anywhere in the product. Your
only budget control is the DeepSeek dashboard and who holds create.faq.
The permission is the budget
All six gate on create.faq — the same key that lets somebody add an article.
There is no separate AI permission.
That is the fact to plan around. Granting an author create.faq so they can write
articles also grants them the ability to spend your DeepSeek balance, repeatedly,
including from a screen that loops over every article on a page. If your billing
matters, keep create.faq on a small set of roles and let everyone else work
under edit.faq.
Input bounds
Every helper bounds its input before anything reaches the model:
| Bound | Limit | Applies to |
|---|---|---|
| Topic | 500 characters | The subject you hand generate |
| Question | 2,000 characters | A question being answered or improved |
| Content | 20,000 characters | An answer body, or free text to summarise |
Over the limit, the request is refused with a 400 that states the actual length and the limit, before a single token is billed.
None of these routes bounded what they forwarded. A single request carrying a 200,000-character "topic" was sent verbatim and billed accordingly — an admin account, or anything that had obtained one, could run the bill up with one call and repeat it as fast as the network allowed.
The limits above are generous for the job each helper does. A topic is a sentence; an answer to improve is a few paragraphs. Anything past that is not a real request.
What each helper does
Generate
You give it a topic and optional context; it returns a question, an answer and suggested tags as a structured result. If the model returns something that is not valid JSON, the raw text is used as the answer with your topic as the question rather than failing — so an odd-looking draft is a parse fallback, not a bug.
Treat the output as a first draft written by something that has never seen your platform. It knows nothing about your fees, your limits, your supported networks or your withdrawal times, and it will state plausible values for all of them. Check every number.
Improve
You give it the question and the current answer; it returns a rewritten answer, and nothing else. It is a rephrasing tool: clearer, longer, better structured. It cannot add facts it was not given, so it will not fix an answer that is wrong — it will make a wrong answer read more confidently.
Answer
You give it a submitted reader question; it answers from your published articles. Unpublished ones are excluded.
Every published article's question and answer text is loaded and concatenated into the prompt. There is no cap and no relevance pre-filter.
On a small library that is fine. On a large one it means every press of this button sends your whole knowledge base to a metered API — the cost scales with the size of your library, not with the question — and past a certain size the prompt simply stops fitting, at which point the helper starts failing rather than degrading.
If your library is large, prefer answering by hand and use generate for the
drafting.
The prompt instructs the model to reply "I don't have enough information to answer this question" when the library does not cover it. That answer is the useful one: it is a knowledge gap, so convert the question into a new article rather than pressing the button again.
Tag
Question and answer in, three to five tags out. If the model returns something unparseable, quoted strings are extracted from the response as a fallback.
Remember the storage rules: at most 10 tags, each 2–30 characters, letters, digits,
spaces, - and _ only. A suggestion outside those is rejected on save, not on
suggestion.
Related
The most carefully built of the six. It loads a shortlist of at most 200 published articles, most-viewed first, excluding the one you are editing, and asks the model to choose up to five a reader would want next.
Two safeguards:
- The shortlist is capped because every candidate's question text goes into the prompt, and the cap takes the most-viewed first so the entries most worth linking to are the ones that survive it.
- Whatever identifiers come back are intersected against that same shortlist
before anything is returned. Without that intersection a hallucinated identifier
would be written into
relatedFaqIdsand render as a dead link forever.
If there are no other published articles, it returns an empty list rather than inventing one.
Summarize
Free text in, a paragraph under 100 words out. It writes nothing to any article — the result is yours to paste wherever you want it.
The batch improve screen
/admin/faq/ai is gated on access.faq, and it is not in the navigation —
the only way in is the AI Improve button in the header of the Manage screen.
It offers three scopes: one article, every article on a page path, or all of them.
For each article in scope it calls improve, then writes the result straight
back over the stored answer, and reports how many succeeded, failed or were
skipped.
There is no diff, no confirmation per article and no rollback. An answer that was correct and an answer that was carefully worded are both replaced by whatever the model returns. Articles are published, so the new text is live the moment it is written.
It is also a call per article, sequentially. Pointing it at "all" on a library of three hundred articles is three hundred billed requests and three hundred rewritten answers.
Take a database backup first, and run it against a single page path you can check by hand before you ever run it wider.
The narrower per-article helpers in the editor are the safe way to use the same model: same call, same result, but it lands in the form for you to read before you save.
A workflow that holds up
-
Draft with
generate, from a topic in your own words. -
Correct every fact. Fees, limits, timings, network names, supported assets. The model does not know your platform and will invent all of them convincingly.
-
Run
tagandrelatedonce the text is final, not before — both read the answer, and tagging a draft you are about to rewrite wastes the call. -
Publish, then leave it alone. Let real feedback tell you whether it works.
-
Use
improveon articles the dashboard says are failing, and read the result before saving. A failing article is usually failing on content, whichimprovecannot fix — check the feedback comments first to see whether the problem is the wording or the answer.
Everything the helpers produce is subject to the same validation as hand-written content: 10–500 characters for a question, 20–10,000 for an answer, and the answer is sanitised of scripts and event handlers on the way in and again on the way out. See Writing and publishing articles.