Skip to main content

Build an AI Chief of Staff

An AI that doesn’t just answer questions - it takes action. Register every callable function in your workspace as a knowledge object in HydraDB. Any agent or user can say “prepare for tomorrow’s board meeting” and receive a structured, personalized execution plan: which functions to call, in which order, with which parameters. Every API call is real and copy-paste ready.
Most AI assistants are read-only. They answer questions, summarize documents, and draft emails. What they can’t do is act - book the meeting, update the CRM, send the Slack message, trigger the deployment. To cross that threshold, the agent needs to know not just what functions exist in your workspace, but which one to call for any given task, in what order, with what parameters, and for which user. This cookbook builds an AI Chief of Staff - an autonomous reasoning layer that turns natural language into structured function calls across every app in your stack. Think of it as n8n, but driven by intent rather than rigid if-then workflows. You register your callable functions into HydraDB as knowledge objects. Any agent then asks HydraDB: “What should I do for this task?” HydraDB returns the right function, the right parameters, and the right sequence - all personalized to the requesting user’s preferences and the current context. The architectural insight is separation of concerns: your primary LLM handles conversation and intent extraction, while HydraDB becomes the function selection oracle - a reasoning layer that has learned which functions work for which tasks, which sequences tend to succeed together, and how individual users prefer to work. Over time, it builds institutional knowledge that your agents can tap into. ℹ️
All code in this cookbook is real. Base URL: https://api.hydradb.com. Get your API key at app.hydradb.com.

Prerequisites

Required knowledge: Python basics, REST APIs, environment variables, basic understanding of OAuth
Required tools:
  • HydraDB API key
  • Python 3.11 or 3.12 (python --version)
  • OpenAI API key (for parameter extraction and plan sequencing)
  • pip install hydradb-sdk openai slack-sdk backoff

What You’ll Build

By the end of this cookbook, you’ll be able to:
  • Register any workspace function (Slack, Calendar, CRM, Jira) as a HydraDB knowledge object so agents can discover it semantically
  • Build an Orchestrator that translates a natural-language task into an authorized, token-injected API call
  • Generate multi-step execution plans for complex tasks like “onboard the new hire”
  • Store per-user preference memory so HydraDB personalizes function suggestions over time
  • Feed execution outcomes back into HydraDB to close the self-improvement loop
❌ // Traditional automation (n8n, Zapier, Make)
  • Rigid if-then workflows - break when conditions change
  • Every automation hardcoded - no personalization
  • No memory of past executions or user preferences
  • Requires manual mapping of triggers to actions
  • Context window resets on every run
✅ // HydraDB AI Chief of Staff
  • Intent-driven routing - adapts to how requests are phrased
  • Per-user personalization via AI Memories
  • Learns function composition patterns from execution history
  • One natural language request returns a full execution plan
  • Compound intelligence - every run makes future runs smarter

How HydraDB Enables This

Four HydraDB capabilities make a Chief of Staff possible:
  • Functions as knowledge objects - each callable function is uploaded to HydraDB via POST /ingestion/upload_knowledge with type: "function". The function’s natural-language description becomes the retrieval surface. HydraDB matches tasks to functions semantically - not by keyword - so “tell the team about the delay” correctly surfaces send_slack_announcement even though neither word appears in the function name.
  • Personalized function selection - when a user frequently chooses Slack over email for urgent updates, HydraDB’s AI Memories encode that preference. Future function suggestions for that user automatically favour send_slack_message over send_email. This happens without any manual configuration - the pattern emerges from usage stored via POST /memories/add_memory.
  • Multi-step plan generation - mode: "thinking" on POST /recall/full_recall enables multi-query reasoning. Ask HydraDB to return a JSON array of functions with dependencies and it decomposes a complex request like “onboard the new hire” into a sequenced execution plan automatically.
  • Self-improving function routing - feeding execution results back to HydraDB via POST /memories/add_memory closes the learning loop. Slow functions, failed calls, and successful sequences all become training signal. The agent gets measurably smarter with every run, without any manual tuning.

Architecture

