Skip to content

Repository files navigation

Collaborative Multi-Agent Health Behavior Persona Data Generation

A web-based chatbot implemented as proof-of-concept that leverages a LLM-based multi-agent architecture for the generation of health behavior persona data. By defining input variables based on a description in natural language from a domain researcher, health behavior personas are created. These variables are used to create a SMT-solver problem based on the constraints in the variables, this generates event data for the specified users locally.

The application uses:

  • a FastAPI backend
  • a Streamlit frontend
  • PostgreSQL user-data storage
  • a per-user hb_agent container for the multi-agent workflow

The multi-agent architecture is based on expert agents inspired by the CoALA paper. This includes RAG (semantic memory), conversation memory (episodic memory), and expert prompts (procedural memory). ChromaDB is used for memory storage, LangChain/LangGraph are used for agent orchestration, and the supervisor is implemented as a ReAct agent.

Prerequisites

  • Docker
  • OpenAI key
  • Local compute capacity for the Z3-based SMT solver

Setup

  • Clone the repository
  • Build the local agent image first with docker compose up --build hb_agent
  • Then launch the shared services with docker compose up --build
  • FastAPI is exposed on host port 8001 to avoid common local conflicts on 8000
  • The compose file pins PostgreSQL to major version 17 so the persisted Docker volume is not broken by postgres:latest upgrades
  • hb_agent is not used as one shared always-on Compose service during normal usage. After login, Streamlit starts a per-user container such as hb_agent_<username>
  • Initial ChromaDB setup for general semantic memory still has to be done manually. Embed documents under:
    • general_environmental
    • general_event
    • general_analytical

Interface

  • Login screen to access the chatbot
  • Register page to add username, password, and OpenAI key
  • After login, a user-specific hb_agent container is started with that user’s OpenAI key
  • The chatbot interface supports:
    • chatting with the supervisor
    • uploading PDFs per expert for semantic memory / RAG
    • updating episodic memory
    • clearing runtime message history without writing a reflection
    • inspecting stored variables
    • deleting one stored variable or clearing all stored variables
    • downloading generated data

The full flow is visualized below. User flow system

Multi-agent Network Architecture

  • The multi-agent network is based on one ReAct supervisor and three experts:
    • analytical expert: extracts relations between events and describes these relations using LTL, stored as ltl_expressions
    • environmental expert: extracts environmental and demographic information, stored as constant_persona_features
    • event expert: extracts event definitions and constraints, stored as eventironmental_data
  • The expert prompts used to initialize these experts and the supervisor are available in HB_Agent/Set_up/Templates
  • Additional experts can be added, but the supervisor prompt and HB_Agent/main.py must be adjusted

Stored Variable Workflow

  • Each user has at most one stored value for each required variable:
    • constant_persona_features
    • eventironmental_data
    • ltl_expressions
  • If an expert generates a new valid version of one variable, it overwrites the previous stored version for that same user
  • The supervisor uses stored variables as the source of truth
  • If a variable is already stored and complete, the supervisor should not query that expert again unless the user explicitly asks for a revision
  • If a variable is missing or incomplete, the supervisor only queries the relevant expert
  • The full stored variable values are shown in the sidebar inspection panel for the user

Compact Supervisor Check

  • The supervisor has a storage inspection tool that only returns a compact status per required variable
  • For each required variable, the tool returns:
    • checkmark if the variable is present and complete
    • a follow-up question or issue if the variable is missing or incomplete
  • The full variable bodies are not returned through this supervisor check path
  • This keeps inter-agent communication shorter and reduces token use

Message History and Memory

  • Runtime message history is separate from the persistent variable store
  • The supervisor keeps its own conversation history
  • Each expert keeps its own runtime message history inside its conversation handler
  • Update Memory reflects the current runtime histories into episodic memory and then clears:
    • environmental expert runtime history
    • event expert runtime history
    • analytical expert runtime history
    • supervisor runtime history
  • Clear Message History clears those runtime histories without storing a reflection first

Event data generation

  • The event data generation folder in HB_Agent uses the three required variables generated by the multi-agent architecture
  • In the current flow, these variables are read directly from per-user stored variable state when run_data_generation is called
  • For constant persona generation, the following elements are implemented:
    • age_group
    • age
    • gender
    • education_level
    • occupation_status
    • marital_status
    • field_of_study
    • housing_type
    • time_window
    • number_of_subjects
    • horizon
  • For the analyst agent, the following inter-event constraints are implemented:
    • No Overlap: G ¬(A ∧ B)
    • Implication (A implies B in future): G (A → F B) on a daily basis
    • Event A must overlap with at least one event B: G (A → F (A ∧ B))
  • Event constraints implemented:
    • per_event_duration: { min, max, unit }
    • total_event_duration_daily: { scale, min, max, unit }
    • total_event_episodes_daily: { scale, min, max, unit }
    • temporal_patterns
      • seasonality
        • time window or day: morning, afternoon, evening, night, weekday, weekend, day_part
        • direction: increasing or decreasing
        • amount: numeric percentage
        • within which window or day: single value or list
      • trend
        • scale: season
        • direction: increasing or decreasing
        • amount: integer number of events
        • within: number of days
        • start: start day
        • end: end day
      • fix
        • used to fix an event to one time window, for example only night
  • The solver builds a model for each day, and events that span the next day are carried over as spillover
  • LTL constraints are enforced on a per-day basis
  • Daily event counts are supplied according to trends combined with randomness
  • A compliance check is added to the generated data. This is not a strict pass/fail test but indicates the actual realized percentages per window/day
  • Visualization plots are added to the generated data
  • Outputs are downloaded through the ZIP implementation

