# How OasisProfileGenerator Creates Agent Profiles from Seed Information

> Discover how OasisProfileGenerator transforms seed data into OASIS agent profiles using hybrid graph searches LLM or rule based generation and multi layer error recovery for robust JSON.

- Repository: [BaiFu/mirofish](https://github.com/666ghj/mirofish)
- Tags: how-to-guide
- Published: 2026-02-23

---

**OasisProfileGenerator converts raw Zep graph entities into structured OASIS-compatible agent profiles by enriching seed data with hybrid graph searches, applying LLM-based or rule-based generation strategies, and validating JSON output through multi-layer error recovery.**

The **OasisProfileGenerator** class in the `666ghj/mirofish` repository transforms sparse Zep entity nodes into fully-featured OASIS agent profiles through a robust pipeline that combines graph traversal with large language model inference. Located in [`backend/app/services/oasis_profile_generator.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/services/oasis_profile_generator.py), this component bridges raw seed information and simulation-ready personas by systematically enriching context, generating structured attributes, and ensuring deterministic fallbacks when AI services are unavailable.

## Generator Initialization and Credential Management

The pipeline begins in the `__init__` method (lines 80‑100) of [`backend/app/services/oasis_profile_generator.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/services/oasis_profile_generator.py), which initializes the **OpenAI** client using configuration values for `api_key`, `base_url`, and `model_name`. When a Zep API key is provided, the constructor also instantiates a **Zep** client (`self.zep_client`) to enable hybrid graph searches for supplemental context.

```python
def __init__(self,
             api_key: Optional[str] = None,
             base_url: Optional[str] = None,
             model_name: Optional[str] = None,
             zep_api_key: Optional[str] = None,
             graph_id: Optional[str] = None):
    self.api_key = api_key or Config.LLM_API_KEY
    self.base_url = base_url or Config.LLM_BASE_URL
    self.model_name = model_name or Config.LLM_MODEL_NAME
    self.client = OpenAI(api_key=self.api_key, base_url=self.base_url)
    
    self.zep_api_key = zep_api_key or Config.ZEP_API_KEY
    self.graph_id = graph_id
    if self.zep_api_key:
        self.zep_client = Zep(api_key=self.zep_api_key)

```

This initialization ensures both LLM and optional graph database connections are available for the enrichment phase.

## Context Enrichment from Seed Entities

Before generating profiles, the system enriches raw seed data through the `_build_entity_context` method (lines 124‑166). This function aggregates the entity’s intrinsic attributes, directly-linked edges representing facts and relationships, and summaries of related nodes. For deeper context, it invokes `_search_zep_for_entity` (lines 86‑122) to execute parallel hybrid searches against Zep’s edge and node indices, deduplicating results to create a comprehensive context string capped at 3000 characters.

The enrichment process ensures that even sparse seed entities carry sufficient narrative detail to generate coherent agent personas, drawing from both the immediate graph neighborhood and broader semantic matches in the Zep knowledge base.

## Selecting the Generation Strategy

The `generate_profile_from_entity` method (lines 112‑132) serves as the orchestration layer that determines whether to use AI-driven or deterministic generation. When `use_llm=True`, the system routes to `_generate_profile_with_llm` (lines 150‑197); otherwise, it falls back to `_generate_profile_rule_based` to ensure profile creation continues even during API outages.

```python
if use_llm:
    profile_data = self._generate_profile_with_llm(...)
else:
    profile_data = self._generate_profile_rule_based(...)

```

This dual-path architecture guarantees that **OasisProfileGenerator** can create agent profiles under varying infrastructure constraints.

## LLM Prompt Engineering and Robust JSON Handling

For LLM-driven generation, the system constructs specialized prompts based on entity type. Individual entities trigger `_build_individual_persona_prompt` (lines 176‑224), while groups or institutions invoke `_build_group_persona_prompt` (lines 226‑274). Both templates embed the enriched context and enforce a strict JSON schema requiring fields such as `bio`, `persona`, `age`, `gender`, `mbti`, `country`, `profession`, and `interested_topics`.

The `_generate_profile_with_llm` method (lines 150‑197) executes the API call with a forced JSON response format and implements progressive temperature reduction on retries (`temperature=0.7 - (attempt * 0.1)`). When the LLM returns truncated output (finish reason `'length'`), `_fix_truncated_json` (lines 182‑206) attempts automatic bracket closure. For malformed JSON, `_try_fix_json` (lines 208‑272) extracts partial structures, repairs newline characters, and ultimately falls back to a minimal safe dictionary to prevent pipeline failure.

## Assembling the OasisAgentProfile Dataclass

Whether generated by LLM or rules, the final data flows into the `OasisAgentProfile` dataclass constructor (lines 154‑173 in the return statement). This structure maps extracted or default values to required OASIS fields:

- **Identity**: `user_id`, `user_name`, `name`
- **Narrative**: `bio`, `persona`
- **Platform Metrics**: `karma`, `friend_count`, `follower_count`, `statuses_count` (populated with random defaults if unspecified)
- **Demographics**: `age`, `gender`, `mbti`, `country`, `profession`, `interested_topics`
- **Provenance**: `source_entity_uuid`, `source_entity_type`

```python
return OasisAgentProfile(
    user_id=user_id,
    user_name=user_name,
    name=name,
    bio=profile_data.get("bio", f"{entity_type}: {name}"),
    persona=profile_data.get("persona", entity.summary or f"A {entity_type} named {name}."),
    karma=profile_data.get("karma", random.randint(500, 5000)),
    friend_count=profile_data.get("friend_count", random.randint(50, 500)),
    follower_count=profile_data.get("follower_count", random.randint(100, 1000)),
    statuses_count=profile_data.get("statuses_count", random.randint(100, 2000)),
    age=profile_data.get("age"),
    gender=profile_data.get("gender"),
    mbti=profile_data.get("mbti"),
    country=profile_data.get("country"),
    profession=profile_data.get("profession"),
    interested_topics=profile_data.get("interested_topics", []),
    source_entity_uuid=entity.uuid,
    source_entity_type=entity_type,
)

```

## Batch Generation and Concurrency

For processing multiple seeds efficiently, `generate_profiles_from_entities` (lines 208‑285) implements a **ThreadPoolExecutor** to parallelize individual profile creation. This method accepts a `progress_callback` for real-time UI updates and supports `realtime_output_path` to stream interim results to disk, preventing data loss during long-running batch jobs. The `parallel_count` parameter controls concurrency levels, allowing operators to balance throughput against API rate limits.

## Practical Implementation Examples

### Generating a Single Profile

To create a profile from a specific Zep entity:

```python
from backend.app.services.oasis_profile_generator import OasisProfileGenerator
from backend.app.services.zep_entity_reader import ZepEntityReader

entity = ZepEntityReader().read_entity(entity_uuid="1234-abcd")
generator = OasisProfileGenerator()

profile = generator.generate_profile_from_entity(
    entity=entity,
    user_id=42,
    use_llm=True
)

print(profile.to_reddit_format())

```

### Batch Processing with Progress Tracking

For large-scale generation:

```python
def progress(current, total, msg):
    print(f"[{current}/{total}] {msg}")

entities = ZepEntityReader().read_entities_from_graph(graph_id="my-graph")
generator = OasisProfileGenerator(zep_api_key="ZEP_KEY", graph_id="my-graph")

profiles = generator.generate_profiles_from_entities(
    entities=entities,
    use_llm=True,
    progress_callback=progress,
    parallel_count=8,
    realtime_output_path="output/reddit_profiles.json",
    output_platform="reddit"
)

```

## Summary

- **OasisProfileGenerator** in [`backend/app/services/oasis_profile_generator.py`](https://github.com/666ghj/mirofish/blob/main/backend/app/services/oasis_profile_generator.py) orchestrates the transformation of Zep graph entities into OASIS-compatible agent profiles through a multi-stage pipeline.
- The system enriches sparse seed information via `_build_entity_context` and hybrid Zep searches, ensuring rich narrative inputs for generation.
- Dual generation strategies (LLM-based via `_generate_profile_with_llm` and rule-based fallback) guarantee operational resilience, with automatic JSON repair mechanisms handling truncation and parsing errors.
- Output conforms strictly to the `OasisAgentProfile` dataclass structure, supporting serialization to Reddit and Twitter platform formats.
- Batch operations leverage thread pools and real-time persistence to efficiently process large entity graphs while maintaining progress visibility.

## Frequently Asked Questions

### What input format does OasisProfileGenerator require to create agent profiles?

The generator accepts **EntityNode** objects from the Zep graph database, typically retrieved via `ZepEntityReader`. These entities contain seed information including UUIDs, types, summaries, and attribute dictionaries that serve as the foundation for profile generation.

### How does OasisProfileGenerator handle LLM API failures or malformed responses?

The implementation features a multi-layer resilience strategy. If the LLM call fails or returns invalid JSON, `_fix_truncated_json` (lines 182‑206) and `_try_fix_json` (lines 208‑272) attempt automated repairs. When `use_llm=False` or all recovery attempts fail, the system falls back to `_generate_profile_rule_based` to produce deterministic profiles using templates and default values.

### Can OasisProfileGenerator create profiles for organizations and groups, or only individuals?

The generator supports both entity types through specialized prompt engineering. The `generate_profile_from_entity` method routes individual entities to `_build_individual_persona_prompt` (lines 176‑224) and groups/institutions to `_build_group_persona_prompt` (lines 226‑274), ensuring appropriate narrative structures for each category.

### What social media platforms are supported for profile export?

The `OasisAgentProfile` dataclass provides native serialization methods including `to_reddit_format()` and `to_twitter_format()`, generating platform-specific data structures compatible with Reddit and Twitter simulation environments, respectively.