# HR Productivity Environment — AgentX-AgentBeats ## Overview A fully-implemented HR simulation environment (OpenEnv-compliant) where an LLM agent serves as Chief Human Capital Officer (CHCO), managing a simulated company over 6 quarters. The agent uses Fitz-enz HR Analytics frameworks to optimize human capital metrics through strategic hiring, training, compensation, and retention decisions. ## Repository Structure ``` /tmp/autoresearch/ ├── hr_env/ │ └── server/ │ ├── environment.py # Main simulation loop (OpenEnv Environment) │ ├── company.py # Company + Department models (Cobb-Douglas production) │ ├── employee.py # Employee dataclass with lifecycle methods │ ├── metrics.py # Fitz-enz metrics: HCVA, HCROI, QIPS, Five Indexes │ ├── scoring.py # Reward computation + final score (normalized [0,1]) │ ├── phases.py # HCM:21 phase management (Scanning→Planning→Producing→Controlling) │ ├── events.py # Stochastic quarterly events (market, competitor, etc.) │ ├── data_gen.py # Synthetic company generation (Faker + numpy) │ └── app.py # OpenEnv server entrypoint ├── agent/ │ ├── hr_agent.py # Claude-based CHCO agent with phase-aware prompting │ ├── prompts.py # System prompt, phase prompts, summary prompts │ └── run.py # Agent runner script ├── tests/ # Test suite ├── openenv.yaml # OpenEnv configuration ├── pyproject.toml # Python project config (uv) └── Dockerfile # Container build ``` ## Development Commands ```bash # Install dependencies uv sync # Run tests uv run pytest tests/ -v # Start OpenEnv server uv run python -m hr_env.server.app # Run agent against server uv run python -m agent.run # Docker build docker build -t hr-productivity-env . ``` ## Architecture ### Simulation Engine - **Company Model**: 5 departments (Engineering, Sales, Operations, HR, Finance) with Cobb-Douglas production functions - **Employee Model**: 17 tracked attributes including performance, engagement, flight_risk, promotability - **Revenue**: `A * headcount^alpha * avg_skill^beta * engagement_mult * market_modifier` per department - **Turnover**: Stochastic based on flight_risk (logistic function of pay, engagement, tenure, market) ### Fitz-enz Metrics - **HCVA**: (Revenue - Non-Employment Costs) / FTE - **HCROI**: Revenue / Employment Cost - **QIPS**: Quality(0.25) + Innovation(0.25) + Productivity(0.30) + Service(0.20) - **Five Indexes**: Cost, Time, Quantity, Quality, Human Reactions (% change vs prior quarter) - **Employee Value**: avg(Productivity + Promotability + Transferability + Retainability) ### HCM:21 Phase System (per quarter) 1. **Scanning** (min 2 actions): query_department, query_employees, calculate_metric, review_financials 2. **Planning** (min 1): set_hiring_target, set_training_budget, set_compensation_policy, set_retention_program 3. **Producing** (min 1): execute_hiring, execute_promotion, execute_transfer, execute_training, execute_termination 4. **Controlling** (min 1): submit_report, calculate_metric → then advance_quarter ### Scoring - **Quarterly reward**: HCVA improvement (40%) + HCROI (20%) + QIPS (20%) + Five Indexes (20%) - **Final score** [0,1]: HCVA trajectory (25%) + HCROI improvement (20%) + Employee Value (20%) + QIPS consistency (15%) + Five Indexes cumulative (10%) + Financial health (10%) ### Stochastic Events MarketDownturn, CompetitorPoaching, ProductLaunch, ExecDeparture, MinWageIncrease, EmployerAward, BudgetCut, TrainingBreakthrough — each with independent probability per quarter, max 2 per quarter. ## Databricks Integration The simulation is adapted into a Databricks notebook (`/tmp/AimpointDigital/01_agentic_wikipedia_aimpoint_interview.ipynb`) with: - **Wikipedia knowledge layer**: HR theory articles (Fitz-enz, HCM, talent management) indexed into FAISS via BGE-Large embeddings - **LangGraph orchestration**: StateGraph with 5 nodes (initialize → agent_decide → execute_tools → check_done → summarize) - **RAG bridge**: `consult_hr_knowledge` tool lets the agent ground decisions in Wikipedia-sourced HR theory - **Databricks LLM**: `databricks-meta-llama-3-1-8b-instruct` for agent reasoning ## Key Conventions - Pydantic models for OpenEnv; plain dataclasses/dicts for Databricks adaptation - Phase-gated action space prevents random action sequences - Company generation uses Faker (names) + numpy (distributions) with deterministic seeds - Salary distributions: lognormal; tenure: exponential; engagement: beta(7,3) - Level distribution: pyramid [0.35, 0.30, 0.20, 0.10, 0.05] for levels 1-5 - Recruiting cost: $8,000/hire; Benefits: 30% of salary; Training: $50/hr/employee ## Databricks Deployment ### Workspace - **URL**: `https://dbc-c005fe3a-5584.cloud.databricks.com` - **Org ID**: `7474655330631867` - **Target Folder ID**: `1876640772048528` - **Folder URL**: `https://dbc-c005fe3a-5584.cloud.databricks.com/browse/folders/1876640772048528?o=7474655330631867` - **PAT**: (stored in env / .databrickscfg — not committed) - **User**: `n8.mauer@gmail.com` - **Edition**: Community Edition (Free) - **LLM endpoint**: `databricks-meta-llama-3-1-8b-instruct` - **Embedding endpoint**: `databricks-bge-large-en` ### .env file (for local development) ``` DATABRICKS_HOST=https://dbc-c005fe3a-5584.cloud.databricks.com DATABRICKS_TOKEN= DATABRICKS_ORG_ID=7474655330631867 ``` ### Cold-Start Setup 1. `pip install databricks-cli` 2. Write `~/.databrickscfg`: ```ini [DEFAULT] host = https://dbc-c005fe3a-5584.cloud.databricks.com token = ``` 3. Deploy notebook: ```bash databricks workspace import \ "/tmp/AimpointDigital/01_agentic_wikipedia_aimpoint_interview.ipynb" \ /Users/n8.mauer@gmail.com/01_agentic_wikipedia_aimpoint_interview \ --format JUPYTER --language PYTHON --overwrite ``` 4. Open workspace URL → attach cluster → Run All ### Deploy Script ```bash ./deploy.sh # from /tmp/AimpointDigital/ ``` ### Runtime Fixes Applied - **Rate limiting**: `agent_decide` LLM calls wrapped with `backoff.on_exception` (exponential, max 8 retries, 120s) + 1.5s proactive delay between calls. Community Edition has low QPS for foundation model endpoints. - **MLflow tracing**: `mlflow.langchain.autolog()` added at top of Cell A2 to enable tracing and suppress Databricks "Enhance GenAI observability" hint. `mlflow-skinny[databricks]` already in pip install cell. ### GitHub Repo - URL: `https://github.com/n8mauer/AimpointDigital` - Contains: notebook, build script, deploy script, README (runbook + talk track), assignment PDF ## TRL/GRPO Training (`notebooks/hcm21_trl_training.ipynb`) ### Architecture - **Model**: `unsloth/Qwen3-0.6B` with LoRA (r=16, 4-bit quantization) - **Method**: GRPO (Group Relative Policy Optimization) via TRL's `GRPOTrainer` - **Environment**: HCM:21 OpenEnv on HF Spaces (`https://paretooptimal-hcm21.hf.space`) - **Colab URL**: `https://colab.research.google.com/github/n8mauer/autoresearch/blob/main/notebooks/hcm21_trl_training.ipynb` ### GRPO Reward Strategy (JSON action parsing — no environment_factory) The model generates text completions containing JSON action objects (one per line). `reward_func` parses these with regex (`\{[^{}]*"action_type"[^{}]*\}`), executes them in a fresh `HCM21Env` instance, and returns the environment's final score. **Why not `environment_factory`?** - TRL's `environment_factory` exposes env methods as tools for tool-calling, but a 0.6B model can't reliably generate structured tool calls - `environment_factory` requires `transformers>=5.2.0` which conflicts with Unsloth patches - Disabling Qwen3 thinking mode via `chat_template.replace("enable_thinking", "")` may break tool-calling templates - Direct JSON parsing in `reward_func` is simpler, more robust, and works with Unsloth ### Key Implementation Details - `SYSTEM_PROMPT` instructs the model to output 20-40 JSON action objects covering 6 quarters - `reward_func(completions, **kwargs)` — no `environments` param (environments created internally) - `GRPOTrainer` has NO `environment_factory` argument - Evaluation (cell 20) generates one completion per seed, parses all actions, executes them - `tokenizer.apply_chat_template()` may return `BatchEncoding` — extract `.input_ids` before using `.shape` ### Training Config - `per_device_train_batch_size=2`, `gradient_accumulation_steps=4`, `num_generations=4` - `max_completion_length=2048`, `learning_rate=5e-6`, `fp16=True` - Dataset: 20 prompts with different episode seeds ### Verification Checklist After running in Colab, confirm: - `reward` column shows **non-zero values** - `reward_std` is **non-zero** (learning signal exists) - `Training Loss` is **non-zero** (GRPO has gradients) - Rewards trend upward over training steps