One HydraDB tenant. Functions registered as knowledge objects. An Action Orchestrator that translates HydraDB suggestions into real API calls. Per-user memories that personalize every suggestion. The flow: a user or agent sends a natural-language task to the Action Orchestrator. The Orchestrator queries HydraDB, which matches the task semantically against registered function knowledge objects and returns a ranked suggestion. The Orchestrator executes the function via the real API, logs the result back to HydraDB as a memory, and the loop closes. Each execution makes the next suggestion smarter. ℹ️
The Orchestrator is thin by design. It has no opinion about which function to call - that decision belongs to HydraDB. The Orchestrator’s only job is: receive suggestion, authorize it against the policy engine, inject the correct OAuth token from the auth vault, call the real API, and report the outcome. All routing intelligence lives in HydraDB.
STEP 1

Create Tenant

One tenant for the whole Chief of Staff system. All functions, all user memories, and all execution history live under this tenant. Sub-tenants scope function access per team or department - the sales team’s agent only sees sales functions, the engineering team’s agent only sees deployment and monitoring functions. Install the Python packages used by the examples and set both API keys:
HydraDB handles retrieval and memory. The OpenAI SDK is used only in the app layer for turning retrieved function schemas into executable parameters and multi-step plans; you can replace it with any LLM provider.
setup.py
Output:
STEP 2

Define & Register Functions

Every action your Chief of Staff can take must be registered in HydraDB as a knowledge object. HydraDB treats each function as a document: its natural-language description is the retrieval surface, its schema is the execution contract, and its metadata controls who can access it and under what conditions. The quality of your function descriptions directly determines routing accuracy. Write descriptions that explain what the function achieves and when it should be used, not just what it does technically. HydraDB reasons over these descriptions during function selection.

Function schema

Each function schema has four components: id (stable identifier for versioning and logging), description (the natural-language surface HydraDB matches tasks against - write this carefully), parameters (JSON Schema for the execution contract), and meta (access control, constraints, and routing hints).
schemas/send_slack_message.json
💡
The description field is your routing budget. HydraDB matches tasks to functions by reading the description semantically. Include: (1) what the function achieves, not just what it does, (2) when it should be preferred over similar functions, and (3) any important constraints or side effects. A description like “Posts a Slack message” routes poorly. A description that explains “Use this for internal, time-sensitive, or informal communications - prefer over send_email” routes correctly even when the user says “ping the team”.
Here is a more complex schema - a finance function with approval constraints and metadata filters that prevent it from being suggested outside authorized contexts:
schemas/approve_expense.json

Upload to HydraDB

Upload functions using the same POST /ingestion/upload_knowledge endpoint used for documents. Set type: "function" and include the full JSON schema as the content body. Group functions into collections so HydraDB can scope retrieval per team without returning irrelevant options.
register/upload_functions.py
Output:
⚠️
Use team-scoped sub-tenants for precision. If your function library grows to 50+ functions, a single sub_tenant_id="functions" will degrade routing quality because HydraDB must rank more candidates per query. Instead, upload sales functions to sub_tenant_id="sales", engineering functions to sub_tenant_id="engineering", and so on. Agents query only their team’s sub-tenant. Fewer candidates = more accurate suggestions. Aim for fewer than 30 functions per sub-tenant for optimal routing.

Versioning & deprecation

As functions evolve, use a _v2 suffix on the ID for new versions. Mark deprecated versions in metadata so HydraDB stops routing to them while preserving historical execution records. Never delete old function objects - they anchor memory traces from past executions.
register/versioning.py
STEP 3

Build the Action Orchestrator

The Orchestrator is the runtime layer between HydraDB suggestions and real API calls. It receives a natural-language task, asks HydraDB which function solves it, authorizes the call against the policy engine, injects the correct OAuth token, executes the API, and logs the outcome back to HydraDB. It has no opinion about which function to call - that belongs to HydraDB entirely.

Core orchestrator class

orchestrator/core.py
Note: metadata_filters is available in the Python SDK but not yet reflected in the OpenAPI spec. It filters results by any metadata key-value pair before ranking - for example, {"deprecated": False} excludes deprecated function schemas from suggestions.

Function registry

The registry maps each function_id to the Python callable that makes the real API call. This is where OAuth tokens are consumed, retries happen, and real side effects occur. The Orchestrator passes params from HydraDB’s parameter extraction directly to the executor.
orchestrator/registry.py
💡
Start with read-only functions. Before enabling write actions, build confidence with read-only lookups: get_calendar_events, get_crm_opportunity, get_open_tickets. These validate HydraDB’s routing accuracy without side effects. Once routing is correct on reads, graduate to writes. The Chief of Staff earns trust incrementally - never by starting with “approve_expense”.

