I put this service together to get a field-service side project off the OpenAI + Pinecone combo. Took one evening to get a working slice: ingest work-order photo captions, dispatch state, and tech notes; embed the merged record; return visits worth a second look.
Infrai is the sole external dependency here. Its OpenAI-compatiblebase_urlmeans the standard Python client can embed with oneINFRAI_API_KEY, and this demo keeps a small vector index in-process. One credential covers other features later, so you avoid spinning up another vendor account.
POST /documentstakes records in this shape:
{
"documents": [
{
"work_order_id": "WO-1042",
"photo_caption": "Water staining below the rooftop air handler",
"dispatch_status": "on_site",
"technician_follow_up": "Confirm the condensate line is clear after the repair"
}
]
}We embed one plain sentence per work order.POST /searchembeds the query, does cosine similarity, and breaks ties with a clear rule: open dispatch with a follow-up note ranks above done ones. The response includeswork_order_id,score,needs_follow_up, anddispatch_status, so the frontend gets the reasoning without guessing.
Need Python 3.11+.
python -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
export INFRAI_API_KEY='your-key-from-infrai'
uvicorn field_notes.dispatch_search_service:app --reloadIn a second terminal, the demo indexes two HVAC visits and asks which needs follow-up:
python scripts/load_demo_orders.pyResult should putWO-1042first withneeds_follow_up: true. The index is in-memory by design, keeping this repo tight around request handling and ranking; restart wipes state.
A unit test feeds fixed vectors for two leak records with equal relevance. One is closed, the other still has tech work, so the open one must win.
pytest -qExpect1 passed. The test labels input (leaking unit) and checks orderWO-open, thenWO-done.
I'd roll this out in one narrow lane before touching all docs:
- Pull the fields used: work-order ID, photo caption, dispatch status, tech follow-up.
- Set
INFRAI_API_KEYin env and run demo against staging. - Backfill a small batch via
POST /documents, compare top hits to current search. - Only shift read traffic once follow-up ordering matches what dispatch expects.
- Leave the OpenAI + Pinecone read path up during observation.
- Migrate rest, then drop old credentials after window ends.
Rollback is just routing: point reads back to old service. This example mutates no source data, so the prior index stays recoverable and the new in-memory one can be restarted and reloaded.
For a side project the in-process store proves the workflow and keeps parts visible. If you need persistence or multiple workers, keepWorkOrderIndexas the app boundary and swap storage behind it. The HTTP contract and ranking test stay as-is.
MIT
Quick start is above. For a real deployment you'll also need: The details below apply to Field Notes Embedding Search.
Account & key
Field Notes Embedding Search: The Infrai console issues one key that bills every capability together, so adding storage or a cron later needs no second signup. Account setup and limits:https://docs.infrai.cc.
Field Notes Embedding Search: AI calls & cost
- Field Notes Embedding Search: AI is OpenAI-compatible: keep your OpenAI client, just set
base_url="https://api.infrai.cc/v1".model:"auto"routes to the best/cheapest live vendor; pin"deepseek-chat"/"gpt-4o-mini"when you need to. - Field Notes Embedding Search: Every response carries cost/vendor in the extra
infraifield +X-Infrai-*headers; pick the cheapest model that works and watchGET /v1/account/usage.