מניעת הלבנת הון והונאות באמצעות BigQuery GraphRAG

1. מבוא

ב-Codelab הזה תבנו פתרון Graph Retrieval-Augmented Generation (יצירה משולבת-אחזור של גרפים, GraphRAG) כדי לזהות הלבנת הון (AML) והונאות פיננסיות. תשתמשו ב-Vertex AI, בחיפוש וקטורי וביכולות הגרף המובנות של BigQuery, בתיאום באמצעות LangChain. בסיום שיעור ה-Lab הזה תראו איך מודל שפה גדול (LLM) יכול לזהות ניתוב לא חוקי של כספים על ידי סינתזה של יומני ביקורת סמנטיים ורשתות מורכבות של עסקאות.

תרשים הארכיטקטורה של GraphRAG

+------------------+     1. Vector Search      +---------------------+
| User Prompt /    | ------------------------> | BigQuery ML         |
| Investigation    |                           | (AccountAudits)     |
+------------------+                           +---------------------+
         |                                                |
         |                                                | 2. Seed Entity ID
         v                                                v
+------------------+     3. GQL Traversal      +---------------------+
| LangChain        | <------------------------ | BigQuery Property   |
| Graph Retriever  |                           | Graph (FinGraph)    |
+------------------+                           +---------------------+
         |
         | 4. Synthesized Context
         v
+------------------+
| Gemini 2.5 Flash | ---> Detailed Fraud Report
+------------------+

הפעולות שתבצעו:

  • שלב 1: הגדרת מערך הנתונים וגרף המאפיינים: יוצרים טבלאות פיננסיות רלציוניות ומבנים PROPERTY GRAPH מקורי של BigQuery.
  • שלב 2: יצירת הטמעות וקטוריות סמנטיות: יצירת הטמעות טקסט ישירות ב-SQL ליומני ביקורת באמצעות AI.GENERATE_EMBEDDING (text-embedding-005).
  • שלב 3: כלי אחזור (Retriever) מותאם אישית של LangChain GraphRAG: בניית כלי אחזור מותאם אישית של Python שמשלב דמיון וקטורי (COSINE_DISTANCE) ומעברים בנתיב ISO GQL.
  • שלב 4: ניתוח הונאות באמצעות LLM והמחשה ויזואלית של נתיבי העברה: מריצים שרשרת ניתוח של Gemini כדי לחשוף לולאות לא חוקיות של הלבנת הון ולהמחיש ויזואלית את נתיבי ההעברה ב-BigQuery Studio.

הדרישות

  • דפדפן אינטרנט כמו Chrome.
  • פרויקט ב-Google Cloud שהחיוב בו מופעל.

ה-Codelab הזה מיועד למפתחים, למהנדסי נתונים ולמומחי AI בכל הרמות, כולל מתחילים.

משך הזמן המשוער: 35 דקות
העלות המשוערת: פחות מ-2.00 דולר ארה"ב (השימוש הוא ב-Vertex AI וב-BigQuery לפי תשלום על פי שימוש).

‫2. לפני שמתחילים

יצירת פרויקט ב-Google Cloud

  1. במסוף Google Cloud, בוחרים או יוצרים פרויקט בענן של Google.
  2. הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud.

הפעלת Cloud Shell

  1. לוחצים על Activate Cloud Shell בחלק העליון של מסוף Google Cloud.
  2. אימות האימות:
gcloud auth list
  1. מגדירים משתני סביבה ב-Cloud Shell:
export GCP_PROJECT=$(gcloud config get-value project)
export REGION="us-central1"
export BQ_DATASET="fingraph_rag"
gcloud config set project $GCP_PROJECT

הפעלת ממשקי ה-API

מריצים את הפקודה הבאה כדי להפעיל את כל ממשקי ה-API הנדרשים:

gcloud services enable \
 bigquery.googleapis.com \
 aiplatform.googleapis.com

3. הגדרה ואתחול

בשלב הזה נגדיר סביבת Python, נתקין את הספריות הנדרשות ונפעיל את הלקוחות של BigQuery ו-Vertex AI. אפשר להריץ את הפקודות האלה ב-Cloud Shell או בסביבת מחברת Jupyter.

  1. יוצרים ומפעילים סביבה וירטואלית של Python:
python3 -m venv venv
source venv/bin/activate
  1. מתקינים את חבילות Python הנדרשות:
pip install langchain-google-vertexai langchain-core google-cloud-bigquery vertexai
  1. יוצרים קובץ Python בשם graphrag_aml.py ומוסיפים את קוד האתחול. מחליפים את במזהה הפרויקט ב-Google Cloud.
import vertexai
from google.cloud import bigquery

# Configuration
GCP_PROJECT_ID = "<YOUR_PROJECT_ID>"
REGION = "us-central1"
BQ_DATASET_ID = "fingraph_rag"
MODEL_NAME = "gemini-2.5-flash"

# Initialize clients
bq_client = bigquery.Client(project=GCP_PROJECT_ID)
vertexai.init(project=GCP_PROJECT_ID, location=REGION)

4. יצירת טבלאות וסכימה

בשלב הבא, מגדירים את הסכימה של הגרף הפיננסי על ידי יצירת מערך נתונים וטבלאות רגילות ב-BigQuery.

  1. יוצרים את מערך הנתונים ב-BigQuery:
bq mk --location=US --dataset fingraph_rag
  1. יוצרים את הטבלאות. אפשר להריץ את הפקודה הזו בממשק המשתמש של BigQuery Studio או דרך Cloud Shell. הנה ה-SQL:
CREATE TABLE IF NOT EXISTS `fingraph_rag.Account` (id INT64, create_time TIMESTAMP, is_blocked BOOL, type STRING);
CREATE TABLE IF NOT EXISTS `fingraph_rag.Loan` (id INT64, loan_amount FLOAT64, balance FLOAT64, create_time TIMESTAMP, interest_rate FLOAT64);
CREATE TABLE IF NOT EXISTS `fingraph_rag.Person` (id INT64, name STRING);
CREATE TABLE IF NOT EXISTS `fingraph_rag.AccountRepayLoan` (id INT64, loan_id INT64, amount FLOAT64, create_time TIMESTAMP);
CREATE TABLE IF NOT EXISTS `fingraph_rag.AccountTransferAccount` (id INT64, to_id INT64, amount FLOAT64, create_time TIMESTAMP);
CREATE TABLE IF NOT EXISTS `fingraph_rag.PersonOwnAccount` (id INT64, account_id INT64, create_time TIMESTAMP);
CREATE TABLE IF NOT EXISTS `fingraph_rag.AccountAudits` (id INT64, audit_timestamp TIMESTAMP, audit_details STRING, embedding ARRAY<FLOAT64>);

5. הוספת מערך הנתונים

עכשיו נכניס את הישויות ואת הקשרים ביניהן כדי ליצור את שרשרת העברות הכספים. מערך הנתונים הזה מייצג את הפעילויות החשודות בין Doe (בעלים של חברת קש חשודה), Jacoby (מתווך), Menville (יעד שנכשל ב-KYC) ו-Smith (צופה תמים מהצד).

מריצים את ה-SQL הבא כדי לאכלס את הטבלאות:

INSERT INTO `fingraph_rag.Account` VALUES 
  (10,'2020-01-10 06:22:20.222',false,'brokerage account'), 
  (20,'2020-01-27 17:55:09.206',false,'checking account'), 
  (30,'2020-02-15 09:12:33.111',false,'savings account'), 
  (40,'2019-11-05 14:33:10.000',false,'business account');

INSERT INTO `fingraph_rag.Loan` VALUES 
  (100,2022278.5,123359.0,'2020-03-18 16:42:57.719',0.064), 
  (200,50000.0,45000.0,'2020-03-23 19:03:05.567',0.097), 
  (300, 15000.0, 10000.0, '2020-05-10 10:00:00.000', 0.05);

INSERT INTO `fingraph_rag.Person` VALUES 
  (1,'Jacoby'), (2,'Menville'), (3,'Smith'), (4,'Doe');

INSERT INTO `fingraph_rag.AccountTransferAccount` VALUES 
  (40,10,25000.0,'2020-08-01 10:00:00.000'), 
  (10,20,24000.0,'2020-08-29 15:28:58.647'), 
  (30,20,150.0,'2020-09-01 12:00:00.000');

