← Back to all apps

Enterpret

Businessby Enterpret Inc
Launched May 18, 2026 on ChatGPTLaunched Apr 1, 2026 on Claude

Turn customer feedback into answers you can act on, directly in Claude. Query your Enterpret knowledge graph across support tickets, Gong calls, app reviews, NPS surveys, Slack, and more. Every insight is traced back to real customer conversations with direct links. Just ask a question in plain language. No query language or setup needed.

7ChatGPT Tools
7Claude Tools
Enterpret IncDeveloper
BusinessCategory

Use Cases

data

Available Tools

Find User Quote

find_user_quote
Full Description

Find validated verbatim user quotes from Knowledge Graph record IDs.

Use this whenever the user asks for quotes, verbatims, snippets, sample customer language, or examples in the customer's words. First call the graph query tool available on the current surface only to fetch candidate NaturalLanguageInteraction record IDs, then pass those IDs here: run_graph_query on v2/admin schema-decomposition surfaces, execute_cypher_query on the legacy auth-scoped surface.

Do not use fi.content/nli.content rows as quotes. If this tool returns no validated quotes, do not substitute summaries or paraphrases. Do not treat product, feature, or customer names in quote requests as source filters unless the user explicitly asks for a source or integration. If a narrow source-like filter returns no candidate records or no quotes, broaden the candidate query across sources before concluding no quotes exist. If the user specified a date window, keep record timestamps from the candidate query and state the actual earliest/latest dated records analyzed as the first sentence of the final response before any title, heading, or quote list. Do not merely restate the user's requested window. Preserve numeric citation links only on exact numeric values returned by the graph query tool. Do not reuse a citation URL for computed, summed, rounded, or approximate numbers. Preserve returned quote text and speaker attribution links in final answers. For prose, keep the exact blockquote shape, including the > marker on both the quote line and the attribution line: > "Quote text" > — [Speaker](link) For tables, keep the quote text and speaker attribution link in the same table cell as "Quote text" — [Speaker](link); do not split them into a generic record-link column. If the user asks for a table, include the requested columns such as date, channel/title, and record link, while preserving quote + attribution in one quote cell. If the user asks for direct customer quotes plural, return at least two validated quotes when available; if a narrow candidate query yields too few quotes, broaden candidate records before concluding none.

Args: criteria: What the quotes should be about record_ids: NLI record IDs returned by a previous graph query count: Number of quotes to return, between 1 and 5 user_question: The user's original question for language and speaker intent detection

Returns: Validated quotes formatted as blockquotes with speaker attribution and record links.

Parameters (2 required, 2 optional)
Required
criteriastring
record_idsarray
Optional
countinteger
Default: 1
user_questionstring

Get Knowledge Graph Schema

get_graph_schema
Full Description

Get the Knowledge Graph schema structure for a specific organization.

Retrieves entity names, relationships, and static properties.

IMPORTANT — check this flag in the response:

has_source_fields:

  • If true: call search_graph_fields(query) before each Cypher query

to get relevant integration fields (Zendesk, Salesforce, Gong, etc.)

  • If false: no source-specific metadata, skip search_graph_fields

Returns: Schema structure with has_source_fields flag

Get Organization Details

get_organization_details
Full Description

Get details about your organization.

Fetches organization metadata including name, slug, and dashboard URL. This is useful for understanding your organization context and generating proper links to customer records.

Returns: Organization details including name, slug, and dashboard URL

Get Query Examples

get_query_examples
Full Description

Get sample Cypher queries similar to what you need to build.

Returns reference examples showing correct compiler dialect. Some examples include a wrong_cypher field showing a common mistake and why it fails — study these to avoid the same errors.

HOW TO USE THE RESULTS: 1. Study the correct_cypher patterns — relationships, COUNT DISTINCT, date functions, MISC filters, category_enum usage 2. If wrong_cypher is present, understand what mistake it shows and avoid it 3. ADAPT the patterns with entity names from search_graph_values results 4. Build your own query — do NOT copy-paste 5. For month/month-range requests with no year, use the most recent fully completed occurrence relative to the current date. If the range is upcoming or in progress this year, use the previous year. 6. For "last month" / "past month" without a named calendar month, use a rolling window: now()

  • INTERVAL 30 DAY. For daily/weekly/monthly analysis,

