Siwi (/ˈsɪwi/) عبارة عن PoC لنظام الحوار مع الرسم البياني المعرفي المدعوم بقاعدة بيانات الرسم البياني.
في الوقت الحالي، يعد هذا عرضًا توضيحيًا لروبوتات الحوار القائمة على المهام (وليس للأغراض العامة) مع KG (الرسم البياني المعرفي) الذي يستفيد من Nebula Graph باستخدام الحد الأدنى/عينة مجموعة البيانات من Nebula Graph Manual/ NG中文手册.
نصائح: الآن يمكنك اللعب بالرسم البياني عبر الإنترنت دون تثبيته بنفسك!
ملعب السديم | ملعب السديم - البر الرئيسى للصين
الاستعلامات المدعومة:
relation
:
serving
:
friendship
:
يمكنك تجربتها من الصفر هنا: https://siwei.io/learn/nebula-101-siwi-kgqa/
يعد هذا واحدًا من أكثر خطوط الأنابيب سذاجة لمجال معين/روبوت دردشة لغرض واحد مبني على الرسم البياني المعرفي.
الواجهة الخلفية (Siwi API) عبارة عن خادم API يعتمد على Flask:
يتلقى خادم Flask API الأسئلة في HTTP POST، ويستدعي واجهة برمجة تطبيقات الروبوت.
في جزء واجهة برمجة تطبيقات الروبوت، يوجد classfier (التحليل التوافقي، ومطابقة النوايا، وملء الفتحات)، وممثلي الأسئلة (استدعاء الإجراءات المقابلة للاستعلام عن الرسم البياني المعرفي باستخدام المقاصد والفتحات).
تم بناء الرسم البياني المعرفي على قاعدة بيانات الرسم البياني مفتوحة المصدر: Nebula Graph
الواجهة الأمامية عبارة عن تطبيق VueJS ذو صفحة واحدة (SPA):
┌────────────────┬──────────────────────────────────────┐
│ │ │
│ │ Speech │
│ ┌──────────▼──────────┐ │
│ │ Frontend │ Siwi, /ˈsɪwi/ │
│ │ Web_Speech_API │ A PoC of │
│ │ │ Dialog System │
│ │ Vue.JS │ With Graph Database │
│ │ │ Backed Knowledge Graph │
│ └──────────┬──────────┘ │
│ │ Sentence │
│ │ │
│ ┌────────────┼──────────────────────────────┐ │
│ │ │ │ │
│ │ │ Backend │ │
│ │ ┌──────────▼──────────┐ │ │
│ │ │ Web API, Flask │ ./app/ │ │
│ │ └──────────┬──────────┘ │ │
│ │ │ Sentence ./bot/ │ │
│ │ ┌──────────▼──────────┐ │ │
│ │ │ │ │ │
│ │ │ Intent matching, │ ./bot/classifier│ │
│ │ │ Symentic Processing │ │ │
│ │ │ │ │ │
│ │ └──────────┬──────────┘ │ │
│ │ │ Intent, Entities │ │
│ │ ┌──────────▼──────────┐ │ │
│ │ │ │ │ │
│ │ │ Intent Actor │ ./bot/actions │ │
│ │ │ │ │ │
│ └─┴──────────┬──────────┴───────────────────┘ │
│ │ Graph Query │
│ ┌──────────▼──────────┐ │
│ │ │ │
│ │ Graph Database │ Nebula Graph │
│ │ │ │
│ └─────────────────────┘ │
│ │
│ │
│ │
└───────────────────────────────────────────────────────┘
.
├── README.md
├── src
│ ├── siwi # Siwi-API Backend
│ │ ├── app # Web Server, take HTTP requests and calls Bot API
│ │ └── bot # Bot API
│ │ ├── actions # Take Intent, Slots, Query Knowledge Graph here
│ │ ├── bot # Entrypoint of the Bot API
│ │ ├── classifier # Symentic Parsing, Intent Matching, Slot Filling
│ │ └── test # Example Data Source as equivalent/mocked module
│ └── siwi_frontend # Browser End
│ ├── README.md
│ ├── package.json
│ └── src
│ ├── App.vue # Listening to user and pass Questions to Siwi-API
│ └── main.js
└── wsgi.py
تعتمد الواجهة الخلفية على Nebula Graph، وهي قاعدة بيانات للرسم البياني الموزع مفتوحة المصدر.
تثبيت Nebula Graph في الخط المباشر:
curl -fsSL nebula-up.siwei.io/install.sh | bash
قم بتحميل مجموعة بيانات لاعب كرة السلة.
~ /.nebula-up/console.sh
nebula-console -addr graphd -port 9669 -user root -p nebula -e " :play basketballplayer "
التثبيت والتشغيل.
# Install siwi backend
python3 -m build
# Configure Nebula Graph Endpoint
export NG_ENDPOINTS=127.0.0.1:9669
# Run Backend API server
gunicorn --bind :5000 wsgi --workers 1 --threads 1 --timeout 60
للوظيفة المفتوحة/KNative
docker build -t weygu/siwi-api .
docker run --rm --name siwi-api
--env=PORT=5000
--env=NG_ENDPOINTS=127.0.0.1:9669
--net=host
weygu/siwi-api
جربه واجهة برمجة تطبيقات الويب:
$ curl -s --header " Content-Type: application/json "
--request POST
--data ' {"question": "What is the relationship between Yao Ming and Lakers?"} '
http://192.168.8.128:5000/query | jq
{
" answer " : " There are at least 23 relations between Yao Ming and Lakers, one relation path is: Yao Ming follows Shaquille O'Neal serves Lakers. "
}
استدعاء بوت بايثون API:
from nebula3 . gclient . net import ConnectionPool
from nebula3 . Config import Config
# define a config
config = Config ()
config . max_connection_pool_size = 10
# init connection pool
connection_pool = ConnectionPool ()
# if the given servers are ok, return true, else return false
ok = connection_pool . init ([( '127.0.0.1' , 9669 )], config )
# import siwi bot
from siwi . bot import bot
# instantiate a bot
b = bot . SiwiBot ( connection_pool )
# make the question query
b . query ( "Which team had Jonathon Simmons served?" )
وبعدها يكون الرد هكذا:
In [ 4 ]: b . query (" Which team had Jonathon Simmons serv
...: ed ?")
[ DEBUG ] ServeAction intent : { 'entities' : { 'Jonathon Simmons' : 'player' }, 'intents' : ( 'serve' ,)}
[ DEBUG ] query for RelationshipAction :
USE basketballplayer ;
MATCH p = ( v ) - [ e : serve * 1 ] - > ( v1 ) WHERE id ( v ) == "player112"
RETURN p LIMIT 100 ;
[ 2021 - 07 - 02 02 : 59 : 36 , 392 ]: Get connection to ( '127.0.0.1' , 9669 )
Out [ 4 ]: 'Jonathon Simmons had served 3 teams. Spurs from 2015 to 2015; 76ers from 2019 to 2019; Magic from 2017 to 2017; '
في اشارة الى siwi_frontend
┌─────────────────────────────┐
│ kind: Ingress │ ┌───────────────────┐
│ path: / │ │ Pod │
│ -> siwi-frontend ────┼─────┤ siwi-frontend │
│ │ │ │
│ │ └───────────────────┘
│ │
│ path: /query │ ┌───────────────────────────────────┐
│ -> siwi-api ────┼─────┤ KNative Service │
│ KNative Serving │ │ serving-xxxx │
│ │ │ │
│ │ │ apiVersion: serving.knative.dev/v1│
│ │ │ kind: Service │
└─────────────────────────────┘ └─────────┬─────────────────────────┘
│
└────────────┐
│
┌───────────────────────────────────────────────────────┐ │
│apiVersion: core.openfunction.io/v1alpha1 │ │
│kind: Function │ │
│spec: │ │
│ version: "v1.0.0" │ │
│ image: "weygu/siwi-api:latest" │ │
│ imageCredentials: │ │
│ name: push-secret │ │
│ port: 8080 │ │
│ build: │ │
│ builder: openfunction/builder:v1 │ │
│ env: │ │
│ FUNC_NAME: "siwi_api" │ │
│ FUNC_TYPE: "http" │ │
│ FUNC_SRC: "main.py" │ │
│ srcRepo: │ │
│ url: "https://github.com/wey-gu/nebula-siwi.git" │ │
│ sourceSubPath: "src" │ │
│ serving: │ │
│ runtime: Knative ─────────────────────────────────┼──┘
│ params: │
│ NG_ENDPOINTS: "NEBULA_GRAPH_ENDPOINT" │
│ template: │ │
│ containers: │ │
│ - name: function │ │
│ imagePullPolicy: Always │ │
└───────────────────────────────────────┼───────────────┘
│
┌──────────┘
│
┌────────────────────────────┴───────────────────────────┐
│apiVersion:lapps.nebula-graph.io/v1alpha1 │
│kind: NebulaCluster │
│spec: │
│ graphd: │
│ config: │
│ system_memory_high_watermark_ratio: "1.0" │
│ image: vesoft/nebula-graphd │
│ replicas: 1 │
│... │
└────────────────────────────────────────────────────────┘
من المفترض أن لدينا k8s مع تثبيت OpenFunctions
قم بتثبيت Nebula Graph باستخدام مثبت السديم kubesphere-all-in-one
على KubeSphere:
curl -sL nebula-kind.siwei.io/install-ks-1.sh | bash
الحصول على NodePort لرسم السديم:
NEBULA_GRAPH_ENDPOINT= $( kubectl get svc nebula-graphd-svc-nodeport -o yaml -o jsonpath= ' {.spec.clusterIP}:{.spec.ports[0].port} ' )
echo $NEBULA_GRAPH_ENDPOINT
تحميل مجموعة البيانات في مجموعة السديم:
wget https://docs.nebula-graph.io/2.0/basketballplayer-2.X.ngql
~ /.nebula-kind/bin/console -u root -p password --address= < nebula-graphd-svc-nodeport > --port=32669 -f basketballplayer-2.X.ngql
قم بإنشاء siwi-api المدعوم من Openfunction:
cat siwi-api-function.yaml | sed " s/NEBULA_GRAPH_ENDPOINT/ $NEBULA_GRAPH_ENDPOINT /g " | kubectl apply -f -
احصل على الدالة nebula-siwi وKNative Service:
kubectl get functions nebula-siwi
FUNCTION= $( kubectl get functions nebula-siwi -o go-template= ' {{.status.serving.resourceRef}} ' )
kubectl get ksvc -l openfunction.io/serving= $FUNCTION
KSVC= $( kubectl get ksvc -l openfunction.io/serving= $FUNCTION -o=jsonpath= ' {.items[0].metadata.name} ' )
kubectl get revision -l serving.knative.dev/service= $KSVC
REVISION= $( kubectl get revision -l serving.knative.dev/service= $KSVC -o=jsonpath= ' {.items[0].metadata.name} ' )
echo $REVISION
التحقق من أن الوظيفة تعمل بشكل جيد:
curl -s --header " Content-Type: application/json "
--request POST
--data ' {"question": "What is the relationship between Yao Ming and Lakers ?"} '
$( kubectl get ksvc -l openfunction.io/serving= $FUNCTION -o=jsonpath= ' {.items[0].status.url} ' ) /query
قم بإنشاء موارد تطبيق siwi على K8s:
cat siwi-app.yaml | sed " s/REVISION/ $REVISION /g " | kubectl apply -f -
تحقق من أن الوظيفة تعمل بشكل جيد من خلال الإدخال:
هنا تم استخدام منفذ العقدة بمنفذ http 31059 كنقطة نهاية لوحدة التحكم في الدخول.
curl -s --header " Content-Type: application/json "
--request POST
--data ' {"question": "how does Tim Duncan and Lakers connected?"} '
demo-siwi.local:31059/query
التحقق من الواجهة الأمامية:
curl $( kubectl get svc -l app=siwi -o=jsonpath= ' {.items[0].spec.clusterIP} ' )
تحقق من الواجهة الأمامية خلف المدخل:
curl demo-siwi.local:31059
احصل على جميع الموارد في تطبيق siwi:
kubectl get service,pod,ingress,function -l app=siwi
وينبغي أن يكون شيء من هذا القبيل:
[root@wey nebula-siwi] # kubectl get service,pod,ingress,function -l app=siwi
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/siwi-frontend-file ClusterIP 10.233.60.81 < none > 80/TCP 64m
NAME READY STATUS RESTARTS AGE
pod/siwi-frontend-file 1/1 Running 0 64m
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/siwi-service < none > demo-siwi.local 80 59m
NAME BUILDSTATE SERVINGSTATE BUILDER SERVING AGE
function.core.openfunction.io/nebula-siwi Succeeded Running builder-sbfz6 serving-vvjvl 26h
[root@wey nebula-siwi] # kubectl get service,pod,ingress,function -l app=siwi
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/siwi-frontend-file ClusterIP 10.233.60.81 < none > 80/TCP 65m
NAME READY STATUS RESTARTS AGE
pod/siwi-frontend-file 1/1 Running 0 65m
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/siwi-service < none > demo-siwi.local 80 59m
NAME BUILDSTATE SERVINGSTATE BUILDER SERVING AGE
function.core.openfunction.io/nebula-siwi Succeeded Running builder-sbfz6 serving-vvjvl 26h
docker build -t weygu/siwi-frontend . -f Dockerfile.froentend
docker push weygu/siwi-frontend