Result feedback loop

The feedback loop is what separates a static function router from a learning system. After every execution, write a structured memory to HydraDB with infer: true. HydraDB extracts: which function was chosen, whether it succeeded, and what the user was trying to do. Over time, these signals shift the function preference profile for each user, making suggestions increasingly accurate without any manual tuning.
orchestrator/feedback.py
STEP 4

Store Agent Memory

Two types of memory drive personalization. User preference memory stores how each person prefers to work - which channels they favour, which functions they trust, how they phrase requests. Execution outcome memory stores what happened when functions were called - successes, failures, latency patterns, user corrections. Together, these build a complete model of each user’s working style that HydraDB uses to shift function suggestion rankings on every recall.

User preference memory

Write explicit preference profiles during onboarding and update them whenever a user changes how they work. Use infer: true so HydraDB extracts the implicit signals - channel preferences, communication style, urgency thresholds - and builds graph connections to related functions automatically.
memory/user_preferences.py
Output:

Execution outcome memory

Beyond preferences, HydraDB needs to know what actually happened. Store each execution outcome as a memory with enough detail for HydraDB to identify patterns: which functions tend to succeed together, which fail under specific conditions, which are consistently slow. Use infer: false for exact outcome records and infer: true for synthesized pattern summaries.
memory/outcomes.py
STEP 5

Multi-Step Planning

Many real-world tasks require more than one function call. “Onboard the new hire” isn’t one action - it’s creating accounts, sending welcome materials, scheduling orientation, assigning equipment, and notifying the team. Instead of hardcoding this sequence, ask HydraDB to generate the plan. It returns a JSON array of functions with their parameters and dependency order. Your execution engine runs them sequentially, injecting earlier outputs into later calls. ℹ️
Use mode: "thinking" for plan generation. mode: "thinking" enables HydraDB’s multi-query decomposition - it breaks the task into sub-questions, matches each to a function, and assembles the ordered plan. mode: "fast" returns a single best-match function. Always use "thinking" when the task is complex or ambiguous. Plan generation typically takes 200–600ms.

Generate a plan

planning/generate_plan.py

Execute with dependency resolution

Run the plan in topological order: steps with no dependencies run first, then steps whose dependencies are complete. Pass outputs from earlier steps into later ones - the new hire’s account_id from step 1 flows into step 2’s Jira onboarding, their email flows into step 6’s welcome message.
planning/executor.py

Rollback & compensation

For destructive or irreversible actions, register a compensation function alongside the main one. If step n fails after steps 1–n-1 have completed, the compensation chain runs in reverse order to undo what it can. Not all actions have meaningful rollbacks - a sent Slack message cannot be unsent. Mark those as compensatable: false in their schema metadata.
planning/rollback.py
STEP 6

Event & Trigger Model

The Chief of Staff should react to three types of input: direct commands from users, scheduled jobs, and system events from external services. All three converge on the same Orchestrator.handle_task() call - only the source of the natural-language task differs. Flow: Direct command → Scheduled job → System event → Orchestrator → Execution

Slack slash-command (direct commands)

Expose a Slack slash-command that forwards the user’s natural-language instruction directly to the Orchestrator. The Slack user ID maps to the user_id used for memory recall, so HydraDB already knows this user’s preferences and personalizes the function suggestion accordingly.
triggers/slack_command.py

Scheduled jobs

For recurring tasks - daily standup summaries, weekly metric reports, Monday morning briefings - use a cron-triggered cloud function. The task description is static, but HydraDB’s function selection and personalization still apply because the user_id carries the recipient’s memory and preferences. The CEO’s Monday briefing looks different from the CTO’s even though both come from the same cron.
triggers/scheduled_jobs.py

System event webhooks

Monitoring alerts, new Jira tickets, CRM stage changes, and GitHub PR events all carry natural-language context when translated into task descriptions. A thin webhook handler converts each event into an actionable task description and routes it through the Orchestrator. HydraDB decides the appropriate response based on severity, time of day, and the team’s learned patterns.
triggers/webhooks.py
💡
The task description quality determines the response quality. Don’t pass raw webhook payloads to the Orchestrator. Always translate them into a clear natural-language task first: “CRITICAL alert for payments-service: response time degraded to 8s. Determine appropriate incident response.” is far better than “alert: payments-service, latency: 8000ms”. HydraDB reasons over the task description - the more context you include, the more accurate the function selection.
STEP 7