keep that same filter for every query; group daily/weekly with toStartOfDay/toStartOfWeek, and make monthly the window total unless the user asks for a multi-month trend. 7. For quote requests inside explicit date windows, candidate-record queries should return record_id plus record_timestamp/source/summary. Make the first sentence of the final answer state the actual earliest/latest records analyzed, before any title/heading/quote list; do not only repeat the requested window. 8. For CASE-bucket counts, prefer WITH ... CASE ... END AS bucket, then RETURN bucket, COUNT(DISTINCT ...) so the compiler groups by the bucket. 9. Preserve explicit source filters from the user. If the user says Zendesk/App Store/Gong/G2, do not swap in a different source discovered from exploratory results. 10. "General" and "Generic" taxonomy values are not Miscellaneous. Unless the user explicitly says "miscellaneous", still filter only type != 'MISC' and do not add type != 'GENERIC'. 11. For source metadata prompts, include the source and field intent in search_graph_fields: "appstore rating country", "zendesk tags customer experience", "gong account name call title", "g2 star rating".

HOW TO WRITE THE INTENT (affects which examples you get): The intent argument is a short natural-language description of the Cypher you want to build. It is matched against the example corpus by a hybrid lexical + semantic retriever that prioritizes example user_query phrasing, then rule descriptions and notes. Specificity beats keywords alone. Include the four aspects of your query:

  • Operation: "count", "top themes", "sample records", "sentiment breakdown"
  • Filter: "complaints", "from Zendesk", "in last 30 days"
  • Grouping: "by theme", "by source", "by month"
  • Special needs: "exclude billing", "with account info"

Good intents (specific → better matches): "count complaints by theme from Zendesk in last month" "monthly trend analysis of feedback volume" "sample records with sentiment and source filtering" "top L2 categories with MISC filtering" "exclude specific topics from source analysis" "compare complaint volume before and after a date"

Bad intents (too vague → poor matches): "query" / "get data" / "feedback" / "help"

Args: intent: Short natural-language description of the Cypher you want to build. Include operation, filters, grouping, and special needs. top_k: Number of examples to return (default: 5)

Returns: JSON array of examples with correct_cypher, notes, and optionally wrong_cypher.

Current date for relative date resolution: 2026-06-04 UTC.

Parameters (1 required, 1 optional)
Required
intentstring
Optional
top_kinteger
Default: 5

Run Graph Query

run_graph_query
Full Description

Execute a Cypher query against Enterpret's Knowledge Graph.

Translates your Cypher to SQL and returns structured results. Enterpret's KG unifies 100+ sources (Zendesk, Gong, Slack, AppStore, etc.) into a single graph. Source identity: nli.source. Source-specific metadata fields live on whichever entity the field belongs to — qualify each one with the alias matching its entity group as returned by search_graph_fields (nli.* for NLI/FeedbackRecord, the joined account/user alias for Account/User fields).

BEFORE writing Cypher:

  • If your query involves source-specific fields (ratings, tags, account names, plan types,

custom metadata), you MUST call search_graph_fields first to discover exact field names.

  • Call get_query_examples to see proven patterns for similar queries.

You MUST follow the Enterpret-specific Cypher rules below. Standard Neo4j Cypher patterns will often fail or return incorrect results due to the KG's structure (relationship fan-out creates duplicate rows).

LIMIT

Only apply LIMIT when the user explicitly requests a subset or examples.

No LIMIT — user wants a true total or complete breakdown:

  • "how many" / "total" / "count" → COUNT query, no LIMIT
  • "all feedback" / "every" / "locate all" → exhaustive retrieval, no LIMIT
  • "breakdown by X" / GROUP BY → all groups needed, no LIMIT

Good: RETURN COUNT(DISTINCT nli.record_id) AS total Good: RETURN language, COUNT(DISTINCT nli.record_id) AS total ORDER BY total DESC Bad: RETURN COUNT(DISTINCT nli.record_id) AS total LIMIT 100 -- caps the count! Bad: RETURN ... LIMIT 50 -- when user asked for "all", hides results

Use LIMIT — user wants a ranked subset or examples:

  • "top 5" / "biggest" / "most common" → LIMIT N (default 50)
  • "show me some examples" / "sample feedback" → platform-aware limit:

Gong/Zoom calls ~3-5, Zendesk tickets ~10, Surveys ~20-50

Counting

Always use COUNT(DISTINCT entity.record_id). Never COUNT(*) or COUNT(entity). Graph traversals create duplicate rows: 1 NLI → many FI → many CFT.

Good: COUNT(DISTINCT nli.record_id) AS total Bad: COUNT(*) AS total -- inflated by fan-out duplicates

Feedback count → COUNT(DISTINCT nli.record_id) User/customer count → COUNT(DISTINCT <user_alias>.record_id) via the user-join path your org's schema exposes (PROVIDED_BY_USER → User or HAS_USER → DerivedUser; see get_graph_schema and search_graph_fields).

DISTINCT

Always use DISTINCT when returning NLI rows for samples or examples. Without it, the same record_id may appear multiple times due to fan-out.

Good: RETURN DISTINCT nli.record_id AS record_id, fi.content AS summary Bad: RETURN nli.record_id, fi.content -- duplicates likely

MISC Filter

Every query using Theme, Subtheme, L1, L2, or L3 MUST include: entity.type != 'MISC' This applies to all query types — counts, samples, filtered, exploratory.

Good: WHERE t.category_enum CONTAINS 'COMPLAINT' AND t.type != 'MISC' Bad: WHERE t.category_enum CONTAINS 'COMPLAINT' -- includes junk MISC entries For OPTIONAL MATCH: WHERE (t IS NULL OR t.type != 'MISC') Only omit if user explicitly says "include miscellaneous".

Dates

Relative dates — always use INTERVAL, never hardcode: Good: WHERE nli.record_timestamp >= now()

  • INTERVAL 30 DAY

Good: WHERE opp.close_date >= now()

  • INTERVAL 6 MONTH

Bad: WHERE opp.close_date >= toDateTime('2024-06-01') -- breaks over time

Literal dates: toDateTime('YYYY-MM-DD HH:MM:SS') Month or month range without year: use the most recent fully completed occurrence relative to the current date. If the month/range is upcoming or still in progress this year, use the previous year. For "last month" or "past month" without a named calendar month, use a rolling window: now()

  • INTERVAL 30 DAY. For daily/weekly/monthly analysis over a

relative window, keep the same rolling filter in every query; group daily with toStartOfDay, weekly with toStartOfWeek, and make monthly the total for that same rolling window unless the user asks for a multi-month trend. For explicit time windows, preserve or query actual coverage with returned timestamps or MIN/MAX timestamp fields, and state the actual analyzed min/max as the first sentence of the response before any title, heading, or quote list.

Temporal grouping — use built-in functions: Good: toStartOfMonth(nli.record_timestamp), toStartOfWeek(...), toStartOfDay(...) Bad: substring(nli.record_timestamp, 1, 7) -- not supported Bad: DATE_TRUNC('month', ...) -- not supported

String Matching

Use CONTAINS for all string matching. Never regex, LOWER(), or UPPER(). Good: WHERE nli.source CONTAINS 'Zendesk' Good: WHERE t.category_enum CONTAINS 'COMPLAINT' For case-insensitive search: (fi.content CONTAINS 'login' OR fi.content CONTAINS 'Login')

Entity & Relationship Rules

Sentiment vs Category — different entities, different paths:

  • "negative" / "positive" / "neutral" → Sentiment

Path: (fi)-[:HAS_SENTIMENT]->(sp:SentimentPrediction) Filter: sp.label CONTAINS 'negative' CRITICAL: Do NOT query sentiment for Gong/Zoom/Teams/audio sources. These are multi-user conversations — sentiment analysis requires single-user context. If user asks for sentiment on Gong/Zoom: explain the limitation and use category_enum instead.

  • "complaints" / "praise" / "improvement" / "help" → Category

Path: (cft)-[:HAS_THEME]->(t:Theme) Filter: t.category_enum CONTAINS 'COMPLAINT' (or 'IMPROVEMENT', 'PRAISE', 'HELP') Works for ALL sources. Never use sentiment (sp.label) as a substitute for category. Never use t.name for category filtering — use t.category_enum.

Theme + Subtheme — use separate MATCH clauses from cft, NOT chained paths: Good: MATCH (cft)-[:HAS_THEME]->(t:Theme) MATCH (cft)-[:HAS_SUBTHEME]->(st:Subtheme) Bad: MATCH (t)-[:HAS_SUBTHEME]->(st) -- follows taxonomy hierarchy, not tags

