Digital Twin Umfrage
Diese Anleitung fuehrt Sie durch die Durchfuehrung einer Zielgruppen-Umfrage mit Digital Twins -- von der Authentifizierung bis zur Interpretation von Gruppenmeinungen.
Digital Twins sind KI-Personas, die auf realen demografischen Daten basieren. Sie koennen ihnen einzeln oder als Gruppe Fragen stellen und erhalten Antworten, die ihr demografisches Profil, ihre Werte und Perspektiven widerspiegeln.
Was Sie erstellen werden
Am Ende dieser Anleitung werden Sie:
- Sich bei der neuroflash API authentifizieren
- Ihren Workspace abrufen
- Verfuegbare demografische Gruppen durchsuchen
- Twins in einer Gruppe auflisten
- Einem einzelnen Twin eine Frage stellen
- Gruppenmeinungen von mehreren Twins einholen
Voraussetzungen
- Ein neuroflash-Konto mit API-Zugang
- Ihre
client_idundclient_secret(siehe Authentifizierung)
Schritt 1: Authentifizieren
Rufen Sie zuerst ein Access Token ab:
- cURL
- Python
- Node.js
- Go
curl -X POST https://id.neuroflash.com/oauth/v2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=openid"
import requests
BASE_URL = "https://app.neuroflash.com/api"
# Authenticate
auth_response = requests.post(
"https://id.neuroflash.com/oauth/v2/token",
data={
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"scope": "openid",
},
)
token = auth_response.json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}
const BASE_URL = "https://app.neuroflash.com/api";
// Authenticate
const authResponse = await fetch("https://id.neuroflash.com/oauth/v2/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: "YOUR_CLIENT_ID",
client_secret: "YOUR_CLIENT_SECRET",
scope: "openid",
}),
});
const { access_token } = await authResponse.json();
const headers = { Authorization: `Bearer ${access_token}` };
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
)
const baseURL = "https://app.neuroflash.com/api"
func main() {
// Authenticate
data := url.Values{
"grant_type": {"client_credentials"},
"client_id": {"YOUR_CLIENT_ID"},
"client_secret": {"YOUR_CLIENT_SECRET"},
"scope": {"openid"},
}
resp, _ := http.Post(
"https://id.neuroflash.com/oauth/v2/token",
"application/x-www-form-urlencoded",
strings.NewReader(data.Encode()),
)
defer resp.Body.Close()
var authResult struct {
AccessToken string `json:"access_token"`
}
json.NewDecoder(resp.Body).Decode(&authResult)
token := authResult.AccessToken
}
Schritt 2: Workspace abrufen
Rufen Sie Ihre verfuegbaren Workspaces ab und waehlen Sie den ersten aus. Die Workspace-ID wird fuer die meisten API-Aufrufe benoetigt:
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/workspace-service/v1/workspaces" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
workspaces = requests.get(
f"{BASE_URL}/workspace-service/v1/workspaces",
headers=headers,
).json()
workspace_id = workspaces["_embedded"]["workspaces"][0]["id"]
print(f"Using workspace: {workspace_id}")
const workspaces = await fetch(
`${BASE_URL}/workspace-service/v1/workspaces`,
{ headers }
).then((r) => r.json());
const workspaceId = workspaces._embedded.workspaces[0].id;
console.log(`Using workspace: ${workspaceId}`);
req, _ := http.NewRequest("GET", baseURL+"/workspace-service/v1/workspaces", nil)
req.Header.Set("Authorization", "Bearer "+token)
wsResp, _ := http.DefaultClient.Do(req)
defer wsResp.Body.Close()
var wsResult struct {
Embedded struct {
Workspaces []struct {
ID string `json:"id"`
} `json:"workspaces"`
} `json:"_embedded"`
}
json.NewDecoder(wsResp.Body).Decode(&wsResult)
workspaceID := wsResult.Embedded.Workspaces[0].ID
fmt.Printf("Using workspace: %s\n", workspaceID)
Schritt 3: Statische Gruppen durchsuchen
neuroflash bietet vorgefertigte demografische Gruppen mit sofort einsatzbereiten Digital Twins. Listen Sie die verfuegbaren Gruppen auf:
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/digital-twin-service/v1/static-groups" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
groups = requests.get(
f"{BASE_URL}/digital-twin-service/v1/static-groups",
headers=headers,
).json()
for group in groups:
print(f"{group['key']}: {group['label']} — {group['description']}")
const groups = await fetch(
`${BASE_URL}/digital-twin-service/v1/static-groups`,
{ headers }
).then((r) => r.json());
groups.forEach((g) => console.log(`${g.key}: ${g.label} — ${g.description}`));
req, _ := http.NewRequest("GET", baseURL+"/digital-twin-service/v1/static-groups", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var groups []struct {
Key string `json:"key"`
Label string `json:"label"`
Description string `json:"description"`
}
json.NewDecoder(resp.Body).Decode(&groups)
for _, g := range groups {
fmt.Printf("%s: %s — %s\n", g.Key, g.Label, g.Description)
}
Antwort:
[
{
"key": "gen_z",
"label": "Gen Z",
"description": "Generation Z (born 1997-2012)"
},
{
"key": "millennials",
"label": "Millennials",
"description": "Millennials (born 1981-1996)"
},
{
"key": "gen_x",
"label": "Generation X",
"description": "Generation X (born 1965-1980)"
},
{
"key": "baby_boomers",
"label": "Baby Boomers",
"description": "Baby Boomers (born 1946-1964)"
},
{
"key": "gen_alpha",
"label": "Generation Alpha",
"description": "Generation Alpha (born 2010+)"
}
]
Schritt 4: Twins in einer Gruppe auflisten
Waehlen Sie die erste Gruppe aus und rufen Sie die einzelnen Digital Twins darin ab:
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/digital-twin-service/v1/workspaces/{workspace_id}/static-groups/gen_z/twins?page=1&size=5" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
group_key = groups[0]["key"]
twins = requests.get(
f"{BASE_URL}/digital-twin-service/v1/workspaces/{workspace_id}/static-groups/{group_key}/twins",
headers=headers,
params={"page": 1, "size": 5},
).json()
for twin in twins["data"]:
print(f"{twin['name']} — {twin['title']} (Age: {twin['age']}, {twin['location']})")
const groupKey = groups[0].key;
const twins = await fetch(
`${BASE_URL}/digital-twin-service/v1/workspaces/${workspaceId}/static-groups/${groupKey}/twins?page=1&size=5`,
{ headers }
).then((r) => r.json());
twins.data.forEach((t) =>
console.log(`${t.name} — ${t.title} (Age: ${t.age}, ${t.location})`)
);
groupKey := groups[0].Key
twinsURL := fmt.Sprintf("%s/digital-twin-service/v1/workspaces/%s/static-groups/%s/twins?page=1&size=5",
baseURL, workspaceID, groupKey)
req, _ := http.NewRequest("GET", twinsURL, nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var twinsResult struct {
Data []struct {
ID string `json:"id"`
Name string `json:"name"`
Title string `json:"title"`
Age int `json:"age"`
Location string `json:"location"`
} `json:"data"`
}
json.NewDecoder(resp.Body).Decode(&twinsResult)
for _, t := range twinsResult.Data {
fmt.Printf("%s — %s (Age: %d, %s)\n", t.Name, t.Title, t.Age, t.Location)
}
Antwort:
{
"data": [
{
"id": "a1b2c3d4-...",
"name": "Jens Bauer",
"title": "Tech-Savvy Millennial",
"age": 34,
"gender": "male",
"location": "Munich",
"jobTitle": "Software Engineer",
"staticGroupKey": "millennials",
"_links": {
"avatarUrl": "https://storage.googleapis.com/..."
}
}
],
"page": {
"size": 5,
"totalElements": 20,
"totalPages": 4,
"currentPage": 1
}
}
Schritt 5: Einem einzelnen Twin eine Frage stellen
Stellen Sie nun einem einzelnen Twin eine Frage. Der Twin antwortet charaktergetreu basierend auf seinem demografischen Profil:
- cURL
- Python
- Node.js
- Go
curl -X POST "https://app.neuroflash.com/api/digital-twin-service/v1/workspaces/{workspace_id}/twins/{twin_id}/chat-completions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "user",
"content": "What do you think about electric vehicles? Would you buy one?"
}
]
}'
twin_id = twins["data"][0]["id"]
response = requests.post(
f"{BASE_URL}/digital-twin-service/v1/workspaces/{workspace_id}/twins/{twin_id}/chat-completions",
headers=headers,
json={
"messages": [
{
"role": "user",
"content": "What do you think about electric vehicles? Would you buy one?",
}
]
},
).json()
print(f"Answer: {response['answer']}")
print(f"Reason: {response['reason']}")
const twinId = twins.data[0].id;
const response = await fetch(
`${BASE_URL}/digital-twin-service/v1/workspaces/${workspaceId}/twins/${twinId}/chat-completions`,
{
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({
messages: [
{
role: "user",
content:
"What do you think about electric vehicles? Would you buy one?",
},
],
}),
}
).then((r) => r.json());
console.log(`Answer: ${response.answer}`);
console.log(`Reason: ${response.reason}`);
twinID := twinsResult.Data[0].ID
chatURL := fmt.Sprintf("%s/digital-twin-service/v1/workspaces/%s/twins/%s/chat-completions",
baseURL, workspaceID, twinID)
body, _ := json.Marshal(map[string]any{
"messages": []map[string]string{
{"role": "user", "content": "What do you think about electric vehicles? Would you buy one?"},
},
})
req, _ := http.NewRequest("POST", chatURL, bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var chatResult struct {
Answer string `json:"answer"`
Reason string `json:"reason"`
}
json.NewDecoder(resp.Body).Decode(&chatResult)
fmt.Printf("Answer: %s\n", chatResult.Answer)
fmt.Printf("Reason: %s\n", chatResult.Reason)
Antwort:
{
"answer": "I'm definitely considering it for my next car. The tech has gotten really good, and with charging infrastructure improving in Munich, it makes sense both financially and environmentally.",
"reason": "As a tech-savvy millennial software engineer, Jens is drawn to innovative technology and is environmentally conscious. His urban Munich location provides good charging infrastructure, making EVs practical."
}
Standardmaessig ist useVerbalizedSampling auf true gesetzt. Das bedeutet, dass der Twin 5 wahrscheinlichkeitsgewichtete Antwort-Kandidaten generiert und den repraesentativsten auswaehlt, was zu konsistenteren und zuverlaessigeren Antworten fuehrt.
Schritt 6: Gruppenmeinungen einholen
Die leistungsstaerkste Funktion -- stellen Sie mehreren Twins dieselbe Frage und erhalten Sie eine Zusammenfassung mit Einzelantworten:
- cURL
- Python
- Node.js
- Go
curl -X POST "https://app.neuroflash.com/api/digital-twin-service/v1/workspaces/{workspace_id}/twin-group-chat-opinions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"twinIds": ["twin-id-1", "twin-id-2", "twin-id-3", "twin-id-4", "twin-id-5"],
"question": "Would you switch to a plant-based diet if it were more affordable?"
}'
twin_ids = [t["id"] for t in twins["data"][:5]]
opinions = requests.post(
f"{BASE_URL}/digital-twin-service/v1/workspaces/{workspace_id}/twin-group-chat-opinions",
headers=headers,
json={
"twinIds": twin_ids,
"question": "Would you switch to a plant-based diet if it were more affordable?",
},
).json()
print(f"Summary: {opinions['summary']}\n")
for twin_id, response in opinions["twinResponses"].items():
print(f"Twin {twin_id}:")
print(f" Answer: {response['answer']}")
print(f" Reason: {response['reason']}\n")
const twinIds = twins.data.slice(0, 5).map((t) => t.id);
const opinions = await fetch(
`${BASE_URL}/digital-twin-service/v1/workspaces/${workspaceId}/twin-group-chat-opinions`,
{
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({
twinIds,
question:
"Would you switch to a plant-based diet if it were more affordable?",
}),
}
).then((r) => r.json());
console.log(`Summary: ${opinions.summary}\n`);
for (const [twinId, response] of Object.entries(opinions.twinResponses)) {
console.log(`Twin ${twinId}:`);
console.log(` Answer: ${response.answer}`);
console.log(` Reason: ${response.reason}\n`);
}
twinIDs := make([]string, 0, 5)
for _, t := range twinsResult.Data[:5] {
twinIDs = append(twinIDs, t.ID)
}
opinionsURL := fmt.Sprintf("%s/digital-twin-service/v1/workspaces/%s/twin-group-chat-opinions",
baseURL, workspaceID)
body, _ := json.Marshal(map[string]any{
"twinIds": twinIDs,
"question": "Would you switch to a plant-based diet if it were more affordable?",
})
req, _ := http.NewRequest("POST", opinionsURL, bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var opinions struct {
Summary string `json:"summary"`
TwinResponses map[string]struct {
Answer string `json:"answer"`
Reason string `json:"reason"`
} `json:"twinResponses"`
}
json.NewDecoder(resp.Body).Decode(&opinions)
fmt.Printf("Summary: %s\n\n", opinions.Summary)
for id, r := range opinions.TwinResponses {
fmt.Printf("Twin %s:\n Answer: %s\n Reason: %s\n\n", id, r.Answer, r.Reason)
}
Antwort:
{
"summary": "The group shows mixed sentiment toward plant-based diets. Younger, urban twins are more open to the switch, citing environmental concerns and health benefits. Those in suburban or rural settings express more hesitation, preferring gradual changes. Price is a key factor for all — 4 out of 5 said affordability would significantly increase their willingness.",
"twinResponses": {
"twin-id-1": {
"answer": "Yes, I'd try it. I already eat less meat than my parents did.",
"reason": "As a health-conscious urban millennial, Jens is open to dietary changes..."
},
"twin-id-2": {
"answer": "I'd consider reducing meat, but going fully plant-based is a big step.",
"reason": "..."
}
}
}
Naechste Schritte
- Erfahren Sie mehr ueber Gruppen-Chat-Konversationen fuer Diskussionen mit mehreren Teilnehmern
- Entdecken Sie die Digital Twins API-Referenz fuer alle Endpoints
- Siehe Audiences, um benutzerdefinierte Zielgruppen zu erstellen