INSERT INTO `fingraph_rag.AccountRepayLoan` VALUES 
  (10,100,56809.8,'2020-12-12 07:25:02.597'), 
  (20,200,20000.0,'2021-01-18 01:40:25.317');

INSERT INTO `fingraph_rag.PersonOwnAccount` VALUES 
  (1,10,'2020-01-10 06:22:20.222'), (2,20,'2020-01-27 17:55:09.206'), 
  (3,30,'2020-02-15 09:12:33.111'), (4,40,'2019-11-05 14:33:10.000');

INSERT INTO `fingraph_rag.AccountAudits` (id, audit_timestamp, audit_details) VALUES 
  (10, '2020-05-14 06:57:02', 'Account 10 (Jacoby) flagged by AML system for suspicious high-volume transfers from offshore business accounts.'), 
  (20, '2021-03-09 02:51:45', 'Account 20 (Menville) failed KYC verification. Linked source of funds is unverified and customer is unresponsive.'), 
  (40, '2020-07-20 09:00:00', 'Account 40 (Doe) under investigation as a suspected shell company involved in illicit activities.');

אימות הרשומות שהועברו

מריצים את השאילתה הזו כדי לאמת את מספר הרשומות בטבלאות הפיננסיות:

SELECT 'Account' AS entity_table, COUNT(*) AS row_count FROM `fingraph_rag.Account`
UNION ALL SELECT 'Loan', COUNT(*) FROM `fingraph_rag.Loan`
UNION ALL SELECT 'Person', COUNT(*) FROM `fingraph_rag.Person`
UNION ALL SELECT 'AccountAudits', COUNT(*) FROM `fingraph_rag.AccountAudits`;

הפלט של השאילתה אמור לאשר את הוספת השורה, ולראות כך:

בדיקת תוצאות השאילתה כדי לוודא שהרשומות הוכנסו

6. יצירת גרף מאפיינים ב-BigQuery

אחרי שמיקמנו את הנתונים הרלציוניים, אנחנו מגדירים את FinGraph באמצעות Graph DDL המקורי של BigQuery. הפעולה הזו יוצרת שכבה סמנטית מעל טבלאות יחסיות קיימות בלי להעתיק או לשכפל נתונים.

‫ISO GQL Syntax Primer

בגרפים של נכסים ב-BigQuery נעשה שימוש בדפוסי Graph Query Language‏ (GQL) רגילים של ISO:

  • (node:Label) מגדיר צמתי ישויות (למשל Account, ‏ Person, ‏ Loan).
  • -[edge:LABEL]-> מגדיר קשרים ישירים (לדוגמה, Transfers,‏ Repays,‏ Owns).

מריצים את הצהרת ה-SQL הבאה כדי ליצור את גרף המאפיינים:

CREATE OR REPLACE PROPERTY GRAPH `fingraph_rag.FinGraph`
 NODE TABLES (
   `fingraph_rag.Account` KEY (id) LABEL Account PROPERTIES (id, type, is_blocked),
   `fingraph_rag.Loan` KEY (id) LABEL Loan PROPERTIES (id, loan_amount, balance),
   `fingraph_rag.Person` KEY (id) LABEL Person PROPERTIES (id, name)
 )
 EDGE TABLES(
   `fingraph_rag.AccountRepayLoan`
     KEY (id, loan_id, create_time)
     SOURCE KEY (id) REFERENCES `fingraph_rag.Account` (id)
     DESTINATION KEY (loan_id) REFERENCES `fingraph_rag.Loan` (id)
     LABEL Repays PROPERTIES (amount, create_time),
   `fingraph_rag.AccountTransferAccount`
     KEY (id, to_id, create_time)
     SOURCE KEY (id) REFERENCES `fingraph_rag.Account` (id)
     DESTINATION KEY (to_id) REFERENCES `fingraph_rag.Account` (id)
     LABEL Transfers PROPERTIES (amount, create_time),
   `fingraph_rag.PersonOwnAccount`
     KEY (id, account_id)
     SOURCE KEY (id) REFERENCES `fingraph_rag.Person` (id)
     DESTINATION KEY (account_id) REFERENCES `fingraph_rag.Account` (id)
     LABEL Owns PROPERTIES (create_time)
 );

כדי להציג את הגרף המלא של החשבונות, האנשים וההלוואות, מריצים את שאילתת ה-SQL הבאה ב-BigQuery Studio:

GRAPH `fingraph_rag.FinGraph`
MATCH (src)-[e]->(dst)
RETURN TO_JSON([
  TO_JSON(src),
  TO_JSON(e),
  TO_JSON(dst)
  ]) AS result;

אמורה להופיע תוצאה של תרשים ויזואליזציה שדומה לזה:

תרשים מלא להמחשה

7. יצירת הטמעות ליומני ביקורת

כדי להפעיל את החלק של חיפוש וקטורים בצינור ה-RAG שלנו, אנחנו יוצרים הטמעות טקסט ליומני הביקורת הלא מובנים ישירות ב-BigQuery באמצעות AI.GENERATE_EMBEDDING פונקציה להחזרת טבלה (TVF).

יצירת חיבור מרחוק ל-BigQuery והענקת הרשאות IAM

כדי ש-BigQuery ML יוכל לתקשר בצורה מאובטחת עם נקודות הקצה של הטמעת Vertex AI, נדרש CLOUD_RESOURCE חיבור. כדי ליצור את החיבור, לגלות את חשבון השירות שנוצר אוטומטית ולהעניק את התפקיד Vertex AI User ‏ (roles/aiplatform.user), מריצים את פקודות ה-Bash הבאות ב-Cloud Shell:

# 1. Set environment variables
export PROJECT_ID=$(gcloud config get-value project)
export LOCATION="us"
export CONNECTION_ID="vertex_ai_conn"

# 2. Create the BigQuery Cloud Resource Connection
bq mk --connection \
    --location=${LOCATION} \
    --project_id=${PROJECT_ID} \
    --connection_type=CLOUD_RESOURCE \
    ${CONNECTION_ID}

# 3. Retrieve the auto-generated Service Account ID associated with the connection
SA_ID=$(bq show --format=json --location=${LOCATION} --connection ${CONNECTION_ID} | jq -r '.cloudResource.serviceAccountId')
echo "Connection Service Account: ${SA_ID}"

# 4. Grant Vertex AI User (roles/aiplatform.user) permission to the Service Account
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${SA_ID}" \
    --role="roles/aiplatform.user" \
    --condition=None

יצירת מודל הטמעה מרחוק

לאחר מכן, מגדירים מודל מרוחק של BigQuery ML שמקושר למודל text-embedding-005 של Vertex AI באמצעות החיבור החדש שאושר:

CREATE OR REPLACE MODEL `fingraph_rag.embedding_model`
  REMOTE WITH CONNECTION `us.vertex_ai_conn`
  OPTIONS(ENDPOINT = 'text-embedding-005');

יצירת הטמעות

עכשיו יוצרים הטבעות לטבלה AccountAudits על ידי קריאה ל-AI.GENERATE_EMBEDDING בסעיף FROM של הצהרת UPDATE:

UPDATE `fingraph_rag.AccountAudits` target
SET embedding = source.embedding
FROM AI.GENERATE_EMBEDDING(
  MODEL `fingraph_rag.embedding_model`,
  (SELECT id, audit_details AS content FROM `fingraph_rag.AccountAudits` WHERE ARRAY_LENGTH(embedding) = 0)
) source
WHERE target.id = source.id;

אימות המידות של וקטורים שנוצרו

מריצים את השאילתה הבאה כדי לוודא שהטמעות וקטוריות נוספו:

SELECT id, audit_details, ARRAY_LENGTH(embedding) AS embedding_dim 
FROM `fingraph_rag.AccountAudits`;

הפלט של השאילתה אמור להציג הטמעות של וקטורים ב-768 ממדים, בדומה לזה:

תוצאות השאילתה מאמתות את המאפיין 'וקטור שנוצר'

8. הגדרת כלי לאחזור מידע מסוג GraphRAG

עכשיו ניצור כלי אחזור (retriever) מותאם אישית של LangChain בסביבת Python שלנו. רכיב המאחזר הזה משלב חיפוש וקטורי סמנטי (כדי למצוא נקודות התחלה רלוונטיות) עם שאילתות Graph MATCH מקוריות (כדי לעבור בין קשרים).