Citations: always return nli.record_id (NOT fi.record_id — creates broken links). Inequality: use != (not <>). Compiler rejects <>. Exclusion: use NOT IN ['Gong', 'Zoom'] (not chained != ... AND != ...). Boolean: use OR in a single query, not separate queries. Operator precedence: always parenthesize OR groups when combined with AND. Good: WHERE (a OR b OR c) AND t.type != 'MISC' Bad: WHERE a OR b OR c AND t.type != 'MISC' -- AND only applies to last OR term Aliases: use 'total' not 'count' (reserved word). ORDER BY alias name.

Exploratory Depth (CRITICAL for quality)

Two DIFFERENT hierarchies exist — do not confuse them:

  • L1 → L2 → L3: product taxonomy (feature areas). L3 is a finer category, NOT a complaint.

Example: L1="Platform", L2="Integrations", L3="Slack Integration"

  • Theme → Subtheme: user opinions/complaints about those features.

Example: Theme="Slack Sync Delays", Subtheme="Sync fails during peak hours"

L3 ≠ Theme. L3 tells you WHICH feature. Theme tells you WHAT users say about it. "What are complaints?" → needs Theme (t.name), NOT L3. "What features exist?" → needs L2/L3.

For exploratory "what" questions, you MUST drill to the opinion level:

When user asks about complaints, issues, pain points, or frustrated users:

  • The answer must include t.name (specific complaint themes), not just L2/L3 feature names.
  • If combining with features: return BOTH l2.name AND t.name in the same query.
  • Do NOT run separate queries — one for features, another for themes. Combine them.

When user asks about dominant themes or top themes:

  • The answer must include both t.name AND st.name (subtheme names).
  • Join Theme and Subtheme via separate MATCH from cft (not chained).

When user asks about issues in a specific area:

  • Scope to the L2 area, but return t.name (theme names) underneath — not l3.name.

When user asks about feature requests or improvements:

  • Same pattern as complaints but with IMPROVEMENT category filter.

Skip extra depth for: counts, sentiment, overview questions.

Good: RETURN l2.name AS feature, t.name AS complaint, COUNT(DISTINCT nli.record_id) AS total Bad: RETURN l2.name AS feature, COUNT(DISTINCT nli.record_id) AS total (Theme is joined for filtering but t.name is missing from RETURN — user only sees feature names)

Good: RETURN t.name AS theme, st.name AS subtopic, COUNT(DISTINCT nli.record_id) AS total Bad: RETURN t.name AS theme, COUNT(DISTINCT nli.record_id) AS total (Subtheme not included — user misses the specific sub-issues)

Rule: if you join Theme or Subtheme, ALWAYS include their name in RETURN.

Content Fields

fi.content = AI-generated summaries/chapters. Default for content search. One NLI → 5+ FeedbackInsights (e.g., Gong call → multiple topical chapters). Use for: searching volumes, topic discovery, general queries. nli.content = raw verbatim feedback (full transcripts, 50k+ chars). Use only to inspect candidate records; do not present returned nli.content as final quote text. Decision: "show feedback about X" → fi.content. "exact words" → nli.content. Always prefer taxonomy (Theme/L2/L3) over content text search when possible.

Quote Workflow

This tool is for finding candidate records, not extracting final user quotes. For quote/verbatim/exact-words requests:

  • Query only candidate metadata needed by find_user_quote: DISTINCT

nli.record_id, nli.record_timestamp, nli.source, and fi.content AS summary.

  • Do not return fi.content or nli.content as a column named quote/verbatim.
  • Do not render fi.content or nli.content as quoted text in the final answer.
  • After collecting candidate record_ids, call find_user_quote. If it returns no

validated quotes, do not substitute summaries, paraphrases, or raw content.

Field Types & Operators

Null checks: IS NOT NULL / IS NULL (never != null or = null). List fields (ratings, scores, tags) are stored as lists: Good: WHERE nli.appstore_rating CONTAINS '5' Bad: WHERE nli.appstore_rating = 5 -- fails on list fields Discover available values: RETURN DISTINCT nli.{field} LIMIT 20