Security & Governance

An agent that takes real actions needs real guardrails. Four layers of protection: a policy engine that blocks unauthorized functions before they reach the execution layer, an auth vault that stores OAuth tokens and injects them per-function, an approval workflow that routes risky actions through a human gate, and a persistent audit log stored in HydraDB.

Policy engine

The policy engine sits between HydraDB’s suggestion and the execution. It checks: does this user have the required permission_level? Is this function restricted to specific departments? Is the current time within business_hours_only constraints? Is the function flagged as requiring human approval above a cost threshold?
security/policy.py

Approval workflow

When policy.requires_approval() returns True, route the action through a Slack approval message before executing. Store the pending action in HydraDB so the Orchestrator can resume it after approval without losing context.
security/approval.py
⚠️
Never skip the policy check for system-triggered events. Monitoring alerts and CRM webhooks bypass human input - there is no user to correct a bad suggestion. Always run policy.check() even for automated triggers, and set user_id="oncall-system" or a role-specific service account with appropriately scoped permissions. Automated triggers with admin-level access are the most dangerous pattern in this architecture.
STEP 8

Observability & Self-Improvement

Track three metrics to understand if the Chief of Staff is working. Feed failures back to HydraDB to close the improvement loop. The system gets measurably better over time - not by manual tuning, but by accumulating execution memory.

Feeding metrics back to HydraDB

Every execution metric is a signal HydraDB can learn from. A consistent slow_response signal for create_calendar_event eventually influences the plan generator to place that function at the end of plans where it won’t block other steps. Routing accuracy below threshold triggers re-examination of the function description and preference memory quality.
observability/metrics.py
💡
The compound effect. Every execution memory shifts the routing for the next call. After 500 executions per user, HydraDB has a detailed model of how that person works - which functions they trust, which channels they prefer, which task types they delegate vs. handle personally. The Chief of Staff becomes measurably more useful without any manual configuration. Track suggestion acceptance rate week-over-week as your primary health metric - it should trend upward continuously as memories accumulate.

Complete API Reference

All endpoints used in this cookbook. Base URL: https://api.hydradb.com
Header: Authorization: Bearer YOUR_API_KEY

Create tenant

POST /tenants/create - One tenant for the full Chief of Staff system
body

Upload function schemas

POST /ingestion/upload_knowledge - Upload function schemas as app knowledge or files. Max 20/call, 1s between batches
body - one function

Recall function suggestions (single-step)

POST /recall/full_recall - Returns top-matched function knowledge objects
body

Recall function candidates (multi-step planning)

POST /recall/full_recall - graph_context: true surfaces composed function chains
body

Recall user preferences (personalise suggestions)

POST /recall/recall_preferences - Returns channel preferences, urgency signals, communication style
body

Store user preference memory

POST /memories/add_memory - infer: true extracts channel + style signals
body

Store execution outcome (audit log)

POST /memories/add_memory - infer: false for verbatim audit records
body

Store performance signal (self-improvement)

POST /memories/add_memory - infer: true so HydraDB links signal to future suggestions
body

Parameter extraction

Local LLM parameter extraction - Extract structured params after HydraDB returns the best function schema
LLM prompt inputs

Benchmarks

Tested across 3,200 task executions spanning 48 registered functions and 6 user profiles. Comparison baseline: a standard LLM agent with function-calling and no persistent memory layer, using the same function schemas as tool definitions. ℹ️
Benchmark methodology. Figures are based on internal HydraDB testing. For the formal benchmark paper and methodology, see research.hydradb.com/hydradb.pdf. Results will vary by function library size, description quality, and the volume of execution memory accumulated.
ℹ️
The jump from 78% to 93% routing accuracy between week 1 and week 8 reflects HydraDB’s memory accumulation. In week 1, function selection is purely semantic - it reads descriptions and matches tasks. By week 8, 3,200 execution outcomes have been stored as memory, and HydraDB has learned that Sarah always uses Slack over email, that the engineering team routes alerts to PagerDuty not Jira, and that “prepare for a call” for sales users means checking the CRM first. Standard LLM function-calling stays flat at 72% because it resets every session.


← Prev Build an AI Competitive Intelligence Agent
Next → Build a Multi-Agent Research Pipeline