The algorithm is visualized below. Generate synthetic data

Test case

  • The included test case is based on the study of Paciorkowski et al.
  • Four different smoking cessation profiles are identified in this study
  • The smoking behavior is described in a natural language prompt, adjusted to a horizon of 90 days to limit computational strain and augmented with additional events and inter-event relations
  • These inter-event relations are stored in a PDF available at HB_Agent/Set_up/Semantic_memory and supplied to the semantic memory of the analytical agent
  • The results of these prompts and interaction logs are available in:
    • Long_term_quitters
    • Persistent_smokers
    • Repeated_try_and_fails
    • Short_term_returner

References

  • Paciorkowski, M., Baty, F., Pohle, S., Bürki, E., Brutsche, M. (2022). Identification of smoking cessation phenotypes as a basis for individualized counseling: An explorative real-world cohort study. Tobacco Induced Diseases, 20(September), 81. https://doi.org/10.18332/tid/152546
  • Sumers, T. R., Yao, S., Narasimhan, K., & Griffiths, T. L. (2024). Cognitive architectures for language agents (Version 3) [Preprint]. arXiv. https://arxiv.org/abs/2309.02427

Tests, coverage, and the LifeSnaps pipeline

Everything runs inside the test container, no local Python. The repo is mounted at /app, so code and config edits are picked up on the next run with no rebuild; rebuild only when a dependency changes (for example when pycvcqv was added for the fidelity heterogeneity charts).

# 1. Build the test image once (installs z3, the agent stack, pytest-cov, and pycvcqv)
docker compose -f docker-compose.test.yml build tests

# 2. Run the unit suite with branch coverage (term-missing report + HTML in ./htmlcov)
docker compose -f docker-compose.test.yml run --rm tests

# 3. Generate the full LifeSnaps population (60 persons over 12 weeks) from the fitted config
docker compose -f docker-compose.test.yml run --rm -e PYTHONPATH=/app/HB_Agent tests \
  python -u -m event_data_generation.Model_builder.generate_from_config \
  --config /app/experiments/lifesnaps_personas --out /app/outputs/lifesnaps

# 4. Evaluate fidelity of the synthetic run against the observed LifeSnaps log
docker compose -f docker-compose.test.yml run --rm -e PYTHONPATH=/app/HB_Agent tests \
  python -u -m event_data_generation.Check_data.evaluate_fidelity \
  --real /app/experiments/lifesnaps_personas/observed_lifesnaps_personas_event_log.csv \
  --synthetic-json /app/outputs/lifesnaps \
  --out /app/outputs/fidelity_lifesnaps \
  --figure /app/outputs/fidelity_lifesnaps/lifesnaps_real_vs_synthetic.png

Outputs land under ./outputs (and ./htmlcov), which are mounted from the host:

  • outputs/lifesnaps/ — per-person JSON, the combined event-log CSV, per-persona charts, and summary_report.txt (person and day counts, unsatisfiable days, and overlap/rule violations).
  • outputs/fidelity_lifesnaps/metrics.csv (per persona per event: permutation p and Benjamini-Hochberg q, RMSE, DTW, MMD, KL and JS divergence, lag-1 autocorrelation, Lin's concordance, Hedges g effect size, and the CQV of both streams, all with confidence intervals), the per-event panels, and the paired-count, paired-duration, effect-size-forest, and CQV-heterogeneity figures.
  • htmlcov/index.html — the branch-coverage report.

Run a single test file with, for example, docker compose -f docker-compose.test.yml run --rm tests pytest HB_Agent/tests/test_solver.py.

Smoking personas: generate YAML configs from prompts with LLM calls

The direct (no Streamlit) path turns each persona's natural-language prompt (experiments/<Persona>/Prompt_*.txt) into the four YAML files with one OpenAI call per expert (environmental, event, analytical), each grounded by its Chroma semantic-memory collection (the LTL constraints PDF for the analytical expert). It needs OPENAI_API_KEY in .env (read by config.py).

# Generate the four YAML files for each smoking persona
docker compose -f docker-compose.test.yml run --rm -e PYTHONPATH=/app/HB_Agent tests \
  python -m agents.generate_configs_live \
  --personas Persistent_smokers Long_term_quitters Repeated_try_and_fails Short_term_returner

Each persona's four files land in experiments/<Persona>/generated_config/ (environment.yaml, event_config.yaml, persona_config.yaml, temporal_relation_rules.yaml). Flags: --personas selects which persona directories to run (default: the four smoking personas above); --no-memory skips the Chroma semantic grounding; --experiments-dir points elsewhere.

Then generate the raw event data for every smoking persona by running each generated config through the same generate_from_config entrypoint as the LifeSnaps pipeline:

# Simulate raw event data (per-person JSON, event-log CSV, charts, report) per smoking persona
for p in Persistent_smokers Long_term_quitters Repeated_try_and_fails Short_term_returner; do
  docker compose -f docker-compose.test.yml run --rm -e PYTHONPATH=/app/HB_Agent tests \
    python -u -m event_data_generation.Model_builder.generate_from_config \
    --config /app/experiments/$p/generated_config \
    --out /app/outputs/${p}_generated
done

Each run writes per-person JSON, the combined event-log CSV, per-persona charts, and summary_report.txt under outputs/<persona>_generated/.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages