Back to Featured Work
ProjectView UI

HR AI Chatbot Agent

Built the backend for a released HRIS agent (Mar 2025 - Present) that answers questions and performs real HR actions in conversation. Instead of hardcoding one endpoint per intent, the agent discovers the GraphQL schema at runtime through an introspect tool, then executes the operation it just learned - covering 48 read operations and 31 write operations across KPI, payroll, attendance, leave, ATS, and appraisal workflows.

Problem

HR workflows needed an agent that could act on real product data, not a chat wrapper that could only describe what a user should go and click.

  • A prompt-only assistant could answer questions but could not apply leave, create an appraisal, or record a promotion
  • Hardcoding one backend endpoint per intent would not scale across dozens of HR operations and would drift as the schema changed
  • Because the agent writes to live HR records, wrong or duplicated actions carry real payroll and compliance cost
Agent Architecture

A two-tool loop lets the agent learn an operation before it runs one, so backend capability is discovered at runtime rather than duplicated in agent code.

  • introspectTool reads the live GraphQL schema and returns the operation's arguments, types, and selectable fields
  • executeGraphQLTool then runs the operation the agent just learned, in-process against the same schema
  • A curated allow-list of 48 queries and 31 mutations bounds what the agent may reach, each carrying business-language guidance for the model
  • Two canvas tools render long-form output - contracts, policies, reports, CSV - into a document panel beside the chat instead of flooding the conversation
Introspect

The discovery half of the loop: the agent asks the schema what an operation looks like before attempting it, which removes guesswork about arguments and field names.

  • Walks the schema and renders arguments, return types, and nested fields as markdown the model can read
  • Recursion is bounded by a depth cap and a shared byte budget, so a deep type graph cannot blow the context window
  • Cycle detection tracks ancestor types so self-referencing schemas terminate instead of expanding forever
  • Truncation is explicit - the agent is told detail was withheld and can ask for a field by name, rather than silently seeing a partial schema
Execute

The action half of the loop: run the operation in-process, then normalize the result so the model reads success and failure the same way every time.

  • Executes against the agent GraphQL schema in-process, replacing the previous agent's HTTP round trip
  • Legacy resolvers return JSON-encoded strings for data and paginated items; these are recursively decoded so the model sees structured data
  • Every response is flattened to a consistent success / errorCode / errorMessage envelope, so GraphQL errors become something the agent can act on and retry
  • Runs behind schema-swap and auth middleware, so the agent resolves against the agent schema as the authenticated user
Guardrails

Most of the engineering went into constraining a model that can write to production HR data, encoded as prompt rules the tools enforce in practice.

  • Write-once discipline: a successful mutation is never re-run to confirm, since a null body is a valid success and a repeat call would duplicate the record
  • Leave correctness: booking leave and adjusting a balance are separate operations, and balance changes are deltas read from current state, never target values
  • Job changes route to an audit-trailed activity record rather than a silent profile edit, so promotions, transfers, and resignations stay traceable
  • System identifiers are tool-call-only and never surface in replies; salary data is exposed only when the user is explicitly asking about compensation
Impact

Shipped as a released feature backed by 25 test suites, letting the agent complete real multi-step HR work end to end instead of handing the user back a set of instructions.

  • Covers KPI, payroll, attendance, duty roster, leave, recruitment, and appraisal workflows through one discovery-driven interface
  • Adding a backend operation extends the agent through the allow-list, with no new agent code per capability
  • Runs on a 50-step tool loop with high reasoning effort, so multi-part requests resolve in a single turn
  • The same tool loop backs a scheduled background agent, reusing the architecture for unattended recurring HR tasks