{"id":45645859,"url":"https://github.com/schwichtgit/ai-resume","last_synced_at":"2026-04-02T13:31:43.209Z","repository":{"id":335692724,"uuid":"1146732000","full_name":"schwichtgit/ai-resume","owner":"schwichtgit","description":"AI-Resume is a containerized web application that acts as your digital professional proxy. Transform your CV into a conversational agent.","archived":false,"fork":false,"pushed_at":"2026-02-20T21:55:57.000Z","size":2471,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-20T21:59:13.828Z","etag":null,"topics":["ai-agent","architecture-example","containerized","cross-encoder","fastapi","grpc","hiring-tools","hybrid-search","memvid","multi-domain","openrouter","portfolio-project","production-ready","rag","recruitment-tech","reference-implementation","rust","self-hosted","semantic-search","vector-database"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/schwichtgit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-31T15:36:02.000Z","updated_at":"2026-02-13T05:54:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/schwichtgit/ai-resume","commit_stats":null,"previous_names":["schwichtgit/ai-resume"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/schwichtgit/ai-resume","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schwichtgit%2Fai-resume","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schwichtgit%2Fai-resume/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schwichtgit%2Fai-resume/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schwichtgit%2Fai-resume/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schwichtgit","download_url":"https://codeload.github.com/schwichtgit/ai-resume/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schwichtgit%2Fai-resume/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29771038,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T04:01:02.180Z","status":"ssl_error","status_checked_at":"2026-02-24T03:59:49.901Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","architecture-example","containerized","cross-encoder","fastapi","grpc","hiring-tools","hybrid-search","memvid","multi-domain","openrouter","portfolio-project","production-ready","rag","recruitment-tech","reference-implementation","rust","self-hosted","semantic-search","vector-database"],"created_at":"2026-02-24T04:00:56.628Z","updated_at":"2026-03-16T02:09:32.871Z","avatar_url":"https://github.com/schwichtgit.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![AI Resume Screenshot](frontend/public/ai-resume.png)\n\n# AI Resume Agent\n\n**Turn a static resume into an AI-powered conversation.**\n\nTypeScript (React 19) | Python 3.12 (FastAPI) | Rust (memvid gRPC)\n\nAI-Resume is a containerized web application that acts as your digital professional proxy. It provides a \"30-second scan\" layout for speed, backed by a semantic AI agent that recruiters can \"interview\" in real-time. Using natural language, they can query specific experience (e.g., \"How has she handled MLOps at scale?\") and receive a synthesized, evidence-based summary derived from your personal semantic knowledge base.\n\n\u003chttps://github.com/user-attachments/assets/0b183e42-db28-4ac0-ad22-8cd66d68308c\u003e\n\n\u003e _A recruiter asks about AI experience, tests job fit with a real job description, and explores leadership style -- all without scheduling a call._\n\n## Live Demo\n\nTry it with a fictional candidate: **[jane-doe-ai-resume.schwichtenberg.us](https://jane-doe-ai-resume.schwichtenberg.us/)**\n\nSuggested things to try:\n\n- Ask about specific skills or experience\n- Paste a real job description into the Fit Assessment tab\n- Ask a question the resume can't answer (watch the honest response)\n\n## Who Is This For?\n\n| You are a...                   | What you get                                                                                                                                                                   |\n| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| **Resume Owner**               | Deploy your resume as an always-available AI agent. Visitors get thoughtful answers about your experience without you being in the room.                                       |\n| **Recruiter / Hiring Manager** | Instant, detailed answers about a candidate. Ask about specific skills, experience depth, or job fit. No more scanning PDFs or scheduling screening calls.                     |\n| **Engineer / Architect**       | A reference implementation of a production RAG system: Rust gRPC service, Python FastAPI, React frontend, semantic search with cross-encoder re-ranking, container deployment. |\n\n## Architecture Overview\n\n```text\nmaster_resume.md        Python ingest         .mv2 file          Rust gRPC        Python API       React SPA\n(your resume)     ---\u003e  (chunk + embed)  ---\u003e (vector DB)   ---\u003e (search)    ---\u003e  (LLM + SSE) ---\u003e (chat UI)\n                                                                  \u003c5ms              streaming        responsive\n```\n\nAll content comes from a single Markdown file with YAML frontmatter. No hardcoded data in the frontend -- everything flows through the API from the `.mv2` vector database.\n\nFour services behind a reverse proxy:\n\n| Service            | Stack                                                | Role                                                    |\n| ------------------ | ---------------------------------------------------- | ------------------------------------------------------- |\n| **frontend**       | React 19, TypeScript, Vite 8, Tailwind v4, shadcn/ui | Chat UI, experience cards, fit assessment               |\n| **api-service**    | Python, FastAPI, OpenRouter                          | LLM orchestration, fit assessment, SSE streaming        |\n| **memvid-service** | Rust, Tonic gRPC, memvid-core                        | Semantic search, state lookup, Ask mode with re-ranking |\n| **ingest**         | Python, memvid-sdk                                   | One-shot pipeline: parse resume markdown into .mv2      |\n\nKey technical decisions:\n\n- **Hybrid search**: BM25 lexical + vector semantic + cross-encoder re-ranking (Reciprocal Rank Fusion)\n- **Honest by design**: System prompts enforce factual grounding; guardrails block prompt injection\n- **Single-file portability**: One `.mv2` file contains all embeddings, metadata, and profile data\n- **Read-only containers**: All services run rootless with read-only filesystems\n\nSee [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full system design, data flow, and network topology. The system includes end-to-end distributed tracing with OpenTelemetry across all three languages, a Grafana/Tempo/Prometheus/Loki observability stack, and pre-built dashboards for request waterfalls, latency breakdowns, and LLM cost tracking -- see [docs/OBSERVABILITY.md](docs/OBSERVABILITY.md).\n\n## What It Does\n\n**AI Chat** -- Ask anything about the candidate's background. The agent retrieves relevant resume context via hybrid search (BM25 + vector embeddings + cross-encoder re-ranking) and generates grounded, citation-backed answers. It will not hallucinate or make things up. Users can rate responses with thumbs up/down feedback.\n\n**Fit Assessment** -- Paste a real job description and get an honest analysis: key matches, gaps, and a recommendation. Pre-analyzed examples show strong and weak fit scenarios so you know what calibrated output looks like.\n\n**Experience Cards** -- Structured view of roles, projects, and skills loaded dynamically from a single portable data file.\n\n**MCP Server** -- Exposes the resume agent as an MCP-compatible tool server. Connect from Claude Desktop, Cursor, or any MCP client to query the candidate's experience programmatically.\n\n## Prerequisites\n\n| Tool    | Minimum | Required For                         |\n| ------- | ------- | ------------------------------------ |\n| Node.js | 22.14.0 | Frontend build and dev server        |\n| uv      | 0.9.0   | Python package management            |\n| go-task | 3.48.0  | Build orchestration (`task` CLI)     |\n| Rust    | 1.93.0  | memvid-service only                  |\n| podman  | 5.8.0   | Container builds and deployment only |\n\nPython is not a global prerequisite. `uv` manages per-service virtual environments and pins the Python version in each service's `pyproject.toml`.\n\nVerify all tools are installed and meet minimum versions:\n\n```bash\ntask deps\n```\n\nSee [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for the full tiered prerequisite list.\n\n## Quick Start\n\n```bash\n# 0. Bootstrap dev environment (npm deps, Python venvs, Rust crates, git hooks)\ntask setup\n\n# 1. Create your resume\ncp data/example_resume.md data/master_resume.md\n# Edit with your information (see data/example_resume.md for the schema)\n\n# 2. Ingest into vector database\ncd ingest \u0026\u0026 uv run python ingest.py --verify\n\n# 3. Run the full stack (three terminals)\ntask dev:memvid      # Terminal 1 -- Rust gRPC service (port 50051)\ntask dev:api         # Terminal 2 -- Python FastAPI (port 3000)\ntask dev:frontend    # Terminal 3 -- Vite dev server (port 8080)\n```\n\nPrint these dev instructions any time with `task dev`.\n\n## Build System\n\nThe project uses [go-task](https://taskfile.dev) as the build orchestrator for the entire monorepo. A root `Taskfile.yml` includes per-service taskfiles. Run `task --list` for every available target.\n\nKey commands:\n\n```bash\ntask setup           # Bootstrap full dev environment\ntask deps            # Check tool dependencies\ntask lint            # Lint all services (ESLint, ruff, clippy, markdownlint)\ntask test            # Test all services\ntask build           # Build all services (production)\ntask check           # Full quality sweep: lint + typecheck + test + build\ntask ci              # Reproduce CI pipeline locally\ntask container:build # Build all container images\ntask clean           # Remove build artifacts\n```\n\nPer-service targets are namespaced: `task frontend:test`, `task api:lint`, `task memvid:build:release`, `task ingest:test:coverage`.\n\nSee [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for the complete build system reference, per-service commands, testing, and coverage thresholds.\n\n## API Endpoints\n\n| Method | Path                                 | Description                                           |\n| ------ | ------------------------------------ | ----------------------------------------------------- |\n| GET    | `/health`                            | Health check (root-level alias)                       |\n| GET    | `/api/v1/health`                     | Health check with dependency status                   |\n| POST   | `/api/v1/chat`                       | AI chat with semantic search (supports SSE streaming) |\n| GET    | `/api/v1/profile`                    | Profile metadata from memvid                          |\n| GET    | `/api/v1/suggested-questions`        | Suggested chat questions from profile                 |\n| POST   | `/api/v1/assess-fit`                 | Real-time job fit assessment via AI                   |\n| POST   | `/api/v1/chat/{session_id}/feedback` | Submit thumbs up/down feedback on responses           |\n| POST   | `/api/v1/session/{session_id}/clear` | Clear conversation history for a session              |\n| DELETE | `/api/v1/sessions/{session_id}`      | Delete a chat session                                 |\n| GET    | `/api/v1/version`                    | Build version and commit SHA                          |\n| GET    | `/api/v1/mcp/config/{client_id}`     | MCP client configuration template                     |\n| --     | `/mcp`                               | MCP Streamable HTTP server (opt-out via env)          |\n| GET    | `/metrics`                           | Prometheus metrics (infrastructure)                   |\n\n## Deployment\n\nConfigure secrets and deploy with containers:\n\n```bash\n# Configure\ncp deployment/.env.example deployment/.env\n# Set OPENROUTER_API_KEY in deployment/.env\n\n# Build container images\ntask container:build\n\n# Deploy\ncd deployment \u0026\u0026 podman compose up -d\n```\n\nThe stack runs on both amd64 and arm64, including ARM64 edge devices (Raspberry Pi 4/5, NanoPi) with 4GB+ RAM. Each service enforces a 200MB memory limit.\n\nSee [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) for multi-arch builds, ARM64 edge deployment, compose configuration, and troubleshooting.\n\n## Project Structure\n\n```text\nai-resume/\n  frontend/           # React 19 + TypeScript + Vite + Tailwind + shadcn/ui\n  api-service/        # Python 3.12 FastAPI -- LLM orchestration, SSE streaming\n  memvid-service/     # Rust -- gRPC semantic search (\u003c5ms retrieval)\n  ingest/             # Python -- resume markdown -\u003e .mv2 vector database\n  deployment/         # Compose files, .env.example, deployment utilities\n  data/               # Resume source files and .mv2 output\n  proto/              # gRPC .proto definitions (shared)\n  scripts/            # Build, hook install, and utility scripts\n  ci/                 # CI gate principles (commit, PR, release)\n  docs/               # Architecture, deployment, security, development guides\n  Taskfile.yml        # Root build orchestrator (go-task)\n```\n\n## Documentation\n\n| Document                                                         | Description                                  |\n| ---------------------------------------------------------------- | -------------------------------------------- |\n| [Architecture](docs/ARCHITECTURE.md)                             | System design, data flow, network topology   |\n| [Deployment](docs/DEPLOYMENT.md)                                 | Container builds, ARM64 edge, compose config |\n| [Development](docs/DEVELOPMENT.md)                               | Build system, per-service commands, testing  |\n| [Observability](docs/OBSERVABILITY.md)                           | Distributed tracing, dashboards, runbooks    |\n| [Security](docs/SECURITY.md)                                     | Threat model, prompt injection, hardening    |\n| [Hook Exit Codes](docs/hook-exit-code-conventions.md)            | Claude Code hook exit code conventions       |\n| [Post-Edit Hook Antipattern](docs/post-edit-hook-antipattern.md) | Hook design guidance                         |\n\n## About This Project\n\nA reference project by [Frank Schwichtenberg](https://github.com/schwichtgit) -- built to solve a real problem (making resumes interactive) while demonstrating production engineering practices across the stack:\n\n- **Systems design**: Rust + Python hybrid architecture with gRPC boundaries\n- **Search and retrieval**: Semantic search, BM25, cross-encoder re-ranking, metadata filtering\n- **LLM engineering**: RAG pipeline, prompt design, guardrails, streaming responses\n- **Infrastructure**: Multi-arch containers, rootless deployment, read-only filesystems\n- **Security**: Prompt injection defense, rate limiting, input validation, container hardening\n\n## License\n\nPolyForm Noncommercial License 1.0.0 -- See [LICENSE](LICENSE) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschwichtgit%2Fai-resume","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschwichtgit%2Fai-resume","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschwichtgit%2Fai-resume/lists"}