By Sagar Shankaran, Founder of CallSphere
Build an AI agent that manages food bank inventory, schedules distribution appointments, checks client eligibility, and coordinates with partner agencies for efficient food assistance.
Key takeaways
Food banks operate under constant pressure: perishable inventory that must move quickly, clients with diverse dietary needs, regulatory requirements for food safety, and distribution schedules that need to accommodate working families. Many food banks rely on paper logs and spreadsheets to track thousands of pounds of food across multiple storage locations.
An AI operations agent can maintain real-time inventory awareness, schedule distribution appointments based on client eligibility and available stock, and flag items approaching expiration. This keeps food moving efficiently from donors to families while reducing waste.
Capture the key entities: inventory items, clients, and distribution appointments.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent for financial services in your browser — 60 seconds, no signup.
flowchart LR
CALLER(["Client or Lead"])
subgraph TEL["Telephony"]
SIP["Twilio SIP and PSTN"]
end
subgraph BRAIN["Financial Services AI<br/>Agent"]
STT["Streaming STT<br/>Deepgram or Whisper"]
NLU{"Intent and<br/>Entity Extraction"}
TOOLS["Tool Calls"]
TTS["Streaming TTS<br/>ElevenLabs or Rime"]
end
subgraph DATA["Live Data Plane"]
CRM[("CRM and Notes")]
CAL[("Calendar and<br/>Schedule")]
KB[("Knowledge Base<br/>and Policies")]
end
subgraph OUT["Outcomes"]
O1(["KYC pre-fill done"])
O2(["Funding instructions sent"])
O3(["Compliance officer<br/>escalation"])
end
CALLER --> SIP --> STT --> NLU
NLU -->|Lookup| TOOLS
TOOLS <--> CRM
TOOLS <--> CAL
TOOLS <--> KB
NLU --> TTS --> SIP --> CALLER
NLU -->|Resolved| O1
NLU -->|Schedule| O2
NLU -->|Escalate| O3
style CALLER fill:#f1f5f9,stroke:#64748b,color:#0f172a
style NLU fill:#4f46e5,stroke:#4338ca,color:#fff
style O1 fill:#059669,stroke:#047857,color:#fff
style O2 fill:#0ea5e9,stroke:#0369a1,color:#fff
style O3 fill:#f59e0b,stroke:#d97706,color:#1f2937
from dataclasses import dataclass, field
from datetime import datetime, date
from typing import Optional
from enum import Enum
from uuid import uuid4
class FoodCategory(Enum):
PRODUCE = "produce"
DAIRY = "dairy"
PROTEIN = "protein"
GRAINS = "grains"
CANNED_GOODS = "canned_goods"
FROZEN = "frozen"
BEVERAGES = "beverages"
BABY_SUPPLIES = "baby_supplies"
PERSONAL_CARE = "personal_care"
class StorageType(Enum):
DRY = "dry"
REFRIGERATED = "refrigerated"
FROZEN = "frozen"
@dataclass
class InventoryItem:
item_id: str = field(default_factory=lambda: str(uuid4()))
name: str = ""
category: FoodCategory = FoodCategory.CANNED_GOODS
quantity_lbs: float = 0.0
unit_count: int = 0
storage_type: StorageType = StorageType.DRY
expiration_date: Optional[date] = None
received_date: date = field(default_factory=date.today)
donor_source: str = ""
location: str = "Warehouse A"
is_allergen_free: bool = False
dietary_notes: str = ""
@dataclass
class FoodBankClient:
client_id: str = field(default_factory=lambda: str(uuid4()))
household_name: str = ""
household_size: int = 1
address: str = ""
phone: str = ""
dietary_restrictions: list[str] = field(default_factory=list)
last_visit_date: Optional[date] = None
visits_this_month: int = 0
is_eligible: bool = True
registered_at: datetime = field(default_factory=datetime.utcnow)
@dataclass
class DistributionAppointment:
appointment_id: str = field(default_factory=lambda: str(uuid4()))
client_id: str = ""
scheduled_date: date = field(default_factory=date.today)
time_slot: str = "10:00 AM"
estimated_weight_lbs: float = 0.0
status: str = "scheduled"
special_requests: str = ""
The agent tracks what is in stock, flags expiring items, and helps plan distributions based on available supply.
from agents import function_tool
inventory: list[InventoryItem] = []
@function_tool
async def check_inventory(
category: str = "all",
include_expiring: bool = False,
) -> dict:
"""Check current food bank inventory levels."""
results = []
expiring = []
for item in inventory:
if category != "all" and item.category.value != category:
continue
entry = {"name": item.name, "category": item.category.value,
"quantity_lbs": item.quantity_lbs, "storage": item.storage_type.value}
if item.expiration_date:
days_left = (item.expiration_date - date.today()).days
entry["expires_in_days"] = days_left
if days_left <= 3:
expiring.append(entry)
results.append(entry)
resp = {"items": results, "total_weight_lbs": sum(i.quantity_lbs for i in inventory)}
if include_expiring:
resp["expiring_within_3_days"] = expiring
return resp
@function_tool
async def receive_donation(
item_name: str,
category: str,
quantity_lbs: float,
unit_count: int,
donor_source: str,
storage_type: str = "dry",
expiration_date: str = "",
) -> dict:
"""Log a new food donation into inventory."""
item = InventoryItem(
name=item_name,
category=FoodCategory(category),
quantity_lbs=quantity_lbs,
unit_count=unit_count,
storage_type=StorageType(storage_type),
expiration_date=date.fromisoformat(expiration_date)
if expiration_date else None,
donor_source=donor_source,
)
inventory.append(item)
return {"status": "received", "item_id": item.item_id,
"name": item_name, "quantity_lbs": quantity_lbs}
Food banks typically allow visits on a set frequency. The agent checks eligibility and books appointments.
clients_db: dict[str, FoodBankClient] = {}
appointments_db: list[DistributionAppointment] = []
MAX_VISITS_PER_MONTH = 2
POUNDS_PER_PERSON = 5.0
@function_tool
async def check_eligibility(client_id: str) -> dict:
"""Check if a client is eligible for food assistance."""
client = clients_db.get(client_id)
if not client:
return {"error": "Client not found. Please register first."}
eligible = client.visits_this_month < MAX_VISITS_PER_MONTH
allocation_lbs = client.household_size * POUNDS_PER_PERSON
return {
"client": client.household_name,
"household_size": client.household_size,
"visits_this_month": client.visits_this_month,
"max_visits": MAX_VISITS_PER_MONTH,
"is_eligible": eligible,
"allocation_lbs": allocation_lbs,
"dietary_restrictions": client.dietary_restrictions,
"reason": "Eligible" if eligible else
f"Monthly visit limit ({MAX_VISITS_PER_MONTH}) reached",
}
@function_tool
async def schedule_appointment(
client_id: str,
preferred_date: str,
preferred_time: str = "10:00 AM",
special_requests: str = "",
) -> dict:
"""Schedule a food distribution appointment for an eligible client."""
client = clients_db.get(client_id)
if not client:
return {"error": "Client not found"}
if client.visits_this_month >= MAX_VISITS_PER_MONTH:
return {"error": "Client has reached monthly visit limit"}
allocation = client.household_size * POUNDS_PER_PERSON
appt = DistributionAppointment(
client_id=client_id,
scheduled_date=date.fromisoformat(preferred_date),
time_slot=preferred_time,
estimated_weight_lbs=allocation,
special_requests=special_requests,
)
appointments_db.append(appt)
return {
"status": "scheduled",
"appointment_id": appt.appointment_id,
"date": preferred_date,
"time": preferred_time,
"estimated_allocation_lbs": allocation,
"household_size": client.household_size,
"notes": special_requests or "None",
}
from agents import Agent, Runner
food_bank_agent = Agent(
name="Community Food Bank Agent",
instructions="""You are the operations agent for the Community
Food Bank. Your responsibilities:
1. Track inventory across all food categories
2. Flag items expiring within 3 days for urgent distribution
3. Check client eligibility before scheduling appointments
4. Allocate 5 lbs per household member per visit
5. Respect the 2-visit-per-month limit per household
6. Note dietary restrictions when preparing orders
7. Log incoming donations with proper categorization
8. Be compassionate — clients are in difficult situations
9. Never ask for income verification through the chat
10. Direct complex eligibility questions to case managers""",
tools=[
check_inventory,
receive_donation,
check_eligibility,
schedule_appointment,
],
)
result = Runner.run_sync(
food_bank_agent,
"The Johnson family (household of 5, client ID jhn-001) needs to "
"schedule a pickup. They have a gluten allergy. Also, we just "
"received 200 lbs of canned vegetables from Walmart.",
)
print(result.final_output)
The agent's inventory check tool flags items within 3 days of expiration. When these are detected, the agent prioritizes distributing them in upcoming appointments and can suggest an emergency distribution event. The agent can also notify partner agencies that may accept near-expiration items for immediate use.
Still reading? Stop comparing — try CallSphere live.
See the financial services AI agent handle a real call — complete, industry-specific, and live in your browser. No signup.
Add a threshold alert tool that monitors category-level inventory. When any category drops below a configurable minimum (for example, 50 lbs of protein), the agent generates a notification for the food bank manager and can draft donation requests to regular supplier partners.
The agent detects unregistered clients when the eligibility check returns "not found." It then walks the caller through registration, collecting household name, size, address, phone, and dietary restrictions. After registration, the agent immediately checks eligibility and offers to schedule an appointment.
#FoodBank #NonprofitOperations #InventoryManagement #AgenticAI #Python #LearnAI #AIEngineering

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
The 2026 desktop AI agent landscape — ServiceNow Project Arc, Anthropic Claude offerings, OpenAI agents, and Google Mariner. A buyer's map.
Step-by-step build of a working agent with the OpenAI Agents SDK — Agent class, tools, handoffs, tracing — plus an eval pipeline that catches regressions before merge.
An agentic-AI perspective on Anthropic Skills system, covering orchestration patterns, tool use, and how agent tooling fits production agent stacks.
Enterprise CIO Guide perspective on Comet's general-availability launch put an agentic browser in front of millions of consumers, and it works better than the demos suggested.
Enterprise CIO Guide perspective on Harvey AI's enterprise rollout numbers show legal agents have moved past the pilot stage at AmLaw 100 firms.
Enterprise CIO Guide perspective on Hippocratic AI's deployment numbers show healthcare voice agents are moving from pilot to production across major US health systems.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco