phpbotscout ask¶
The ask command answers a question using only the documentation phpbotscout has already indexed. When the indexed corpus contains an answer, it returns grounded prose backed by citations. When it does not, it declines — honestly and by design — rather than inventing something plausible.
Usage¶
It reads the index built by index build, so an empty index
declines everything.
Description¶
phpbotscout ask turns a question into a grounded answer, or into an honest refusal to answer.
The command retrieves the most relevant passages from the indexed documentation, then asks a language model to compose an answer using only those passages. Every substantive claim in the reply must be traceable to a specific, cited passage that was actually retrieved.
Declining is treated as a first-class outcome, not a failure. There are three situations in which the command will decline instead of answering:
-
Nothing matched. Retrieval returned no passages relevant to the question, so there is nothing to ground an answer in.
-
The composer declined. The passages discuss the subject but do not actually answer the question — a common and especially damaging trap, because the resulting answer would look well sourced while being wrong.
-
The answer could not be grounded. A draft answer was produced, but it cited nothing (see
ErrUngrounded) or cited a passage outside the retrieved set (seeErrFabricatedCitation). Publishing such an answer is exactly the failure this command exists to prevent, so it is downgraded to a decline.
Why declining matters
A declined question is a knowledge gap with a timestamp on it. This is deliberate: the stream of unanswered questions is intended to become a self-writing, prioritised documentation backlog. A decline is an outcome to act on, not an error to suppress.
Answers are grounded, not guessed
The model is instructed to use only the supplied documentation passages and to ignore anything it may "know" about the projects from elsewhere. Passages are treated as untrusted content and fenced within explicit delimiters, so text inside a passage is never interpreted as an instruction.
An actual error (a non-zero exit) is reserved for something genuinely breaking — for example, the index being unreachable or the model provider failing. An error never means "we do not know"; that is a decline. Keeping the two distinct is what allows a knowledge gap to be told apart from an incident.
Which model answers¶
ask reads two configuration keys and has no flags for either:
| Key | Default | Notes |
|---|---|---|
ai.provider |
claude-local |
Only claude and claude-local work. openai, gemini and openai-compatible are refused at construction |
ai.model |
— | Empty leaves the provider's default, which for claude is claude-opus-4-8 — not the Haiku 4.5 the project selected |
The API key for ai.provider: claude comes from ANTHROPIC_API_KEY and from nowhere else; the
credentials chain that serves gitlab.auth is not wired to the AI provider. Full detail in
the configuration reference.
--retrieval-only needs no provider and no key at all.
Flags¶
| Name | Description | Default |
|---|---|---|
--limit |
How many passages to retrieve. Values of 0 or below fall back to the default, which is why --help lists no default for it. |
8 |
--retrieval-only |
Print the ranked passages without composing an answer. No model is called, so this costs nothing. | false |
-h, --help |
Help for ask. |
false |
Global flags (--config, --debug, --output, --ci) are inherited from the
root command.
Diagnosing a bad answer
--retrieval-only separates the two things that can go wrong. If the right
passage is not in the ranked list, the problem is retrieval; if it is there
and the answer is still wrong, the problem is composition. Raising --limit
tells you whether a missing answer was ranked just out of reach.
Examples¶
Ask a question directly:
Ask a longer, quoted question:
An answer is grounded in the documentation and carries its citations, heading path included:
$ phpbotscout ask "How do I stop a gtb tool checking for updates?"
To stop a gtb tool from checking for updates, set the `update.policy` configuration key to
`disabled`. This will log only without checking for updates.
Sources:
Configuration Keys › Self-update
https://go-tool-base-ff2fdf.gitlab.io/reference/config/#self-update
When the corpus does not cover the question, it declines rather than guessing — and shows what it did retrieve, so the gap is diagnosable:
$ phpbotscout ask "What is the airspeed velocity of an unladen swallow?"
No answer from the indexed documentation.
nothing in the indexed documentation matched this question
Inspect retrieval without spending anything on a model:
What ask cannot do¶
- It cannot answer from anything not indexed. An empty index declines everything; build one
first with
index build. - It cannot search semantically. Ranking is BM25 keyword matching, so a question sharing no vocabulary with the page that answers it will not find it.
- It has no memory. Each question is answered from its own passages; nothing carries over.
- It has no relevance-threshold setting.
--limitis the only retrieval control.
See also¶
- Configuration:
ai— provider, model, and what happens when either is wrong - How an answer is produced — grounding, declines, and why there is no score gate
- Indexing reference — how the passages it retrieves were made
- Diagnose a bad answer — when it declines and you think it should not