How Prompt Templates Are Structured in the Hiring-Agent Project
The hiring-agent project stores Jinja-style prompt templates as separate .jinja files under prompts/templates/ and uses a TemplateManager class to load, index, and render them with runtime variables.
The interviewstreet/hiring-agent repository separates prompt logic from application code by organizing LLM prompts as external template files. This architecture allows prompt engineers to modify instructions without touching Python source code, while the TemplateManager class handles the heavy lifting of template loading and variable substitution.
Template File Organization
All raw prompt texts live in the prompts/templates/ directory as individual .jinja files. Each file contains the exact prompt that will be sent to the LLM for a specific resume-section extraction task, using placeholders such as {{ text_content }} that are substituted at runtime.
The repository includes distinct templates for different resume sections:
basics.jinja– Extracts basic personal informationwork.jinja– Parses work experience entrieseducation.jinja– Handles education detailsskills.jinja– Extracts skill listsprojects.jinja– Processes project informationawards.jinja– Identifies awards and recognitions
The TemplateManager Class
Located in prompts/template_manager.py, the TemplateManager class abstracts the loading, indexing, and rendering of Jinja templates. It creates a Jinja Environment pointing at the template directory and maintains a private dictionary self._templates to store compiled Template objects.
Loading Mechanism
During initialization, the manager iterates over a hard-coded mapping of logical section names (e.g., basics, work, skills) to their corresponding filenames. It loads each file into the Jinja environment and stores the compiled templates in self._templates, making them available for rapid lookup by section name.
Rendering Interface
The render_template(section_name, **kwargs) method serves as the primary interface for consumers. It looks up the requested section in the internal dictionary, passes the supplied keyword arguments to Jinja's render method, and returns the final prompt string. If the template cannot be found, the method prints an error and returns None, allowing calling code to implement fallback behavior.
Practical Usage Examples
Instantiate the manager and list available sections:
from prompts.template_manager import TemplateManager
tm = TemplateManager() # defaults to "prompts/templates"
print(tm.get_available_sections()) # → ['basics', 'work', 'education', …]
Render the "basics" prompt with resume markdown content:
resume_md = "... (raw markdown) ..."
prompt_text = tm.render_template("basics", text_content=resume_md)
# `prompt_text` now holds the full Jinja-expanded prompt ready for the LLM.
Handle missing templates gracefully:
missing = tm.render_template("nonexistent")
# prints an error and returns None; you can fall back to a default behavior.
Use the rendered prompt in downstream LLM calls:
from llm_utils import call_llm # hypothetical helper
response = call_llm(prompt_text) # returns JSON with extracted basics
Summary
- Template storage: Prompts are stored as
.jinjafiles inprompts/templates/with placeholders like{{ text_content }}for dynamic content. - Manager implementation:
TemplateManagerinprompts/template_manager.pyinitializes a JinjaEnvironmentand indexes templates by section name inself._templates. - Rendering API: The
render_template(section_name, **kwargs)method handles variable substitution and returns the final prompt string, orNoneif the section is not found. - Architectural benefit: This three-layer design (filesystem → manager → consumer) keeps prompt content decoupled from core application logic, enabling independent prompt iteration.
Frequently Asked Questions
Where are the prompt template files located in the hiring-agent repository?
All Jinja template files reside in the prompts/templates/ directory. Individual files such as basics.jinja, work.jinja, and skills.jinja contain the raw prompt texts for different resume sections, each describing specific extraction instructions for the LLM.
How does TemplateManager handle missing template files?
If you call render_template() with a section name that does not exist in the hard-coded mapping, the method prints an error message and returns None. This allows consumer code in modules like prompt.py to detect the failure and implement appropriate fallback behavior.
What variables can be passed to render_template?
You can pass any keyword arguments that match the Jinja placeholders defined in the template files. The most commonly used variable is text_content, which typically contains the raw resume markdown to be processed, though additional context-specific variables may be defined per template.
Why does the project use Jinja templates instead of hard-coded strings?
Separating prompts into external Jinja files allows non-developers to modify LLM instructions without changing Python code, enables version control of prompts independently from application logic, and maintains a clean separation of concerns between prompt engineering and software implementation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →