# Local document QA trial / 本地文档问答实验

Tested 2026-10-16. Windows 11, llama.cpp b11669 / commit 620d2225c (reports 0.7.0-dev), Qwen2.5-0.5B-Instruct Q4_0, CPU two threads, one parallel slot, context 4096. Requests: temperature 0, seed 42, maximum 180 output tokens. No cloud API, production account or real policy document.

Official runtime: https://github.com/ggml-org/llama.cpp/releases/tag/b11669
Official model: https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct-GGUF
Model filename: qwen2.5-0.5b-instruct-q4_0.gguf
SHA-256: 7671c0c304e6ce5a7fc577bcb12aba01e2c155cc2efd29b2213c95b18edaf6ed
Request documentation: https://github.com/ggml-org/llama.cpp/blob/620d2225c/tools/server/README.md

## Reproduction

1. Inspect fixtures.json and its five expected checks before reading results. Everything is synthetic English; credit amounts are not real financial advice.
2. In an isolated folder, obtain the pinned official CPU runtime and model. Check current licenses and compare the model hash. Do not run files from an arbitrary mirror.
3. Start the local server with `llama-server -m <model-file> -c 4096 -t 2 -np 1 --host 127.0.0.1 --port 3032 --api-key <your-local-test-key>`. Keep it loopback-only, use a temporary key and stop it after testing. The placeholder is not an actual credential.
4. POST to `/v1/chat/completions` with your local Bearer key. Each public record includes the actual system message, user message and responseFormat. Use the fixed settings above. Raw output and the application decision are separate fields.
5. For all-sources, include every fixture document. For controlled-sources and guarded-schema, select kind=policy, validFrom <= asOf <= validTo, and literal requiredTerm in the text. No candidates means an application refusal and no model call. Guarded-schema additionally supplies the recorded schema and sentence-copy instruction.
6. For controlled answers, verify source membership, an exact nonempty source substring as quote, and all answer numbers in that quote. A failure becomes unverified; do not replace it with the expected answer. These checks do not prove semantic entailment.
7. Repeat the same trial and keep both records. Temperature/seed are disclosed, not a guarantee of identical floating-point inference or wording. Stop the server and keep only synthetic outputs for sharing.

`matchesExpected` is a narrow deterministic fixture check, NOT editorial approval or population accuracy. For known answers it checks answered status, an expected answer token and the expected source ID; for unknowns it checks not_found. A blocked correct number does not count as a usable answer. The article separately inspects quotations and explains remaining uncertainty.

The guarded-schema receipt output in both trials omitted quote and returned a source object, contrary to the requested ID-or-null field. The application blocked it. This is an observed schema mismatch, not proof of successful enforcement; its runtime/configuration cause was not isolated. The current-cap quote did not support its number. No receipt quotation was invented or expanded: the required field was absent.

中文：此实验不是 AnythingLLM、Open WebUI 或 RAGFlow 部署测试，没有测文档解析、向量检索、权限或生产稳定性。来源规则来自自制代码，不是模型自带保护。第三轮票据回答没有遵守请求结构，缺少引文且来源返回对象；不能声称结构约束可靠生效。fixtures 与两份 trial 记录包含复现所需公开输入、参数与输出，但不包含密钥、权重或执行脚本。可以只下载并逐项核对，无需在自己的电脑上安装模型。