מוסיפים את הקוד הבא לסקריפט Python graphrag_aml.py:

from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever
from typing import List

class FinGraphRetriever(BaseRetriever):
    project: str
    dataset: str

    def _get_relevant_documents(self, query: str) -> List[Document]:
        # 1. Vector Search
        vector_query = f"""
            SELECT id, audit_details
            FROM `{self.dataset}.AccountAudits`
            ORDER BY COSINE_DISTANCE(
                embedding,
                (
                    SELECT embedding
                    FROM AI.GENERATE_EMBEDDING(
                        MODEL `{self.dataset}.embedding_model`,
                        (SELECT @query AS content)
                    )
                )
            )
            LIMIT 1
        """
        res = bq_client.query(vector_query, job_config=bigquery.QueryJobConfig(
            query_parameters=[bigquery.ScalarQueryParameter("query", "STRING", query)]
        )).result()

        start_id = None
        audit_text = ""
        for row in res:
            start_id = row.id
            audit_text = row.audit_details

        if not start_id: return []

        # 2. Native Graph Traversal
        graph_query = f"""
            GRAPH `{self.dataset}.FinGraph`
            MATCH
              (sender_person:Person)-[:Owns]->(sender_acc:Account)
              -[tx:Transfers]->
              (a:Account)
              -[repays:Repays]->(l:Loan),
              (owner:Person)-[:Owns]->(a)
            WHERE a.id = @id
            RETURN
              owner.name as owner_name,
              a.type as account_type,
              sender_person.name as sender_name,
              tx.amount as transfer_amount,
              repays.amount as repayment_amount,
              l.id as loan_id
        """
        graph_res = bq_client.query(graph_query, job_config=bigquery.QueryJobConfig(
            query_parameters=[bigquery.ScalarQueryParameter("id", "INT64", start_id)]
        )).result()

        context_docs = [Document(page_content=f"Primary Audit Log (Target Account): {audit_text}")]
        sender_names = []
        for row in graph_res:
            sender_names.append(row['sender_name'])
            doc_str = (f"Account Owner: {row['owner_name']} (Account Type: {row['account_type']}). "
                       f"Received transfer of ${row['transfer_amount']} from {row['sender_name']}. "
                       f"Made loan repayment of ${row['repayment_amount']} to Loan {row['loan_id']}.")
            context_docs.append(Document(page_content=doc_str))

        if sender_names:
            names_list = "','".join(sender_names)
            sender_audit_query = f"""
                SELECT p.name, au.audit_details
                FROM `{self.dataset}.AccountAudits` au
                JOIN `{self.dataset}.Account` a ON au.id = a.id
                JOIN `{self.dataset}.PersonOwnAccount` poa ON a.id = poa.account_id
                JOIN `{self.dataset}.Person` p ON poa.id = p.id
                WHERE p.name IN ('{names_list}')
            """
            sender_audits = bq_client.query(sender_audit_query).result()
            for row in sender_audits:
                context_docs.append(Document(page_content=f"Audit Log for Sender {row['name']}: {row['audit_details']}"))

        return context_docs

9. הפעלת חקירת ההונאה

לבסוף, אנחנו מריצים את צינור הנתונים של GraphRAG כדי ליצור דוח מפורט על הונאה. מודל ה-LLM ישתמש בהקשר שאוחזר על ידי כלי אחזור הגרפים המותאם אישית שלנו כדי לענות על ההנחיה.

מוסיפים את הקוד הבא לסקריפט graphrag_aml.py ומריצים אותו באמצעות python graphrag_aml.py:

from langchain_google_vertexai import ChatVertexAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# Initialize the LLM and the Retriever
llm = ChatVertexAI(model_name=MODEL_NAME)
retriever = FinGraphRetriever(project=GCP_PROJECT_ID, dataset=BQ_DATASET_ID)

# Define the Prompt
prompt = ChatPromptTemplate.from_template("""
You are a Lead Fraud Analyst. Use the following audit logs and graph transaction history to answer the question.
Your goal is to connect the dots between the entities and explain the flow of funds.
If you see transfers from flagged users or shell companies, highlight the money laundering risk.

Context: {context}

Question: {question}

Detailed Fraud Report:
""")

# Create the LangChain
chain = (
    {"context": retriever , "question": lambda x: x}
    | prompt
    | llm
    | StrOutputParser()
)

# Execute the chain
question = "Why is Menville's loan repayment at risk? Flag any suspicious activity if you notice."
print(chain.invoke(question))

השלמת graphrag_aml.py סקריפט

לעיון, התסריט המלא של graphrag_aml.py אמור להיראות כך:

import vertexai
from google.cloud import bigquery
from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever
from typing import List
from langchain_google_vertexai import ChatVertexAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# Configuration
GCP_PROJECT_ID = "<YOUR_PROJECT_ID>"
REGION = "us-central1"
BQ_DATASET_ID = "fingraph_rag"
MODEL_NAME = "gemini-2.5-flash"

# Initialize clients
bq_client = bigquery.Client(project=GCP_PROJECT_ID)
vertexai.init(project=GCP_PROJECT_ID, location=REGION)

class FinGraphRetriever(BaseRetriever):
    project: str
    dataset: str

    def _get_relevant_documents(self, query: str) -> List[Document]:
        # 1. Vector Search using Cosine Distance
        vector_query = f"""
            SELECT id, audit_details
            FROM `{self.dataset}.AccountAudits`
            ORDER BY COSINE_DISTANCE(
                embedding,
                (
                    SELECT embedding
                    FROM AI.GENERATE_EMBEDDING(
                        MODEL `{self.dataset}.embedding_model`,
                        (SELECT @query AS content)
                    )
                )
            )
            LIMIT 1
        """
        res = bq_client.query(vector_query, job_config=bigquery.QueryJobConfig(
            query_parameters=[bigquery.ScalarQueryParameter("query", "STRING", query)]
        )).result()

        start_id = None
        audit_text = ""
        for row in res:
            start_id = row.id
            audit_text = row.audit_details

        if not start_id: return []

        # 2. Native Graph Traversal (GQL MATCH)
        graph_query = f"""
            GRAPH `{self.dataset}.FinGraph`
            MATCH
              (sender_person:Person)-[:Owns]->(sender_acc:Account)
              -[tx:Transfers]->
              (a:Account)
              -[repays:Repays]->(l:Loan),
              (owner:Person)-[:Owns]->(a)
            WHERE a.id = @id
            RETURN
              owner.name as owner_name,
              a.type as account_type,
              sender_person.name as sender_name,
              tx.amount as transfer_amount,
              repays.amount as repayment_amount,
              l.id as loan_id
        """
        graph_res = bq_client.query(graph_query, job_config=bigquery.QueryJobConfig(
            query_parameters=[bigquery.ScalarQueryParameter("id", "INT64", start_id)]
        )).result()

        context_docs = [Document(page_content=f"Primary Audit Log (Target Account): {audit_text}")]
        sender_names = []
        for row in graph_res:
            sender_names.append(row['sender_name'])
            doc_str = (f"Account Owner: {row['owner_name']} (Account Type: {row['account_type']}). "
                       f"Received transfer of ${row['transfer_amount']} from {row['sender_name']}. "
                       f"Made loan repayment of ${row['repayment_amount']} to Loan {row['loan_id']}.")
            context_docs.append(Document(page_content=doc_str))

        if sender_names:
            names_list = "','".join(sender_names)
            sender_audit_query = f"""
                SELECT p.name, au.audit_details
                FROM `{self.dataset}.AccountAudits` au
                JOIN `{self.dataset}.Account` a ON au.id = a.id
                JOIN `{self.dataset}.PersonOwnAccount` poa ON a.id = poa.account_id
                JOIN `{self.dataset}.Person` p ON poa.id = p.id
                WHERE p.name IN ('{names_list}')
            """
            sender_audits = bq_client.query(sender_audit_query).result()
            for row in sender_audits:
                context_docs.append(Document(page_content=f"Audit Log for Sender {row['name']}: {row['audit_details']}"))

        return context_docs

# Initialize LLM & Retriever
llm = ChatVertexAI(model_name=MODEL_NAME)
retriever = FinGraphRetriever(project=GCP_PROJECT_ID, dataset=BQ_DATASET_ID)

