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 OAuthRequired 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
- 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
- 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_knowledgewithtype: "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 surfacessend_slack_announcementeven 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_messageoversend_email. This happens without any manual configuration - the pattern emerges from usage stored viaPOST /memories/add_memory. - Multi-step plan generation -
mode: "thinking"onPOST /recall/full_recallenables 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_memorycloses 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:setup.py
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 samePOST /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
Use team-scoped sub-tenants for precision. If your function library grows to 50+ functions, a singlesub_tenant_id="functions"will degrade routing quality because HydraDB must rank more candidates per query. Instead, upload sales functions tosub_tenant_id="sales", engineering functions tosub_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
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_filtersis 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 eachfunction_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 withinfer: 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
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. Useinfer: 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
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. Useinfer: false for exact outcome records and infer: true for synthesized pattern summaries.
memory/outcomes.py
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. ℹ️Usemode: "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’saccount_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 ascompensatable: false in their schema metadata.
planning/rollback.py
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 sameOrchestrator.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 theuser_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 theuser_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 requiredpermission_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
Whenpolicy.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 runSTEP 8policy.check()even for automated triggers, and setuser_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.
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 consistentslow_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.comHeader:
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 schemaLLM 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