AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻譯準備中
AI systems engineer who designs and ships production AI end to end - RAG pipelines, agentic assistants, measured retrieval quality, and multi-provider LLM infrastructure, with hands-on QLoRA fine-tuni
翻譯準備中
開發工具Python · TypeScriptGitHub @architecture-zero上線中營運者未確認
試用過了嗎? 點一下就好,不需要登入。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證A self-hosted AI assistant platform where trust is measured, not claimed - hybrid retrieval behind a reranker seam, clearance enforced identically at four surfaces including both sides of the federation seam, an ingest-time injection gate, and judged evals published live on a trust panel.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A self-hosted AI assistant platform where trust is measured, not claimed.
Most "AI systems" are a text box, an API key, and a prompt. This is the
rest: hybrid retrieval with a cross-encoder reranker behind a swappable
provider seam, tiered access control enforced at four surfaces, an
ingest-time injection gate that quarantines hostile content before it can
reach an answer, and a judged evaluation harness that scores the system's
correctness, groundedness, freshness, and honesty - then publishes those
numbers on a public trust panel derived live from stored runs.檢視完整 README ↗A self-hosted AI assistant platform where trust is measured, not claimed.
Most "AI systems" are a text box, an API key, and a prompt. This is the rest: hybrid retrieval with a cross-encoder reranker behind a swappable provider seam, tiered access control enforced at four surfaces, an ingest-time injection gate that quarantines hostile content before it can reach an answer, and a judged evaluation harness that scores the system's correctness, groundedness, freshness, and honesty - then publishes those numbers on a public trust panel derived live from stored runs. If a number is on the panel, a run produced it; nothing is hand-set.
Every piece here shipped somewhere real first. The platform is derived from the shared core of production instances that have been running, measured, and incident-hardened - the code carries those lessons as working constraints, not war stories. Nothing in this repository is aspirational.
Prerequisites: Docker with the compose plugin, and an
Ollama install on the host with the embedding model
pulled (ollama pull nomic-embed-text) plus a chat model if you want local
inference (ollama pull qwen3:8b). On a Linux host, make Ollama listen
beyond loopback - its service binds 127.0.0.1 by default, and the
containers reach the host through the docker bridge address, so a stock
install is unreachable from them until it listens on all interfaces:
sudo systemctl edit ollama # add: [Service] Environment="OLLAMA_HOST=0.0.0.0"
sudo systemctl restart ollama
(Docker Desktop on macOS and Windows does not need this. Port 11434 stays closed at your firewall; this only changes which local interfaces answer.)
The embedder is required whichever provider answers chat. Only the chat
model is swappable for a cloud API; embeddings speak the Ollama dialect to
EMBED_BASE and have no provider seam. With nothing reachable there the
instance still boots, ingestion fails per file, and any question asked with
retrieval on - the default - returns a 500 rather than an answer. /api/health
reads only the self-check's last pass against the chat endpoint (it calls nothing
itself), so it reports healthy throughout. /api/health/ready is the check that
sees it: while the instance has documents to serve (the shipped knowledge/
folder counts), its retrieval-lane check embeds a fixed sentence through
EMBED_BASE, at boot and on every pass, and readiness answers 503 while that
fails.
git clone https://github.com/architecture-zero/architecture-zero
cd architecture-zero
cp .env.example .env # set JWT_SECRET_KEY - the backend refuses to boot on the placeholder
docker compose up -d --build
Create the Owner account and ask your first question. Claiming a deployment
takes a code that the backend prints to its own logs at boot - docker compose logs backend - so a deployment that is reachable before you finish setup
cannot be taken by whoever gets there first:
docker compose logs backend | grep -A2 "claim code"
Then open http://localhost:5173 - a fresh deployment routes straight to the claim screen. Paste the code, pick a username and password, and you are signed in as the Owner.
Or claim it from the API instead, which is the same endpoint the screen calls:
curl -X POST localhost:8000/api/auth/setup -H "Content-Type: application/json" \
-d '{"username":"owner","password":"<strong password>","claim_code":"<from the logs>"}'
Your first question needs no documents of your own: the instance boots already knowing itself (see the built-in onboarding assistant), and the runbook's deploy steps end with the exact call to make.
The platform is API-first: everything - chat (streaming SSE at /api/chat),
ingestion, users, evals, the trust panel - is served over a documented HTTP
surface, so any client works. A reference web client ships with it
(frontend/): chat with citations, the claim screen, and an admin panel
covering the trust panel, knowledge base, quarantine review, users, the
system prompt, chat controls, guest access, settings, models, audit,
monitoring, backup and the ingest queue. It is a reference, not a
requirement - the API is the product, and the client is one consumer of it.
Full walkthrough: docs/runbook.md.
Architecture Zero does not just ship with documentation - the assistant is its own support channel, pre-loaded with its own manual. The shipped corpus is the product's documentation: a getting-started guide, an operations troubleshooting guide keyed to the exact error strings the code emits (paste the error, retrieve its explanation), the security model, and a guide to what the evaluation numbers mean - plus a synthetic demo company so departments, tiers, and history routing demonstrate without anyone's real data. All of it ingests automatically on first boot.
So the moment the Owner account exists, you can ask the instance itself -
"how do I add my first documents?", "why was my upload withheld?", "what
does the recall number mean?" - and get a cited answer from its own
corpus - retrieval is on by default, so a plain request is already
grounded (send "use_rag": false to ask without the corpus). The shipped
evaluation seed asks the same class of support questions, so the first run
scores how well the instance onboards its own operator - support quality
as a measured number from day one.
The assistant also answers from the instance itself, not only from documentation. "What does the ingestion injection scan do?" is a documentation question; "is the scan actually on, on this instance, right now?" is answered from records generated at boot from the live database and ranked above everything else in the context. Those records are Owner clearance, so lower tiers still use the posture surfaces (GET /api/status, and the public trust panel at GET /api/trust). The records carry no document names, no account names, and nothing a user typed - only values the code produced or that passed an allowlist.
That starter corpus is the operator's to replace, and once it is gone
nothing in it answers "how do I sign in?" for the people who use the
instance. So the product also carries its own help: five short pages for
week one - signing in, how answers work, documents and who can see them,
data and privacy, a map of the admin panel - shipped inside the backend
image and synced at boot into a reserved collection that is never a
department. The Help button on the chat shell asks those pages alone: a
help question is never answered from your documents, a normal question is
never answered from a help page, and the pages never appear in the
Knowledge Base tab, the document count or the evaluation fingerprint.
HELP_DOCS=false turns the lane off.
There is no SDK - the platform's own seams are the developer surface:
Commercial modules exist for the enterprise edges (data connectors with permission-aware sync, SSO), built on this same core in a separate product - see MODULES.md for the honest map of what exists beyond the core and how modules graduate into it.
backend/app/ - the platform (FastAPI)backend/tests/ - the suite CI runs on every push and on the daily schedulebackend/scripts/ - the measurement harness (retrieval A/B arms, noise
bands, answer-layer runs, outside-model holdout authoring, the live-fire
injection probe)frontend/ - the reference web client (React + Vite, served by nginx)scripts/acceptance.sh - end-to-end check against a RUNNING deploymentknowledge/ - the shipped corpus (help docs + demo company)docs/ - operator docs, ingested as corpusdocker-compose.yml, backend/Dockerfile, frontend/Dockerfile - the
single-VM shapepython -m venv .venv
.venv/bin/pip install -r backend/requirements-dev.txt # Windows: .venv\Scripts\pip
cd backend && ../.venv/bin/python -m pytest tests -q # Windows: ..\.venv\Scripts\python
The suite mocks the vector store and embedder: no network, no keys, no GPU.
The client, in a container - this works everywhere, including on machines whose OS refuses to load unsigned native modules (see below):
cd frontend
docker run --rm -v "$PWD:/app" -v /app/node_modules -w /app node:24-alpine \
sh -c "npm ci && npm run type-check && npm test && npm run build"
Or on the host, if you have Node 24+ and your OS allows it:
cd frontend && npm install
npm run type-check && npm test && npm run build
npm run dev # see the note below before using this
npm run dev proxies /api to http://backend:8000 - the compose service
name, which resolves only inside the compose network. Running it on the host
against the stock deployment, the page loads and every API call fails to
resolve: point vite.config.ts at http://localhost:8000 first, and expect
vite to pick a different port since compose already holds 5173.
On Windows, the host path may not work at all, and the error will not tell
you why. Smart App Control (on by default on many Windows 11 installs) and
corporate WDAC policies block unsigned native binaries, and npm ships native
modules unsigned as a matter of course - so vite cannot load its own rollup
binary. Every one of npm run dev, npm test and npm run build fails; only
npm run type-check still works, since TypeScript is pure JavaScript. Use the
container command above. Nothing about deploying is affected: docker compose up --build builds the client inside Linux, where the policy does not apply.
CI runs both suites plus a full-history secret scan, a private-residue guard (a denylist grep that fails the build if lineage from the private deployments this template descends from appears in the tree), dependency and static-analysis scanning (pip-audit, bandit, trivy), and both Docker image builds on every push to main. The scanning jobs and the backend suite also run daily, because the two things they catch - a new CVE filed against a pin that has not moved, and a guard that quietly stopped holding - both arrive without a commit. Findings that cannot be fixed are not silently muted: every entry in the pip-audit ignore list carries its reasoning, what the ignore rests on, and what would retire it.
Stated here rather than discovered later. Each is tracked in ROADMAP.md.
frontend/src/sessionRefresh.ts, installed before the first render) - one
refresh and one replay on a 401, one refresh at a time across tabs under a
Web Lock, the refresh token sent only to the page's own origin or the
configured API base. It has its own tests. The banner still appears when a
refresh is refused, which is the only case where a session is really lost.ClosingStreamingResponse
(backend/app/closing_stream.py), which closes the generator as soon as the
response is over, and holds the provider stream in closing(), so the close
reaches the provider's connection. Its tests drop a real connection
mid-answer (backend/tests/test_stream_close.py)./metrics needs METRICS_TOKEN for a scraper. A user session expires
faster than a scrape interval matters, so set the static token if you want
Prometheus to pull. Unset, the endpoint is still reachable with a signed-in
request that holds view_analytics (the Owner, or the Admin preset).