AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
AI 시스템 엔지니어로 RAG 파이프라인·에이전트 어시스턴트·검색 품질·다중 제공자 LLM 인프라 설계·QLoRA 파인튜닝까지 전 과정 담당
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를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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).