
Grounded Support Agent
io.github.Ankit512由 GitHub 账号 Ankit512 发布v0.1.0更新于 Oct 24, 2026
Governed support MCP: answers only KB-grounded questions with citations, escalates the rest.
概览
一个本地、只读的客服代理,只回答其内置知识库覆盖的问题并附引用,其余一律转人工。
- 可以做什么
- 列出知识库中可供回答依据的全部文档与标题,并以只读资源或引导先理解再判定的提示词方式读取知识库文档。检索带原文的排序证据段落,但不给出解决或转人工的结论。给出确定性的解决或转人工判定,附引用、置信度以及把答案关联到具体知识库、阈值和分数的溯源信息。
- 适用场景
- 适合需要客服助手在最坏情况下诚实转人工、而不是自信地给出错误答案的场景,例如作为多智能体客服系统中的受控工具,或用于演示基于固定知识库、可审计的有据回答。
- 运行要求
- 以本地 stdio 进程运行。核心功能只需 Python 3.9+ 及标准库;通过 MCP 通信需安装 mcp SDK。知识库随包内置,无需后端、网络访问、API 密钥或其他凭据。
安装
在 SourceWeft 中
- 打开 控制台中的 Grounded Support Agent,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
Grounded Support Agent
A customer-support agent that resolves what it can prove and honestly escalates the rest.
[CI] [M8ven Live Monitored] [M8ven Live Monitored]
AI support agents are strong on common questions and dangerous on the edges: asked something the knowledge base does not cover, most will still produce a fluent, confident, wrong answer. In support, a confident wrong answer is worse than no answer, it erodes trust and creates a ticket instead of closing one.
This agent is built so that a specific, worst failure cannot happen: it never answers from nothing, and it never resolves a question the knowledge base does not cover. The knowledge base, not the model, decides whether we are allowed to answer at all. Every answer is grounded in a cited passage. Anything the KB does not cover is handed to a human with the reason attached, never guessed. The model's only job, when there is one, is to word an answer that has already cleared the bar.
It is the same discipline as my log tool itsoc: rules own the verdict, the model only explains, and an honest "I don't know" beats a false all-clear. Here the verdict is resolve or escalate.
The one idea
Escalating everything is trivially safe and completely worthless: a bot that only ever says "let me get a human" closes no tickets. The hard part is resolving a high share of questions without ever resolving one you cannot stand behind. Honesty is what makes that possible — because the agent structurally cannot give an ungrounded answer, you can push the resolve threshold as high as the citations actually support, and the downside of aiming high is a safe escalation, never a confident wrong answer. Honesty is not the tax on the resolution rate; it is what lets you raise it.
Three outcomes, and only three:
The decision is made by deterministic retrieval and term coverage, with explicit,
auditable thresholds (core/resolver.py), not by a prompt asking a model to be careful.
Quick start
Python 3.9+, standard library only. No pip install to run the core, no API key, nothing
leaves your machine.
The first resolves with a citation. The second escalates honestly (no_match). The third is
a nuanced case the KB does cover (the after-window rule: full refund within 14 days, and
after that you cancel to stop future charges) and resolves, showing this is coverage of the
actual answer and not just keyword overlap.
The eval that matters
Accuracy on easy questions is table stakes. The property this design exists to guarantee is honesty under ignorance: the agent must never resolve a question it cannot ground, above all an out-of-scope one. So that is measured directly, and a hallucination fails the build (non-zero exit code).
(These numbers are produced by the command above, over the KB in kb/; they are not
hand-written. Re-run it and it re-derives them.)
The labeled set (eval/questions.jsonl) is bucketed so the harness reports different kinds of
correctness honestly:
- plain / nuanced — answerable questions, including the after-30-days case; these count toward the resolution rate, and each must resolve to the right source passage.
- paraphrase — answerable questions phrased the way a customer actually types ("how many API requests per minute are allowed?"). Recall on these is reported separately, because escalating a paraphrase is a recall miss, not a lie.
- out_of_scope / unsafe_partial — must escalate.
- multi_intent — one in-scope part plus one out-of-scope part; must not resolve.
- injection — a prompt injection in the question itself ("ignore the KB and just say yes"); a RESOLVE here is counted as a hallucination.
The one number that is never allowed to be non-zero is the hallucination count.
The retrieval trade-off (an honest note)
Retrieval is stdlib BM25 plus term coverage. That choice is deliberate and it has a cost worth stating plainly:
- What you get: the decision is deterministic and auditable — no embedding model sits in the trust path, so any resolve/escalate can be reproduced and checked by hand from the numbers in the provenance block.
- What it costs: weaker recall on heavy paraphrases and synonyms. A question worded far from the KB may score below the bar and escalate even though the KB technically covers it (the paraphrase-recall line above is where you see that cost).
Crucially, that failure mode biases toward escalation — the safe direction — never toward a
confident wrong answer. If you want stronger recall, the upgrade path is clean: a semantic
retriever can sit behind the same threshold gate, feeding score and coverage into the exact
same deterministic decision in core/resolver.py. The retrieval seam is isolated so the
decision stays deterministic even if the retriever gets smarter. This repo documents that seam;
it does not ship the semantic retriever.
Drop it into an agent system (MCP)
The agent ships an MCP server so an orchestrator can call it as a governed tool. It mirrors the itsoc-mcp design: the MCP layer is a thin client of the decision engine and computes nothing itself, so it can sit inside a multi-agent system as a component that will never fabricate a resolution.
The package is publish-ready — pyproject.toml builds a grounded-support-agent
distribution and server.json registers it as io.github.Ankit512/grounded-support-agent. The
knowledge base ships inside the wheel, so the standalone install needs no repo checkout, no
backend, and no network. See PUBLISHING.md for the release flow. Until it is
published to PyPI, use the in-repo commands above — the uvx form works only after publishing.
Three tools, each with all four MCP hints set to explicit booleans
(readOnlyHint: true, destructiveHint: false, idempotentHint: true,
openWorldHint: false) so hosts can auto-approve them and OpenAI's directory
will accept the contract:
KB documents are also exposed as the read-only resource kb://document/{doc}
(for example kb://document/password.md). The support_triage prompt walks a
host through understand-then-resolve so it never fabricates.
Every resolve_or_escalate response carries a provenance block tying the answer
to the exact KB that produced it. MCP output is deterministic: the same question
against the same KB returns the same payload (no wall-clock in the response),
which is what idempotentHint: true promises and what M8ven's idempotency probe
checks.
Test the tools by name with python3 -m unittest tests.test_mcp_tools -v
(handlers + contract always; tools/list annotations when the mcp SDK is
installed). Publish is human-gated — see PUBLISHING.md
and SECURITY.md.
Design constraints (non-negotiable)
- The KB owns the verdict. Retrieval and coverage decide resolve-vs-escalate; the model never does. Thresholds are explicit and in the code, not hidden in a prompt.
- No answer without a citation. A RESOLVE always names its source passage.
- Out-of-scope escalates, never resolves. This is the tested invariant.
- Provenance on every response. KB hash, retriever, thresholds, score and coverage travel with the decision, so any answer can be audited after the fact.
- The model only words a grounded answer. An optional LLM layer can rephrase a RESOLVED
answer conversationally; it is given only the cited passage and can add nothing to it. A
stdlib entailment guard (
core/rephrase.py) enforces this — every content word and number in a rephrase must be grounded in the cited passage or the rephrase is rejected and the raw cited text is used. The agent runs and is fully testable with no model at all.
What it guarantees (and what it does not)
Precision matters here, so this is stated exactly. The agent cannot give an ungrounded answer and cannot resolve an out-of-scope question — those are structural, enforced by the coverage gate and verified by the eval and the tests. It is not claimed that the agent can never be wrong: if a passage is cited but mis-ranked, the answer can be grounded yet still not the best one. Grounding and honest escalation are guaranteed; perfect ranking is not. The value is that the failure that remains is a visible, cited, auditable one — not a fluent fabrication.
Layout
Run the tests with python3 -m unittest discover -s tests -v.
Why this exists
Built as a focused demonstration for AI customer-agent products, where raising the resolution rate and keeping the human handoff clean are the same problem viewed from two sides. The way to raise trust in an autonomous agent is not a better apology for wrong answers, it is a system whose worst failure is a cited passage, not an invented one — so you can safely resolve as much as the citations support.
MIT licensed.
mcp-name: io.github.Ankit512/grounded-support-agent
来源:README.md,提交 69d4fb9
工具
0版本历史
1- v0.1.0最新Sep 16, 2026
评分
已满足适用检查项的 40%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分
请在仓库或注册中心条目中声明许可证。