Building a guided conversational chatbot with GraphRAG

更新时间:
复制 MD 格式

The GraphRAG service in AnalyticDB for PostgreSQL uses decision trees to power multi-turn, guided customer service conversations. Instead of free-form retrieval augmented generation (RAG), GraphRAG navigates a structured question tree to narrow down user problems and deliver precise solutions—making it well suited for after-sales support, fault diagnosis, and other scenarios where the conversation path is known in advance.

How it works

A decision tree organizes diagnostic knowledge as a hierarchy of questions and answers:

  • Root node: the opening question

  • Internal nodes: follow-up questions that narrow the problem

  • Branches: the user's possible responses

  • Leaf nodes: the final resolution or action

GraphRAG stores this tree as a knowledge graph in AnalyticDB for PostgreSQL and uses semantic similarity to match user replies to the correct branch at each turn. When a user's reply is semantically closer to a node deeper in the tree than to the immediate next step, GraphRAG can skip intermediate questions and jump directly to the relevant node. This reduces unnecessary back-and-forth while still delivering the right answer.

A simple air conditioner decision tree looks like this:

image

How semantic matching works at runtime:

At each conversation turn, GraphRAG runs two searches in parallel:

  • Local search: finds the best-matching child node of the current node

  • Global search: finds the best-matching node across the entire tree

If the global search score exceeds the local search score by at least global_distance_threshold (default: 0.1), GraphRAG jumps directly to the globally matched node, skipping intermediate steps. Adjust this threshold to control how aggressively GraphRAG takes shortcuts: lower values trigger jumps more readily, higher values keep the conversation on the sequential path.

Prerequisites

Before you begin, make sure you have:

  • An AnalyticDB for PostgreSQL 7.0 instance with minor engine version 7.2.1.3 or later

    Versions 7.3.0.0 and 7.3.1.0 do not support the adbpg_graphrag extension. To check your instance's minor engine version, go to the Basic Information page in the AnalyticDB for PostgreSQL console. To upgrade, see Update the minor engine version.
  • The plpython3u and age extensions installed (see Install extensions)

  • The adbpg_graphrag extension installed by technical support (see step 3 below)

Install extensions

On instances with minor engine version 7.2.1.4 or later, plpython3u, age, and adbpg_graphrag are installed automatically. Skip to adding ag_catalog to the search path.

For earlier versions, install the three extensions in order:

1. Verify the plpython3u extension

The plpython3u extension is installed by default. Confirm it is active in your target database:

SELECT * FROM pg_extension WHERE extname = 'plpython3u';

Expected output:

  oid  |  extname   | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
-------+------------+----------+--------------+----------------+------------+-----------+--------------
 14674 | plpython3u |       10 |           11 | f              | 1.0        |           |
(1 row)

If no rows are returned, install the plpython3u extension before continuing.

2. Configure the age extension

Install the Apache AGE extension, then add ag_catalog to the search path so you can run graph queries without schema-qualifying every statement.

For the current session only:

SET search_path TO "$user", public, ag_catalog;

Permanently for the database:

ALTER DATABASE <database_name> SET search_path TO "$user", public, ag_catalog;

To let other users run graph queries, grant them access to the ag_catalog schema. Use the initial account or a privileged user with the RDS_SUPERUSER role:

GRANT USAGE ON SCHEMA ag_catalog TO <username>;

3. Install the adbpg_graphrag extension

The adbpg_graphrag extension depends on plpython3u and age. Contact technical support to install it after confirming those two extensions are active.

Set up GraphRAG

Step 1: Initialize the service

Call adbpg_graphrag.initialize with a JSON configuration object to set up the service.

SELECT adbpg_graphrag.initialize(config json);

Parameters

ParameterDescriptionDefault
llm_modelLarge language model (LLM) used for conversationqwen-max-2025-01-25
embedding_modelEmbedding model used for similarity searchtext-embedding-v3
languageLanguage for responses. Options: English, Simplified ChineseEnglish
entity_typesEntity node types to extract when building the knowledge graph
relationship_typesRelationship edge types to extract when building the knowledge graph
first_node_contentOpening message sent at the start of every conversationHello, how can I help you?
end_node_contentClosing message sent after the final resolution is reachedAre there any other questions?
global_distance_thresholdControls jump navigation. If the global search score exceeds the local search score by at least this value, GraphRAG skips intermediate nodes and jumps to the globally matched node. Lower values trigger jumps more aggressively; higher values keep the conversation closer to the sequential path.0.1

Step 2: Import a decision tree

Decision trees are imported as Markdown-formatted text. Indentation defines the parent-child relationship between nodes.

Air conditioner example tree:

Hello, how can I help you?
    The air conditioner's cooling effect is poor
        Is the machine not blowing air or not cooling
            The machine is not cooling
                Please provide the operating mode of the air conditioner
                    Cooling mode
                        Has the filter not been cleaned for a long time
                            Yes
                                Please clean the filter and then observe the cooling performance of the air conditioner
                            No
                                Please call our repair hotline, a maintenance engineer will visit for inspection
                    Non-cooling mode
                        Please switch to cooling mode
            The machine is not blowing air
                Does the air conditioner display a sensor fault
                    Yes
                        Please power off the air conditioner for 3 minutes and restart it, to see if it returns to normal
                    No
                        Please call our repair hotline, a maintenance engineer will visit for inspection
    No more issues
        Complete

Two import methods are available:

Import directly

Pass the tree content directly to upload_decision_tree:

SELECT adbpg_graphrag.upload_decision_tree(original_content text, root_content text);
ParameterDescription
original_contentAll tree content excluding the root node
root_contentThe root node text

Example:

SELECT adbpg_graphrag.upload_decision_tree(
  'The air conditioner''s cooling effect is poor
      Is the machine not blowing air or not cooling
          The machine is not cooling
              Please provide the operating mode of the air conditioner
                  Cooling mode
                      Has the filter not been cleaned for a long time
                          Yes
                              Please clean the filter and then observe the cooling performance of the air conditioner
                          No
                              Please call our repair hotline, a maintenance engineer will visit for inspection
                  Non-cooling mode
                      Please switch to cooling mode
          The machine is not blowing air
              Does the air conditioner display a sensor fault
                  Yes
                      Please power off the air conditioner for 3 minutes and restart it, to see if it returns to normal
                  No
                      Please call our repair hotline, a maintenance engineer will visit for inspection
  No more issues
      Complete',
  'Hello, how can I help you?'
);

Import from a table

For larger trees or programmatic workflows, store the tree in a table first.

  1. Create the table and insert the tree content:

    CREATE TABLE documents_text (id integer, original_content text);
    
    INSERT INTO documents_text VALUES (1, 'The air conditioner''s cooling effect is poor
            Is the machine not blowing air or not cooling
                The machine is not cooling
                    Please provide the operating mode of the air conditioner
                        Cooling mode
                            Has the filter not been cleaned for a long time
                                Yes
                                    Please clean the filter and then observe the cooling performance of the air conditioner
                                No
                                    Please call our repair hotline, a maintenance engineer will visit for inspection
                        Non-cooling mode
                            Please switch to cooling mode
                The machine is not blowing air
                    Does the air conditioner display a sensor fault
                        Yes
                            Please power off the air conditioner for 3 minutes and restart it, to see if it returns to normal
                        No
                            Please call our repair hotline, a maintenance engineer will visit for inspection
        No more issues
            Complete');
  2. Import the tree from the table:

    SELECT adbpg_graphrag.upload_decision_tree(original_content, 'Hello, how can I help you?')
    FROM documents_text
    WHERE id = 1;

Run multi-turn conversations

All conversations use adbpg_graphrag.query('user input', 'tree'). GraphRAG maintains session state between calls and advances the tree based on semantic matching.

Sequential conversation

Each response follows the next node in the tree:

Round 1:

SELECT adbpg_graphrag.query('Hello', 'tree');
          query
--------------------------
 Hello, how can I help you?
(1 row)

Round 2:

SELECT adbpg_graphrag.query('The air conditioner is not cooling', 'tree');
              query
--------------------------------
 Is the machine not blowing air or not cooling
(1 row)

Round 3:

SELECT adbpg_graphrag.query('The air conditioner is not blowing air', 'tree');
             query
---------------------------
 Does the air conditioner display a sensor fault
(1 row)

Round 4:

SELECT adbpg_graphrag.query('Yes', 'tree');
                          query
-----------------------------------------
 Please power off the air conditioner for 3 minutes and restart it, to see if it returns to normal
(1 row)

Round 5:

SELECT adbpg_graphrag.query('OK', 'tree');
          query
--------------------------
 Do you have any other questions?
(1 row)

Jump navigation

When a user's reply is semantically closer to a deeper node than to the immediate next question, GraphRAG jumps directly to that node—skipping intermediate steps. The global_distance_threshold parameter controls how sensitive this behavior is.

Round 1:

SELECT adbpg_graphrag.query('Hello', 'tree');
          query
--------------------------
 Hello, how can I help you?
(1 row)

Round 2 — the user describes the problem specifically, so GraphRAG jumps past the intermediate question:

SELECT adbpg_graphrag.query('The machine is not blowing air', 'tree');
             query
---------------------------
 Does the air conditioner display a sensor fault
(1 row)

Round 3:

SELECT adbpg_graphrag.query('It shows F1 error code', 'tree');
                          query
--------------------------------------------
 Please call our repair hotline, a maintenance engineer will visit for inspection
(1 row)

Round 4:

SELECT adbpg_graphrag.query('good', 'tree');
          query
--------------------------
 Do you have any other questions?
(1 row)

Reset the conversation

To start a new conversation, clear the session state:

SELECT adbpg_graphrag.reset_tree_query();
       reset_tree_query
-------------------------------
 Successful! Reset Tree Query.
(1 row)

Manage decision trees

After importing a tree, you can add or remove subtrees without reimporting the entire tree.

All tree management operations require the entity_id of the target node. Get it using one of these methods:

  • Age-Viewer: Open the Age-Viewer visualization tool and hover over the node.

  • Cypher query: Run the following to list all nodes and their IDs:

    SELECT * FROM cypher('chunk_entity_relation', $$
      MATCH (V)-[R:DIRECTED]-(V2)
      RETURN V, R, V2
    $$) AS (V agtype, R agtype, V2 agtype);

Add a subtree

Append a new subtree under an existing node:

SELECT adbpg_graphrag.append_decision_tree(context text, root_node_id text);
ParameterDescription
contextMarkdown-formatted subtree content to append
root_node_idThe entity_id of the node to attach the subtree to

Delete a subtree

Remove a node and all its descendants:

SELECT adbpg_graphrag.delete_decision_tree(root_node_entity text);
ParameterDescription
root_node_entityThe entity_id of the subtree root to delete