prompt = ChatPromptTemplate.from_template("""
You are a Lead Fraud Analyst. Use the following audit logs and graph transaction history to answer the question.
Your goal is to connect the dots between the entities and explain the flow of funds.
If you see transfers from flagged users or shell companies, highlight the money laundering risk.

Context: {context}

Question: {question}

Detailed Fraud Report:
""")

chain = (
    {"context": retriever, "question": lambda x: x}
    | prompt
    | llm
    | StrOutputParser()
)

question = "Why is Menville's loan repayment at risk? Flag any suspicious activity if you notice."
print(chain.invoke(question))

הפלט אמור להיות דומה לדוח הניתוח לדוגמה של מודל שפה גדול (LLM):

דוח ניתוח AML של תשובת LLM

10. הדמיה של נתיב הלבנת ההון

כדי להבין באופן ויזואלי את עקבות הלבנת ההון שגילינו זה עתה באופן פרוגרמטי, אפשר להריץ שאילתת ויזואליזציה של גרף במסוף BigQuery Studio.

מריצים את השאילתה הזו ב-BigQuery Studio. (חשוב לוודא שהפעלתם את התכונה 'המחשה של גרף' או ללחוץ על הכרטיסייה 'גרף' אם היא זמינה).

GRAPH `fingraph_rag.FinGraph`
 MATCH
   (p_shell:Person)-[o1:Owns]->(acc_shell:Account)-[t1:Transfers]->(acc_fraud:Account)-[t2:Transfers]->(acc_target:Account)-[r:Repays]->(l:Loan),
   (p_fraud:Person)-[o2:Owns]->(acc_fraud),
   (p_target:Person)-[o3:Owns]->(acc_target)
 WHERE p_target.name = 'Menville' AND p_fraud.name = 'Jacoby' AND p_shell.name = 'Doe'
 RETURN TO_JSON([
  TO_JSON(p_shell), TO_JSON(o1), TO_JSON(acc_shell),
  TO_JSON(t1), TO_JSON(acc_fraud), TO_JSON(p_fraud), TO_JSON(o2),
  TO_JSON(t2), TO_JSON(acc_target), TO_JSON(p_target), TO_JSON(o3),
  TO_JSON(r), TO_JSON(l)
]) AS result;

שאילתת GQL הזו עוקבת אחרי הנתיב המלא מבעל חברת הקש המעורר חשד (Doe) דרך המתווך (Jacoby) אל היעד הסופי (Menville) ואל החזר ההלוואה.

אמורה להופיע תוצאה של תרשים ויזואליזציה שדומה לזה:

המחשה סופית של תרשים AML

11. הסרת המשאבים

כדי להימנע מחיובים שוטפים בחשבון Google Cloud, מוחקים את המשאבים שנוצרו במהלך ה-codelab הזה.

מוחקים את מערך הנתונים ב-BigQuery ואת הקישור למשאבים ב-Cloud:

# Delete the BigQuery dataset
bq rm -r -f $PROJECT_ID:fingraph_rag

# Delete the BigQuery Cloud Resource Connection
bq rm --connection --location=us vertex_ai_conn

מוודאים שהמשאבים נמחקו:

bq ls --project_id $PROJECT_ID
bq ls --connection --location=us

12. מזל טוב

מעולה! יצרתם בהצלחה אפליקציית RAG וניתחתם את ההתנהגות שלה. הדגמת איך להשתמש ביכולות המובנות של BigQuery Graph וחיפוש וקטורי כדי לבצע GraphRAG, ולזהות תרמית להלבנת הון ללא ETL.

מה למדתם

  • איך יוצרים גרף מאפיינים ב-BigQuery על בסיס טבלאות רגילות
  • איך ליצור ולאחסן הטמעות וקטוריות באמצעות BigQuery ML
  • איך לשלב בין מעברים ב-BigQuery Graph לבין חיפוש וקטורי בכלי LangChain Retriever
  • איך מודלים גדולים של שפה (LLM) יכולים לסנתז יומני ביקורת סמנטיים עם טופולוגיית גרף כדי להפחית את מספר התוצאות החיוביות הכוזבות

השלבים הבאים

מסמכים לדוגמה