Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# Tasks: Accelerate Embedding Similarity
|
||||
|
||||
> Change: `accelerate-embedding-similarity`
|
||||
>
|
||||
> Status: **Approved / Implemented**
|
||||
|
||||
## Overview
|
||||
|
||||
Reduce runtime of `find_matching_capacities(...)` by implementing:
|
||||
|
||||
- embedding text deduplication + **global** bulk prefetch (roles + competences for **all free capacities at once**, not person-by-person)
|
||||
- in-memory embedding memoization
|
||||
- true Azure embeddings batch requests with chunking
|
||||
|
||||
## Task Breakdown
|
||||
|
||||
### Phase 1: Design & Validation Plan
|
||||
|
||||
- [x] 1.1 Identify hot paths during matching (where `_embed(...)` is called most).
|
||||
- [x] 1.2 Confirm normalization + cache key rules are unchanged and documented.
|
||||
- [x] 1.3 Define expected call-count behavior (upper bounds):
|
||||
- per run: max 1 Azure embedding per unique normalized text (subject to chunking, after cache resolution)
|
||||
- per run: max 1 SQLite read per unique normalized text (after in-memory cache check)
|
||||
|
||||
### Phase 2: Global Bulk Prefetch in `SimilarityEngine`
|
||||
|
||||
- [x] 2.1 Add a new instance variable `_run_cache: dict[str, list[float]]` to `SimilarityEngine` (in-memory cache; **not** created/cleared per matching invocation).
|
||||
- [x] 2.2 Implement a public method `prefetch_embeddings(required_texts: list[str], candidate_texts: list[str], required_roles: list[str], candidate_roles: list[str]) -> dict[str, list[float]]`:
|
||||
- collect all input texts (required competences, **required roles**, all candidate competences, **all candidate roles**)
|
||||
- normalize + deduplicate using existing `_normalize_text()` logic
|
||||
- skip empty/whitespace-only texts
|
||||
- emit a **Python logger warning** if all candidate competences normalize to empty
|
||||
- [x] 2.3 Implement prefetch resolution logic:
|
||||
1) check in-memory cache (`_run_cache`)
|
||||
2) check SQLite embedding cache
|
||||
3) batch-request only cache-missing texts from Azure API (chunked by batch size)
|
||||
- [x] 2.4 Refactor `_per_skill_similarity` to use prefetched embeddings only (no embedding calls inside inner loops).
|
||||
- [x] 2.5 Refactor `_aggregate_similarity` to use prefetched embeddings only.
|
||||
- [x] 2.6 Ensure output format is unchanged and remains deterministic.
|
||||
|
||||
### Phase 3: In-memory Run Cache
|
||||
|
||||
- [x] 3.1 Verify `_run_cache` is an instance-level cache that does not require per-invocation clearing.
|
||||
- [x] 3.2 Add tests ensuring repeated embedding lookups for the same text:
|
||||
- are served from `_run_cache` after first lookup
|
||||
- do not call SQLite/API multiple times for the same text
|
||||
|
||||
### Phase 4: Azure Batch Embeddings Support
|
||||
|
||||
- [x] 4.1 Modify `AzureOpenAIClient.get_embeddings_batch()` to use Azure embeddings API with `input=[...]`.
|
||||
- [x] 4.2 Implement chunking using `azure_openai.embedding_batch_size` (default: 128, configurable, no enforced maximum).
|
||||
- [x] 4.3 Preserve ordering using `index` field in API response if available, otherwise assume stable ordering.
|
||||
- [x] 4.4 Ensure strict error semantics:
|
||||
- entire matching operation fails immediately on error
|
||||
- log the failing **chunk input list** via Python logging
|
||||
- [x] 4.5 Update `CostTracker` to log batch requests: log once per chunk with count of embeddings requested.
|
||||
|
||||
### Phase 5: Configuration
|
||||
|
||||
- [x] 5.1 Extend config model to include `azure_openai.embedding_batch_size` (integer, default: 128, no enforced maximum).
|
||||
- [x] 5.2 Update `config.toml.example` with the new setting and comments.
|
||||
- [x] 5.3 Ensure fallback: if `embedding_batch_size` is not specified in `config.toml`, use the default value (128).
|
||||
|
||||
### Phase 6: Tests
|
||||
|
||||
- [x] 6.1 Unit tests: global prefetch/dedup
|
||||
- verify dedup across required + all candidates (incl. roles)
|
||||
- verify embedding client is called once per unique normalized text (only for cache misses)
|
||||
- verify empty/whitespace-only texts are skipped
|
||||
- verify a Python logger warning is emitted when all candidate competences normalize to empty
|
||||
- [x] 6.2 Unit tests: cache layering
|
||||
- verify in-memory `_run_cache` prevents repeated SQLite reads within a run
|
||||
- verify SQLite hits prevent Azure calls
|
||||
- [x] 6.3 Unit tests: Azure batch request behavior (mocked)
|
||||
- verifies batch call for N texts when `N <= batch_size`
|
||||
- verifies chunking when `N > batch_size` (multiple batch calls)
|
||||
- verifies output ordering is stable (using `index` field or assuming stable order)
|
||||
- verifies strict error propagation
|
||||
- verifies the failing chunk input list is logged
|
||||
- verifies cost tracking logs once per chunk with count
|
||||
- [x] 6.4 Integration test (manual/gated only): real Azure batch embeddings
|
||||
- confirm request uses batch `input=[...]` semantics
|
||||
- ensure behavior matches expected semantics for a representative set of texts
|
||||
|
||||
### Phase 7: Documentation + Assistant Prompt Updates
|
||||
|
||||
- [x] 7.1 Update `README.md` to describe the optimization at a high level and mention the new batch size knob.
|
||||
- [x] 7.2 Update `docs/assistant_system_prompt.md` to reflect:
|
||||
- embeddings are prefetched globally per run
|
||||
- batching/chunking is used and configurable
|
||||
- failure semantics remain strict (no heuristics)
|
||||
- [x] 7.3 Update any Azure setup docs if needed (e.g., `docs/azure_openai_setup.md`) to mention embedding batch behavior and tuning.
|
||||
|
||||
### Phase 8: Quality Gates / Release Hygiene
|
||||
|
||||
- [x] 8.1 Run unit tests: `uv run pytest -m "not integration" -q`
|
||||
- [x] 8.2 Run Ruff and mypy via `uv`.
|
||||
- [ ] 8.3 (Manual/gated only) Run integration tests (Azure) to validate real batch calls.
|
||||
- [x] 8.4 Update change docs status/checklists and ensure OpenSpec validates (`openspec validate accelerate-embedding-similarity --strict`).
|
||||
|
||||
Reference in New Issue
Block a user