Source-specific fields (ratings, tags, account names, custom metadata):

  • These are NOT in the base schema. You MUST call search_graph_fields first.
  • Qualify with the alias matching each field's entity group returned by

search_graph_fields: NLI/FeedbackRecord fields use nli.{source}_{field} (e.g. nli.appstore_rating, nli.g2_metadata_starrating); Account/User fields use the joined alias (e.g. acc.industry via PROVIDED_BY_ACCOUNT).

  • Always discover the exact field name via search_graph_fields before using it in queries.
  • For filtering by rating/score: use CONTAINS since values are stored as lists.
  • Common NLI source fields: nli.appstore_rating,

nli.appstore_country_full / nli.appstore_country_full_name, nli.g2_metadata_starrating, nli.gong_account_account_name, nli.gong_account_opportunity_name, nli.gong_metadata_title.

Supported Syntax

  • MATCH, OPTIONAL MATCH
  • WHERE with CONTAINS, =, !=, >, <, >=, <=, IS NULL, IS NOT NULL, IN, NOT IN, AND, OR, NOT
  • RETURN with aliases, ORDER BY, LIMIT, DISTINCT
  • COUNT(DISTINCT ...), SUM(), AVG(), MIN(), MAX()
  • toStartOfMonth/Week/Day(), now(), INTERVAL, toDateTime(), BETWEEN
  • CASE WHEN ... THEN ... ELSE ... END (prefer WITH for bucketed counts)
  • HAVING for post-aggregation filtering
  • COALESCE() for null fallbacks

OPTIONAL MATCH

Use when user asks to INCLUDE items WITHOUT a relationship (e.g., "include uncategorized"): Good: OPTIONAL MATCH (fi)-[:HAS_TAGS]->(cft)-[:BELONGS_TO_L2]->(l2) RETURN COALESCE(l2.name, 'Uncategorized') AS category, COUNT(DISTINCT nli.record_id) AS total Alternative — run TWO separate queries: Query 1: Count by category (normal MATCH with taxonomy) Query 2: Count total items (MATCH without taxonomy join) Then: Uncategorized = total - sum of categorized Both approaches are valid. Use whichever is simpler for the question. FAIL pattern: using only regular MATCH when user explicitly asks for uncategorized items.

CASE Expressions

Use CASE for bucketing/categorizing values. For grouped CASE bucket counts, prefer WITH ... CASE ... END AS bucket, then RETURN bucket, COUNT(DISTINCT ...). Good: WITH nli, CASE WHEN nli.source CONTAINS 'Gong' THEN 'Internal' WHEN nli.source CONTAINS 'Zendesk' THEN 'Support' ELSE 'Other' END AS channel RETURN channel, COUNT(DISTINCT nli.record_id) AS total Good: WITH nli, nps, CASE WHEN nps.value <= 6 THEN 'Detractor' WHEN nps.value <= 8 THEN 'Passive' ELSE 'Promoter' END AS category RETURN category, COUNT(DISTINCT nli.record_id) AS total Alternative: run separate queries per bucket with WHERE filters. Both approaches are valid.

Not Supported

  • STARTS WITH, ENDS WITH → use CONTAINS instead
  • SKIP / OFFSET → no pagination, use LIMIT only
  • <> operator → use != instead
  • Multiple WITH clauses / WITH + COLLECT chains
  • substring(), toString(), DATE_TRUNC(), LOWER(), UPPER(), regex

Post-Aggregation Filtering

Use HAVING (not WITH...WHERE): Good: RETURN source, COUNT(DISTINCT nli.record_id) AS total HAVING total > 100 Bad: WITH source, COUNT(...) AS total WHERE total > 100 Use HAVING for: "sources with more than 100 items", "themes with at least 50 complaints", "show only high-volume channels", any threshold on aggregated counts.

Deal/Opportunity Queries

  • "Deal" = "Opportunity". ALWAYS MATCH (opp:Opportunity), never (d:Deal).
  • All deal queries START from (opp:Opportunity). Never from DealReport,

envelopes, or leaf entities.

  • Time filter on deals: use opp.close_date (NOT nli.record_timestamp).
  • Stage filtering: opp.stage CONTAINS 'Won' or 'Lost'.
  • "Recently closed" means ALL closed deals (Won + Lost), not just Won.

Analysis pivot: (opp:Opportunity)-[:IS_ANALYSED_AS]->(dr:DealReport)

DealReport branches by prediction type, each via its own envelope:

  • Win/loss: (dr)-[:HAS_WINLOSS_PREDICTION]->(wle:DealWinLossEnvelope)

-[:REFERS_TO_WINLOSS_REASON]->(wlr:WinLossReason) Alt one-hop: (dr)-[:HAS_WIN_LOSS_REASON]->(wlr:WinLossReason). Use wlr.name for reason text. Filter opp.stage CONTAINS 'Won' or 'Lost'.

  • Competitors: (dr)-[:HAS_COMPETITOR_PREDICTION]->(dce:DealCompetitorEnvelope)

-[:REFERS_TO_COMPETITOR]->(c:Competitor) Use c.name for competitor name.

  • Use Cases: (dr)-[:HAS_USE_CASE_PREDICTION]->(due:DealUseCaseEnvelope)

-[:REFERS_TO_USE_CASE]->(uc:UseCase) Use uc.name for use case name.

  • Features: (dr)-[:HAS_FEATURE_PREDICTION]->(dfe:DealFeatureEnvelope)

-[:REFERS_TO_FEATURE]->(df:DealFeature) Filter dfe.mention_type for COMPLAINT/PRAISE. NEVER use L2/L3/Theme/CFT for "features in deals".

Feedback from deals — two DIFFERENT paths, do not confuse them:

  • ALL feedback on a deal (any topic):

(opp:Opportunity)-[:HAS_FEEDBACK_RECORD]->(nli:NaturalLanguageInteraction) Return fi.content verbatims, not just metadata. Use DISTINCT for samples.

  • Insight-specific feedback (deals lost due to X, competitor mentions, etc.):

envelope pivot → leaf filter + (envelope)-[:HAS_EVIDENCE]->(ev:Evidence)-[:HAS_FEEDBACK]->(nli:NaturalLanguageInteraction) NEVER use HAS_FEEDBACK_RECORD for insight-specific — it returns ALL feedback.

Out of Scope

Decline without executing queries: creating/modifying platform artifacts, exporting files, rendering charts, UI navigation, product how-to questions. Never name platform tools (Quantify, dashboards) unless the user mentioned them first. Never expose internal queries (Cypher, SQL) to the user.

Args: cypher_query: Valid Cypher query following the rules above. If the user asked "how many", "all", "total", "count", or "every" — do NOT add a LIMIT clause. description: Plain language description of your information need.

Returns: Structured query results with row count, columns, and data. If source-specific metadata is available, also includes relevant_source_fields.

Current date for relative date resolution: 2026-06-04 UTC.

CITATION URLS: The response carries a `rows_v2 field where every COUNT cell is wrapped as {"value": <number>, "citation": "<dashboard URL>"}. When rows_v2 is populated, rows is empty — use rows_v2 exclusively and wrap the cited number (plus its noun / qualifier when present in prose) inside a markdown link so the URL fires when the reader clicks the claim:

  • prose: [42 complaints](https://dashboard.../citations/...)
  • table cell: [42](https://dashboard.../citations/...)`

Don't fabricate URLs; only use ones returned by this tool.

Parameters (1 required, 1 optional)
Required
cypher_querystring
Optional
descriptionstring
Default: Executing query

Search Graph Fields

search_graph_fields
Full Description

Get source-specific metadata fields available for filtering and grouping.

Only call this if get_graph_schema returned has_source_fields=true. Returns fields like zendesksupport_status, gong_metadata_title, appstore_rating, g2_metadata_starrating — these are NOT in get_graph_schema.

HOW TO CALL: Include the source name in your query for better matches. Good: "zendesk ticket status and tags" Good: "zendesk tags customer experience" Good: "gong call title and account name" Good: "appstore rating country" Good: "g2 star rating" Bad: "billing issues" (too vague, may return wrong source's fields)

HOW TO USE RETURNED FIELDS:

  • Use the exact field names in Cypher WHERE and RETURN clauses
  • Format: {alias}.{field_name}, where {alias} matches the entity group each

field is listed under in the response. NLI/FeedbackRecord fields use nli.*; Account/User fields use the joined alias (see the per-entity prefix block appended to results for the exact MATCH pattern).

  • PREFER source-specific fields over fi.content search when the field exists

Good (NLI): WHERE nli.zendesksupport_status CONTAINS 'solved' Good (Account): MATCH (...)-[:PROVIDED_BY_ACCOUNT]->(acc:Account) WHERE acc.industry CONTAINS 'Retail' Bad: WHERE fi.content CONTAINS 'Acme' (broad, may match irrelevant content) Bad: WHERE nli.industry CONTAINS 'Retail' (industry is on Account, not NLI)

  • When multiple similar fields exist (e.g., countryiso2 vs country_full_name),

prefer the human-readable variant for filtering

RATING/SCORE FIELDS (stored as lists — use CONTAINS, not =): Good: WHERE nli.appstore_rating CONTAINS '1' (filters 1-star reviews) Good: WHERE nli.g2_metadata_starrating CONTAINS '2' (filters 2-star G2 reviews) Bad: WHERE nli.appstore_rating = 1 (fails — ratings are list fields) To combine with other filters, always parenthesize OR groups: Good: WHERE nli.appstore_rating CONTAINS '1' AND (nli.appstore_country_full CONTAINS 'US' OR nli.appstore_country_full_name CONTAINS 'United States')

Args: query: Include the source name (zendesk, gong, appstore, etc.) for best results top_k: Number of source groups to return (default: 10)

Returns: Matched fields grouped by entity and source platform.

Parameters (1 required, 1 optional)
Required
querystring
Optional
top_kinteger
Default: null

Search Graph Values

search_graph_values
Full Description

Search the Knowledge Graph to discover exact entity names before writing Cypher.

Pass a list of related terms for ONE concept. The tool searches each term separately and merges results — giving you the best coverage for spelling and case variants.

ONE CONCEPT = ONE CALL with related terms in the queries list: search(queries=["UI", "changes", "interface"]) — UI changes topic search(queries=["ApplePay", "Apple Pay"]) — spelling variants search(queries=["event", "forwarding"]) — feature name search(queries=["SMB", "smb"]) — case variants

DIFFERENT CONCEPTS = SEPARATE PARALLEL CALLS: search_graph_values(queries=["Zendesk"]) ← source (call 1) search_graph_values(queries=["NPS"]) ← metric (call 2) search_graph_values(queries=["bucket"]) ← field (call 3) search_graph_values(queries=["spenders"]) ← value (call 4)

EXTRACTION PROCESS

Before calling, extract ALL concepts from the user's question: 1. List every distinct concept: source names, filter values, field names, topics 2. Group related terms/variants under the same concept 3. Each concept = one search call, execute SEPARATE PARALLEL calls

Example: "NPS for bucket values 'spenders' from Zendesk for SMB" → 5 parallel calls: search(queries=["Zendesk", "zendesk"]) — source search(queries=["bucket"]) — field search(queries=["NPS", "nps"]) — metric search(queries=["spenders"]) — value search(queries=["SMB", "smb"]) — segment

⚠️ NEVER combine UNRELATED concepts in one call: ✗ search(queries=["Zendesk", "NPS", "bucket"]) — 3 different concepts ✗ search(queries=["churn", "cancellation", "leave", "uninstall"]) — kitchen sink WHY: Combining hides which term failed. Each concept needs individual validation.

⚠️ ALWAYS search SOURCE NAMES (often missed!): "Compare Zendesk vs Gong" → two calls: search(queries=["Zendesk"]), search(queries=["Gong"]) Source names vary by org: Zendesk vs Zendesk-Tickets vs zendesksupport.

WHEN SEARCH RETURNS EMPTY — do NOT use the unverified term: 1. search(queries=["spenders"]) → EMPTY 2. Run discovery: RETURN DISTINCT nli.{field} LIMIT 20 3. Map user's term to closest actual value 4. Use discovered value in Cypher

Args: queries: List of related terms for ONE concept — each term is searched separately and results are merged. Use a single-element list for the simple case (e.g. ["Zendesk"]). entity_types: Optional list of entity types to search, such as ["Theme", "L2"] limit: Maximum number of results per term (default: 10)

Returns: Search results with matched entities, property paths, values, and scores.

Parameters (1 required, 2 optional)
Required
queriesarray
Optional
entity_typesarray
Default: null
limitinteger
Default: 10