refactor: update MemoryPromptConfig to allow custom prompt strings

* Removed the static method for online people research and replaced it with a constructor for MemoryPromptConfig that accepts custom strings for save, extract, and query systems.
* Updated the corresponding test to validate the new configuration approach, ensuring flexibility in memory prompt handling.
This commit is contained in:
lorenzejay
2026-04-07 17:53:36 -07:00
parent eeeb90c3a8
commit 88cbf6bd1a
2 changed files with 10 additions and 103 deletions

View File

@@ -153,104 +153,6 @@ class MemoryPromptConfig(BaseModel):
consolidation_system: str | None = None
consolidation_user: str | None = None
@classmethod
def for_online_people_research(cls) -> MemoryPromptConfig:
"""Prompt profile for open-web people research (e.g. Exa).
Biases memory toward **search provenance** (queries, domains, URLs, dead
ends, strong sources) and away from storing fragile biographical detail
or speculation as high-confidence fact. Pair with ``EXASearchTool`` and
explicit scopes/categories in ``remember()`` when you need determinism.
"""
return cls(
save_system=(
"You analyze content for a hierarchical memory used during "
"online people research.\n"
"Prioritize durable *research-process* signals over raw biographical claims:\n"
"- suggested_scope: use paths like /subjects/<slug>, /searches/queries, "
"/sources/domains when the content is about where or how you searched.\n"
"- categories: include tags such as search_query, result_domain, "
"source_url, exa_search, dead_end, preferred_source, methodology "
"when applicable. Use subject_profile only for well-sourced factual "
"snippets tied to a named URL or document - not for gossip or guesses.\n"
"- importance: higher (0.7-1.0) for reusable search lessons "
"(e.g. 'site X returned 404', 'LinkedIn useful for role Y', "
"'query phrasing Z worked'). Lower (0.2-0.5) for one-off personal "
"minutiae or unverified claims.\n"
"- extracted_metadata.entities: prefer domains, publication names, "
"and search keywords; only list people when the text explicitly "
"anchors a fact to a source.\n"
"Given the content and existing scopes and categories, output:\n"
"1. suggested_scope\n2. categories\n3. importance\n4. extracted_metadata"
),
save_user=(
"Content to store:\n{content}\n\n"
"Existing scopes: {existing_scopes}\n"
"Existing categories: {existing_categories}\n\n"
"Return the analysis as structured output."
),
query_system=(
"You analyze a query against memory for people-research crews.\n"
"Favor recalling *how and where* the team already searched:\n"
"- keywords: include domains, site names, query stems, and subject "
"handles - not only the person's name.\n"
"- suggested_scopes: prefer /searches, /sources, /subjects as relevant.\n"
"- recall_queries: produce phrases that would match memories about "
"Exa queries, domains tried, and conclusions about source quality.\n"
"- complexity: 'complex' if the question asks to synthesize many sources; "
"else 'simple'.\n"
"- time_filter: ISO date if the query implies a time window; else null.\n"
"Given the query and available scopes, output:\n"
"1. keywords\n2. suggested_scopes\n3. complexity\n4. recall_queries\n"
"5. time_filter"
),
query_user=(
"Query: {query}\n\n"
"Available scopes: {available_scopes}\n"
"{scope_desc}\n\n"
"Return the analysis as structured output."
),
extract_memories_system=(
"Extract discrete memory statements from research logs (tool outputs, "
"Exa results, agent notes).\n"
"HIGH priority - always capture when present:\n"
"- Exact or paraphrased search queries used and which engine/tool "
"(e.g. Exa).\n"
"- Domains and canonical URLs of pages opened; HTTP errors or empty results.\n"
"- Judgments about source usefulness (e.g. 'official bio on company site', "
"'social profile - verify elsewhere').\n"
"MEDIUM priority:\n"
"- Verifiable facts explicitly tied to a source in the text "
"(quote which source).\n"
"LOW priority / often skip:\n"
"- Speculation, reputation gossip, or detailed private life unless "
"the task explicitly requires it and a primary source is named.\n"
"Each memory: one clear sentence, no duplicate ideas.\n"
'Output JSON with a single key "memories" whose value is a list of strings.'
),
extract_memories_user=(
"Content:\n{content}\n\n"
"Extract memory statements as described. Return structured output."
),
consolidation_system=(
"You consolidate new research content with similar existing memories.\n"
"Prefer keeping separate memories when they differ by URL, domain, or "
"search query - even if about the same person.\n"
"Merge or update when the new text clearly refines the same source "
"or same search finding.\n"
"Delete only when a memory is clearly wrong and superseded.\n"
"Be conservative: prefer 'keep' when unsure.\n"
"For each existing memory: keep | update | delete. "
"Set insert_new when the new content adds a distinct query, URL, or "
"source judgment."
),
consolidation_user=(
"New content to consider storing:\n{new_content}\n\n"
"Existing similar memories:\n{records_summary}\n\n"
"Return the consolidation plan as structured output."
),
)
class MemoryConfig(BaseModel):
"""Internal configuration for memory scoring, consolidation, and recall behavior.

View File

@@ -653,13 +653,18 @@ def test_remember_survives_llm_failure(
# --- Per-Memory prompt config (MemoryPromptConfig) ---
def test_memory_prompt_overrides_for_online_people_research() -> None:
def test_memory_prompt_config_custom_strings() -> None:
"""Library stays domain-agnostic; apps pass their own MemoryPromptConfig."""
from crewai.memory.types import MemoryPromptConfig
po = MemoryPromptConfig.for_online_people_research()
assert po.save_system and "search_query" in po.save_system
assert po.extract_memories_system and "Exa" in po.extract_memories_system
assert po.query_system and "recall_queries" in po.query_system
po = MemoryPromptConfig(
save_system="Prefer categories: search_query, exa_search, result_domain.",
extract_memories_system="Record Exa queries and canonical URLs first.",
query_system="Distill recall_queries toward domains and past queries.",
)
assert "search_query" in (po.save_system or "")
assert "Exa" in (po.extract_memories_system or "")
assert "recall_queries" in (po.query_system or "")
def test_memory_prompt_overrides_save_system_used_in_analyze(tmp_path: Path) -> None: