feat(profiles): SDK methods and docs for entity profiles
Adds the profile surface to both SDKs and documents it. Python (MemoryClient + AsyncMemoryClient) and TypeScript gain: get/generate profile, get/update settings, sample, regenerate. A profile's keys come from the customer's own JSON Schema, so the TS client keeps `profile` opaque and passes `schema` through untouched in both directions. Camel-casing them would return field names that do not match the schema the customer wrote. Reads use the v2 envelope, where a known entity with no profile yet is a 200 carrying a status rather than a 404, so an empty state is distinguishable from an error. Verified against a live environment running this API: settings round-trip, a partial update leaves the schema intact, generation produces a profile under the configured schema, and sample, regenerate, cooldown and the 400/404 paths all answer as documented.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: 'Get Profile Settings'
|
||||
description: "Retrieve the profile schema, custom instructions, and enabled flag for the current project."
|
||||
openapi: get /v2/profiles/settings/
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: 'Get Profile'
|
||||
description: "Retrieve the structured profile for a user or agent, with a status describing whether generation has completed."
|
||||
openapi: get /v2/entities/{entity_type}/{entity_id}/profile/
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: 'Regenerate Profiles'
|
||||
description: "Rebuild the profile of every entity in the project, applying the current schema to entities that already have one."
|
||||
openapi: post /v2/profiles/regenerate/
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: 'Sample Profiles'
|
||||
description: "Generate profiles for a small set of real entities to evaluate a schema before applying it across the project."
|
||||
openapi: post /v2/profiles/samples/
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: 'Generate Profile'
|
||||
description: "Generate or refresh the profile for a single user or agent immediately, instead of waiting for the message threshold."
|
||||
openapi: post /v2/profiles/trigger/
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: 'Update Profile Settings'
|
||||
description: "Set the JSON Schema, custom instructions, or enabled flag that control profile generation for the project."
|
||||
openapi: post /v2/profiles/settings/
|
||||
---
|
||||
@@ -71,6 +71,7 @@
|
||||
"pages": [
|
||||
"platform/features/v2-memory-filters",
|
||||
"platform/features/entity-scoped-memory",
|
||||
"platform/features/user-profiles",
|
||||
"platform/features/graph-memory",
|
||||
"platform/features/async-client",
|
||||
"platform/features/multimodal-support",
|
||||
@@ -511,6 +512,18 @@
|
||||
"api-reference/entities/delete-user"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Profiles",
|
||||
"icon": "id-card",
|
||||
"pages": [
|
||||
"api-reference/profiles/get-profile",
|
||||
"api-reference/profiles/trigger-profile",
|
||||
"api-reference/profiles/get-profile-settings",
|
||||
"api-reference/profiles/update-profile-settings",
|
||||
"api-reference/profiles/sample-profiles",
|
||||
"api-reference/profiles/regenerate-profiles"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Organizations",
|
||||
"icon": "building",
|
||||
|
||||
@@ -197,6 +197,7 @@ If the user is on a pre-current major (Python < 2, TS < 3, or a Platform call st
|
||||
### Features - Essential
|
||||
- [V2 Memory Filters](https://docs.mem0.ai/platform/features/v2-memory-filters) [Platform]: Use when compound filters (AND/OR on metadata, entity, time) are needed at search.
|
||||
- [Entity-Scoped Memory](https://docs.mem0.ai/platform/features/entity-scoped-memory) [Platform]: Use when partitioning memories by user, agent, app, or run.
|
||||
- [Profiles](https://docs.mem0.ai/platform/features/user-profiles) [Platform]: Use when a structured always-current summary of a user or agent is needed in one read, instead of searching their memories.
|
||||
- [Graph Memory](https://docs.mem0.ai/platform/features/graph-memory) [Platform]: Use when connecting facts across memories through shared entities for entity-centric or multi-hop questions.
|
||||
- [Async Client](https://docs.mem0.ai/platform/features/async-client) [Platform]: Use when the app issues many concurrent Mem0 calls and needs non-blocking I/O.
|
||||
- [Multimodal Support](https://docs.mem0.ai/platform/features/multimodal-support) [Platform]: Use when storing images or PDFs as memory input.
|
||||
@@ -362,6 +363,12 @@ All API Reference docs describe Mem0 Platform REST endpoints (requires API key).
|
||||
### Entities
|
||||
- [Get Users](https://docs.mem0.ai/api-reference/entities/get-users) [Platform]: Use when listing users, agents, or apps known to a project.
|
||||
- [Delete User](https://docs.mem0.ai/api-reference/entities/delete-user) [Platform]: Use when removing an entity and all its memories.
|
||||
- [Get Profile](https://docs.mem0.ai/api-reference/profiles/get-profile) [Platform]: Use when reading a user's or agent's structured profile and branching on its generation status.
|
||||
- [Generate Profile](https://docs.mem0.ai/api-reference/profiles/trigger-profile) [Platform]: Use when a profile is needed before the entity reaches the automatic message threshold.
|
||||
- [Get Profile Settings](https://docs.mem0.ai/api-reference/profiles/get-profile-settings) [Platform]: Use when checking the project's profile schema, instructions, or enabled flag.
|
||||
- [Update Profile Settings](https://docs.mem0.ai/api-reference/profiles/update-profile-settings) [Platform]: Use when defining or changing the JSON Schema that shapes profiles for a project.
|
||||
- [Sample Profiles](https://docs.mem0.ai/api-reference/profiles/sample-profiles) [Platform]: Use when validating a profile schema against a few real entities before applying it project-wide.
|
||||
- [Regenerate Profiles](https://docs.mem0.ai/api-reference/profiles/regenerate-profiles) [Platform]: Use when a new schema must be applied to entities that already have a profile.
|
||||
|
||||
### Organizations
|
||||
- [Create Organization](https://docs.mem0.ai/api-reference/organization/create-org) [Platform]: Use when setting up a new org.
|
||||
|
||||
+372
-1
@@ -8070,6 +8070,377 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v2/entities/{entity_type}/{entity_id}/profile/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"profiles"
|
||||
],
|
||||
"operationId": "profiles_read",
|
||||
"summary": "Get an entity's profile",
|
||||
"description": "Return the memory profile for one user or agent.\n\nGeneration is asynchronous, so a known entity that has no profile yet is a normal 200 carrying a `status`. A 404 means only that no such entity exists.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "entity_type",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"user",
|
||||
"agent"
|
||||
]
|
||||
},
|
||||
"description": "The kind of entity that carries the profile."
|
||||
},
|
||||
{
|
||||
"name": "entity_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "The entity's id, as supplied when the memory was added."
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The profile envelope.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"profile": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"description": "The generated profile, shaped by the project's schema. Empty unless status is succeeded."
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"succeeded",
|
||||
"pending",
|
||||
"failed",
|
||||
"not_enabled",
|
||||
"insufficient_data"
|
||||
],
|
||||
"description": "Generation state. Branch on this rather than on an empty profile."
|
||||
},
|
||||
"entity_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"user",
|
||||
"agent"
|
||||
]
|
||||
},
|
||||
"entity_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true
|
||||
},
|
||||
"generation_count": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Unsupported entity type."
|
||||
},
|
||||
"404": {
|
||||
"description": "No such entity in this project."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v2/profiles/settings/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"profiles"
|
||||
],
|
||||
"operationId": "profiles_settings_read",
|
||||
"summary": "Get profile settings",
|
||||
"description": "Return the profile settings for the project the API key is scoped to.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Current settings.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Whether profile generation runs for this project."
|
||||
},
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"nullable": true,
|
||||
"description": "JSON Schema describing the profile. Every property needs a description."
|
||||
},
|
||||
"custom_instructions": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Extra guidance for the extraction step."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"profiles"
|
||||
],
|
||||
"operationId": "profiles_settings_update",
|
||||
"summary": "Update profile settings",
|
||||
"description": "Update the project's profile settings. Only the fields present in the body are written, so one setting can change without re-sending the others.",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Whether profile generation runs for this project."
|
||||
},
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"nullable": true,
|
||||
"description": "JSON Schema describing the profile. Every property needs a description."
|
||||
},
|
||||
"custom_instructions": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Extra guidance for the extraction step."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Settings as stored after the update.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Whether profile generation runs for this project."
|
||||
},
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"nullable": true,
|
||||
"description": "JSON Schema describing the profile. Every property needs a description."
|
||||
},
|
||||
"custom_instructions": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Extra guidance for the extraction step."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "The schema is not a valid profile schema."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v2/profiles/trigger/": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"profiles"
|
||||
],
|
||||
"operationId": "profiles_trigger",
|
||||
"summary": "Generate one entity's profile now",
|
||||
"description": "Generate or refresh the profile for a single entity immediately.\n\nProfiles are otherwise built once an entity crosses an internal message threshold, so a new entity has none for its first few memories. Returns 202: poll the read endpoint and branch on `status`.",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"entity_id"
|
||||
],
|
||||
"properties": {
|
||||
"entity_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"user",
|
||||
"agent"
|
||||
],
|
||||
"default": "user"
|
||||
},
|
||||
"entity_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"202": {
|
||||
"description": "Generation queued.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"entity_type": {
|
||||
"type": "string"
|
||||
},
|
||||
"entity_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"profile_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Unsupported entity type, or profiles are not enabled and configured."
|
||||
},
|
||||
"404": {
|
||||
"description": "No such entity in this project."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v2/profiles/samples/": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"profiles"
|
||||
],
|
||||
"operationId": "profiles_samples",
|
||||
"summary": "Sample profiles to check a schema",
|
||||
"description": "Generate profiles for a handful of real entities so a schema can be judged before it is applied project-wide.\n\nThese are real generations and the results are kept, so the work counts toward a later regenerate.",
|
||||
"requestBody": {
|
||||
"required": false,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 10,
|
||||
"description": "How many entities to sample."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"202": {
|
||||
"description": "Sampling queued.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"sampled": {
|
||||
"type": "integer"
|
||||
},
|
||||
"results": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Profiles are not enabled and configured."
|
||||
},
|
||||
"429": {
|
||||
"description": "A sample run was already started for this project very recently."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v2/profiles/regenerate/": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"profiles"
|
||||
],
|
||||
"operationId": "profiles_regenerate",
|
||||
"summary": "Rebuild every profile in the project",
|
||||
"description": "Rebuild the profile of every entity in the project. This is how a new schema reaches entities that already have a profile.\n\nReturns 202 immediately; the rebuild runs in the background.",
|
||||
"responses": {
|
||||
"202": {
|
||||
"description": "Regenerate queued.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"project_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"existing_profile_count": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Profiles are not enabled and configured."
|
||||
},
|
||||
"409": {
|
||||
"description": "A regenerate is already running for this project."
|
||||
},
|
||||
"429": {
|
||||
"description": "A regenerate already ran for this project within the last hour."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
@@ -8988,4 +9359,4 @@
|
||||
}
|
||||
},
|
||||
"x-original-swagger-version": "2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
---
|
||||
title: Profiles
|
||||
description: "Build a structured, always-current summary of each user or agent from their memories, shaped by a JSON Schema you define."
|
||||
icon: "id-card"
|
||||
---
|
||||
|
||||
# Profiles
|
||||
|
||||
Memories are individual facts. A profile is the summary of all of them for one entity: a single structured object, shaped by a JSON Schema you define, that Mem0 keeps current as new memories arrive.
|
||||
|
||||
Search answers "what did this user say about X". A profile answers "who is this user", in one read, with no query to write.
|
||||
|
||||
<Info>
|
||||
**Use profiles when…**
|
||||
- You want to personalize a first response, before the user says anything in this session.
|
||||
- You need a compact object to drop into a prompt instead of a list of memories.
|
||||
- You want the same fields for every user, so your code can rely on their shape.
|
||||
</Info>
|
||||
|
||||
Profiles cover **users and agents**. An agent profile summarizes how an agent behaves, in the same way a user profile summarizes a person.
|
||||
|
||||
## How it works
|
||||
|
||||
1. You define a **schema**: the fields a profile should contain, each with a description.
|
||||
2. Mem0 builds each entity's profile from their memories, and rebuilds it as new memories arrive.
|
||||
3. You read the profile whenever you need it.
|
||||
|
||||
Generation is **asynchronous**. A profile is not ready the instant an entity's first memory lands, so a read tells you where it is with a `status` rather than failing.
|
||||
|
||||
## Define the schema
|
||||
|
||||
The schema is JSON Schema. Every property needs a `description` — that is what tells the model how to fill the field, so a vague description gives a vague profile.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient()
|
||||
|
||||
client.update_profile_settings(
|
||||
enabled=True,
|
||||
schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"communication_style": {
|
||||
"type": "string",
|
||||
"description": "How the user prefers to be addressed: terse, detailed, formal, casual",
|
||||
},
|
||||
"expertise_areas": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "Subjects the user demonstrates working knowledge of",
|
||||
},
|
||||
"current_goals": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "What the user is actively trying to accomplish",
|
||||
},
|
||||
},
|
||||
},
|
||||
custom_instructions="Prefer durable traits over one-off remarks.",
|
||||
)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import MemoryClient from "mem0ai";
|
||||
|
||||
const client = new MemoryClient({ apiKey: "your-api-key" });
|
||||
|
||||
await client.updateProfileSettings({
|
||||
enabled: true,
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
communication_style: {
|
||||
type: "string",
|
||||
description:
|
||||
"How the user prefers to be addressed: terse, detailed, formal, casual",
|
||||
},
|
||||
expertise_areas: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
description: "Subjects the user demonstrates working knowledge of",
|
||||
},
|
||||
current_goals: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
description: "What the user is actively trying to accomplish",
|
||||
},
|
||||
},
|
||||
},
|
||||
customInstructions: "Prefer durable traits over one-off remarks.",
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Note>
|
||||
Your schema's property names reach the API exactly as you write them. The SDKs do not rewrite them, so a profile always comes back with the field names you chose.
|
||||
</Note>
|
||||
|
||||
Only the fields you pass are written. To turn the feature off without touching your schema, send `enabled` alone.
|
||||
|
||||
## Read a profile
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = client.get_profile("alice")
|
||||
|
||||
if result["status"] == "succeeded":
|
||||
print(result["profile"])
|
||||
else:
|
||||
print("not ready:", result["status"])
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.getProfile({ entityId: "alice" });
|
||||
|
||||
if (result.status === "succeeded") {
|
||||
console.log(result.profile);
|
||||
} else {
|
||||
console.log("not ready:", result.status);
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
A response looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"profile": {
|
||||
"communication_style": "terse",
|
||||
"expertise_areas": ["distributed systems", "postgres"],
|
||||
"current_goals": ["cut p99 latency", "migrate off the legacy queue"]
|
||||
},
|
||||
"status": "succeeded",
|
||||
"entity_type": "user",
|
||||
"entity_id": "alice",
|
||||
"updated_at": "2026-02-08T10:30:00Z",
|
||||
"generation_count": 4
|
||||
}
|
||||
```
|
||||
|
||||
### Always branch on `status`
|
||||
|
||||
`profile` is empty unless `status` is `succeeded`. Check the status rather than the emptiness of the object, so a profile that is merely still building is not mistaken for a user you know nothing about.
|
||||
|
||||
| `status` | Meaning | What to do |
|
||||
|---|---|---|
|
||||
| `succeeded` | Profile is built and current | Use it |
|
||||
| `pending` | Generation is queued or running | Read again shortly |
|
||||
| `insufficient_data` | Not enough memories to say anything yet | Fall back to defaults |
|
||||
| `not_enabled` | Profiles are off for this project | Enable them in settings |
|
||||
| `failed` | The last generation did not complete | Retry, or trigger a new one |
|
||||
|
||||
A `404` means only that no such entity exists in your project.
|
||||
|
||||
For an agent, pass the entity type:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
client.get_profile("support-bot", entity_type="agent")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
await client.getProfile({ entityId: "support-bot", entityType: "agent" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Generate a profile on demand
|
||||
|
||||
Profiles are built once an entity has accumulated enough messages, so a brand-new user has none during their first few interactions. Trigger one directly to close that gap:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
client.generate_profile("alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
await client.generateProfile({ entityId: "alice" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The call returns as soon as the work is queued. Poll the read endpoint and branch on `status`.
|
||||
|
||||
## Test a schema before applying it
|
||||
|
||||
A schema that reads well can still produce disappointing profiles. Sample a few real entities and inspect the output before committing to it:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
result = client.sample_profiles(limit=5)
|
||||
|
||||
for row in result["results"]:
|
||||
print(client.get_profile(row["entity_id"]))
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = await client.sampleProfiles({ limit: 5 });
|
||||
|
||||
for (const row of result.results) {
|
||||
console.log(await client.getProfile({ entityId: row.entityId }));
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
These are real generations against real memories, and the results are kept — sampling is not wasted work. Sampling is limited to 10 entities per call and cannot be repeated immediately.
|
||||
|
||||
## Apply a new schema to existing entities
|
||||
|
||||
Changing the schema does not retroactively rewrite profiles that already exist. To rebuild every profile in the project:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
client.regenerate_profiles()
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
await client.regenerateProfiles();
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
This returns immediately and runs in the background; a large project takes a while. It is limited to one run per project per hour, so sample first and regenerate once you are satisfied.
|
||||
|
||||
## Use a profile in a prompt
|
||||
|
||||
The point of the structure is that it drops straight into a prompt:
|
||||
|
||||
```python
|
||||
result = client.get_profile(user_id)
|
||||
|
||||
if result["status"] == "succeeded":
|
||||
profile = result["profile"]
|
||||
system_prompt = f"""You are helping {user_id}.
|
||||
Communication style: {profile.get("communication_style", "unknown")}
|
||||
Areas of expertise: {", ".join(profile.get("expertise_areas", []))}
|
||||
Current goals: {", ".join(profile.get("current_goals", []))}
|
||||
|
||||
Match their style and do not explain what they already know."""
|
||||
else:
|
||||
system_prompt = "You are a helpful assistant."
|
||||
```
|
||||
|
||||
## Writing a schema that works
|
||||
|
||||
- **Describe every field.** The description is the instruction; without it the model guesses.
|
||||
- **Prefer durable traits.** "Prefers dark mode" ages well; "is annoyed today" does not.
|
||||
- **Keep it small.** Ten focused fields beat forty speculative ones, and cost less to generate.
|
||||
- **Say what the field is not.** A description that rules out the near-miss interpretation is worth more than one that only states the obvious.
|
||||
- **Sample before you commit.** It is the only way to see what your descriptions actually produce.
|
||||
|
||||
## Settings reference
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
| `enabled` | boolean | Whether profile generation runs for the project |
|
||||
| `schema` | object | JSON Schema describing the profile. Every property needs a `description` |
|
||||
| `custom_instructions` | string | Extra guidance applied during extraction |
|
||||
|
||||
<Note>
|
||||
Profile settings are per project. An API key is scoped to one project, so profiles never cross a project boundary.
|
||||
</Note>
|
||||
|
||||
## Related
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Entity-Scoped Memory" icon="users" href="/platform/features/entity-scoped-memory">
|
||||
How users, agents, apps and runs partition memories.
|
||||
</Card>
|
||||
<Card title="Custom Instructions" icon="pen" href="/platform/features/custom-instructions">
|
||||
Steer what Mem0 extracts in the first place.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
Reference in New Issue
Block a user