Preparation is a saved-job sub-resource. It does not predict an interview or generate complete model answers. It identifies high-value JD evidence gaps, retrieves a small number of learning resources for knowledge gaps, asks concrete questions, and turns user-reported answers into preparation actions.
The guided flow is:
Saved Job + Profile + latest analysis
-> classify skill evidence
-> ask at most five structured evidence questions
-> model proposes skill-specific options with backend-validated transitions
-> user selects the closest option or uses free text when no option fits
-> retrieve resources for at most three confirmed knowledge gaps
-> generate bounded preparation actions
Evidence is marked as supported, partial, unknown, or missing. Answers
submitted by the user remain user-reported evidence and do not silently alter
the resume profile. Candidate-facing labels and skill-specific decision
dimensions are generated by the model. The backend still owns the transition
vocabulary: professional work, project, practice/coursework, conceptual
understanding, no experience, or uncertain. Natural-language answers are
classified back into this vocabulary and never directly control graph state.
Preparation uses a LangGraph state graph for the human pause and resume
boundary. The graph checkpoints by preparation ID in a local SQLite database.
Closing with Save moves the workspace to paused; completing all guided
questions produces a summary; explicitly stopping ends without a summary.
Curated learning topics and official resources are stored in the local database and queried first. MCP is called only when a knowledge gap selected by the user needs learning material and the curated catalog is insufficient. Dynamically discovered links are returned as references and are not silently promoted to curated resources.
The business use case depends on a LearningResourceSearch interface. Set
JOBAGENT_LEARNING_MCP_URL to use a Streamable HTTP MCP server. Optional
configuration:
JOBAGENT_LEARNING_MCP_TOOL, defaultsearch;JOBAGENT_LEARNING_MCP_QUERY_ARGUMENT, defaultquery.
The client uses the stable MCP Python SDK v1, a 15-second HTTP timeout, bounded results, and HTTP(S)-only URLs. MCP errors do not block question generation. The official catalog covers common engineering topics plus physiological signal, PPG blood-pressure, and model-iteration starting points. Unknown topics remain without a link when search is unavailable rather than receiving a fabricated URL.
The repository includes a Tavily-backed server at
mcp_servers/learning_search. It loads TAVILY_API_KEY from the same local
.env.deepseek.local file as JobAgent and listens on
http://127.0.0.1:8001/mcp by default. Run it separately with:
python -m mcp_servers.learning_search.serverThe MCP boundary keeps the preparation use case independent from Tavily. Search results are references only: they do not modify the profile and are not treated as evidence of candidate ability.
Persona-centered evaluation can emit one Langfuse agent trace containing nested Kimi and DeepSeek generations. Each generation records provider usage, latency, retry stage, prompt version, and serialized sizes for the context layers. Prompt and response content are redacted by default.
JOBAGENT_LANGFUSE_ENABLED=true
JOBAGENT_LANGFUSE_CAPTURE_CONTENT=false
LANGFUSE_PUBLIC_KEY=...
LANGFUSE_SECRET_KEY=...
LANGFUSE_BASE_URL=https://your-langfuse-instance
Enable content capture only when that Langfuse deployment is approved to receive resume, job, and synthetic-persona content. Context-size metadata is sufficient for the default token-cost investigation.
The prompt TXT contains bounded job/profile context, current gaps, question IDs, and instructions that prohibit invented experience. An external chat returns:
{"answers": [{"question_id": "...", "answer": "..."}]}The frontend imports only IDs present in the current workspace. The user reviews the text before submission. Browser-side automatic login probing, message sending, and background chat capture are outside this version's privacy boundary.