మీరు గోవా పర్యటనను ప్లాన్ చేయాలనుకుంటున్నారు. మీ వద్ద ఐదు రోజులు, 25,000 రూపాయల బడ్జెట్ మరియు బీచ్లు మరియు సీఫుడ్ పట్ల స్పష్టమైన ఆసక్తి ఉన్నాయి. సాధారణంగా, దీని అర్థం పది బ్రౌజర్ ట్యాబ్లను తెరవడం, పాతబడిన ఫారమ్ పోస్ట్లను చదవడం మరియు మాన్యువల్గా ఒక ఇటినెరరీని (itinerary) తయారు చేయడం. దానికి బదులుగా, ఒకే ఒక POST రిక్వెస్ట్ పంపి, భోజన సూచనలు, కార్యకలాపాల జాబితా మరియు ఖచ్చితమైన బడ్జెట్ విభజనతో కూడిన స్ట్రక్చర్డ్ డే-బై-డే ప్లాన్ను తిరిగి పొందవచ్చని ఊహించుకోండి. ఈ ప్రాజెక్ట్ అదే అందిస్తుంది.
మేము Spring Boot మరియు Azure OpenAI ఉపయోగించి ఒక REST APIని నిర్మిస్తాము. ఈ API గమ్యస్థానం, బడ్జెట్, కాలపరిమితి మరియు ఆసక్తులను స్వీకరిస్తుంది. ఇది క్లీన్ JSONని తిరిగి ఇస్తుంది, దీనిని ఫ్రంటెండ్ లేదా మొబైల్ యాప్ వెంటనే రెండర్ చేయగలదు. ఇక్కడ స్క్రాపింగ్ లేదు, హార్డ్కోడెడ్ ఇటినెరరీలు లేవు. కేవలం ట్రావెల్ ప్లానర్గా పనిచేయమని ప్రాంప్ట్ చేయబడిన ఒక AI మోడల్ మాత్రమే ఉంటుంది.
API ఏమి తిరిగి ఇస్తుంది
రెస్పాన్స్ అనేది మీరు regex ద్వారా విడదీయాల్సిన మార్క్డౌన్ టెక్స్ట్ బ్లాక్ కాదు. ఇది రోజువారీ కార్యకలాపాలు, భోజన సూచనలు మరియు బడ్జెట్ వివరాలను కలిగి ఉన్న ఒక స్ట్రక్చర్డ్ JSON ఆబ్జెక్ట్. గోవా పర్యటన కోసం, మీరు మొదటి రోజు విభాగంలో బీచ్ షాక్లో బ్రేక్ఫాస్ట్ కోసం 500 రూపాయలు, ఉదయం పాలోలెమ్ (Palolem) లో గడపడం మరియు సాయంత్రం ఒక నిర్దిష్ట ప్రాంతంలో సీఫుడ్ డిన్నర్ వంటి వివరాలను పొందవచ్చు. ప్రతి రోజుకు టైమ్ స్లాట్లు, అంచనా వేసిన ఖర్చులు మరియు "beach" లేదా "food" వంటి ట్యాగ్లు ఉంటాయి. ఆధునిక ట్రావెల్ యాప్లు పేరాగ్రాఫ్లను పార్స్ (parse) చేయాలని కోరుకోవు, కాబట్టి ఈ స్ట్రక్చర్ చాలా ముఖ్యం. అవి RecyclerViews లేదా React కాంపోనెంట్లకు మ్యాప్ చేయగల ఆబ్జెక్ట్లను కోరుకుంటాయి.
స్టాక్ మరియు అది ఎందుకు సరిపోతుంది
ఈ ప్రాజెక్ట్ Spring Boot 3.5 మరియు Spring AIని ఉపయోగిస్తుంది. Spring AI ఇందులో కీలకమైన భాగం. ఇది ఒక యూనిఫైడ్ ChatModel అబ్స్ట్రాక్షన్ను అందిస్తుంది, తద్వారా మీరు Azure OpenAI కోసం నేరుగా HTTP క్లయింట్లను రాయాల్సిన అవసరం లేదు. మీరు సర్వీస్ కోడ్ను కాకుండా, కేవలం డిపెండెన్సీలు మరియు ప్రాపర్టీలను మాత్రమే మారుస్తారు.
మీ బిల్డ్ ఫైల్లో నాలుగు డిపెండెన్సీలు అవసరం:
- REST లేయర్ కోసం
spring-boot-starter-web. - Spring AI ఇంటర్ఫేస్ ద్వారా LLMకి కనెక్ట్ కావడానికి
spring-ai-starter-model-azure-openai. - ఆటోమేటిక్ Swagger డాక్యుమెంటేషన్ కోసం
springdoc-openapi. - మీ రిక్వెస్ట్ మరియు రెస్పాన్స్ POJOలలోని బోయిలర్ప్లేట్ (boilerplate) కోడ్ను తగ్గించడానికి
Lombok.
Spring AI మీ బిజినెస్ లాజిక్ మరియు LLM ప్రొవైడర్ మధ్య ఉంటుంది. ఆ పొజిషనింగ్ ఉద్దేశపూర్వకమైనది. ఇది మీ @Service క్లాస్లను క్లీన్గా మరియు ప్రొవైడర్-అజ్ఞాతంగా (provider-agnostic) ఉంచుతుంది.
PromptTemplatesతో ప్రాంప్ట్ ఇంజనీరింగ్
Java స్ట్రింగ్స్లో ప్రాంప్ట్లను హార్డ్కోడ్ చేయడం వల్ల మెయింటైన్ చేయడం కష్టమైన సాఫ్ట్వేర్ తయారవుతుంది. ఒకవేళ ప్రొడక్ట్ టీమ్ AI మరింత క్యాజువల్గా మాట్లాడాలని లేదా ఒక నిర్దిష్ట పరిమితి కంటే ఎక్కువ బడ్జెట్ అంచనాలను తిరస్కరించాలని నిర్ణయించుకుంటే, మీరు మీ సర్వీస్ను మళ్ళీ రీకంపైల్ (recompile) చేయాల్సిన అవసరం ఉండకూడదు.
Spring AI PromptTemplateని అందిస్తుంది. మీరు ప్రాంప్ట్ స్కెలిటన్ను ఒక రిసోర్స్ ఫైల్లో లేదా ప్రత్యేకమైన టెంప్లేట్ స్ట్రింగ్లో నిల్వ చేస్తారు, మరియు {destination}, {budget}, {days}, మరియు {interests} వంటి వేరియబుల్స్ కోసం ప్లేస్హోల్డర్లను ఉంచుతారు. రన్టైమ్లో, సర్వీస్ ఒక Prompt ఆబ్జెక్ట్ను సృష్టించి, యూజర్ విలువలను ఇంజెక్ట్ చేస్తుంది.
సిస్టమ్ మెసేజ్లను యూజర్ మెసేజ్ల నుండి వేరు చేయండి. పర్సోనాను (persona) నిర్వచించడానికి సిస్టమ్ మెసేజ్ని ఉపయోగించండి. ఉదాహరణకు, మోడల్కు అది భారతీయ గమ్యస్థానాలలో నైపుణ్యం కలిగిన, బడ్జెట్ పట్ల జాగ్రత్తగా ఉండే మరియు మార్క్డౌన్ ఫెన్సెస్ (markdown fences) లేకుండా కేవలం JSON మాత్రమే తిరిగి ఇవ్వాలని ఖచ్చితంగా ఉండే ఒక ట్రావెల్ ప్లానర్ అని మీరు చెబుతారు. నిర్దిష్ట పర్యటన వివరాలను పంపడానికి యూజర్ మెసేజ్ని ఉపయోగించండి. API కాంట్రాక్ట్ను మార్చకుండా పర్సోనాస్ను A/B టెస్ట్ చేయాలనుకున్నప్పుడు ఈ విభజన సహాయపడుతుంది.
సర్వీస్ లేయర్: Azure OpenAIతో మాట్లాడటం
@Service క్లాస్కు ఒకే ఒక పని ఉంటుంది. అది ప్రాంప్ట్ను నిర్మిస్తుంది, మోడల్ను పిలుస్తుంది, రెస్పాన్స్ను క్లీన్ చేస్తుంది మరియు ఫలితాన్ని పార్స్ చేస్తుంది.
Spring AI యొక్క ChatClient లేదా ChatModelని ఇంజెక్ట్ చేయండి. వచ్చే రిక్వెస్ట్ విలువలతో PromptTemplateని రెండర్ చేసి, ఆపై చాట్ మెథడ్ను కాల్ చేయండి. రెస్పాన్స్ ఒక String రూపంలో వస్తుంది. ఇక్కడే చాలా ట్యుటోరియల్స్ ఆగిపోతాయి మరియు అసలైన ప్రొడక్షన్ కోడ్ మొదలవుతుంది.
LLMలు కొన్నిసార్లు మర్యాదపూర్వకమైన పీఠికలను (preambles) జోడిస్తాయి. మీకు "Here is your itinerary" అని మొదలై, ఆపై ట్రిపుల్ బ్యాక్టిక్స్లో (triple backticks) ఉన్న JSON వచ్చే రెస్పాన్స్ రావచ్చు. మీరు దానిని నేరుగా Jacksonతో డీసీరియలైజ్ (deserialize) చేయడానికి ప్రయత్నిస్తే, మీ యాప్ క్రాష్ అవుతుంది. రా (raw) స్ట్రింగ్ను స్కాన్ చేసి, మొదటి ఓపెనింగ్ బ్రేస్ మరియు చివరి క్లోజింగ్ బ్రేస్ను కనుగొని, కేవలం JSON పేలోడ్ను మాత్రమే సంగ్రహించే ఒక చిన్న హెల్పర్ మెథడ్ను జోడించండి. ఆపై సంగ్రహించిన బ్లాక్ను వాలిడేట్ చేయండి. ఆబ్జెక్ట్ను కంట్రోలర్కు తిరిగి పంపే ముందు, అవసరమైన ఫీల్డ్లు ఉన్నాయో లేదో మరియు సంఖ్యాపరమైన విలువలు (numeric values) సరిగ్గా ఉన్నాయో లేదో తనిఖీ చేయండి.
ఈ డిఫెన్సివ్ పార్సింగ్ (defensive parsing) అనేది ఐచ్ఛికం కాదు. ఇది ఒక డెమోకు మరియు నమ్మదగిన APIకి మధ్య ఉన్న సరిహద్దు.
పరిణతి చెందిన వ్యవస్థలాగా ఎర్రర్లను హ్యాండిల్ చేయడం
ఎక్స్టర్నల్ APIలు విఫలమవుతాయి. Azure OpenAI రేట్ లిమిట్ ఎర్రర్లు, అథెంటికేషన్ ఫెయిల్యూర్లు లేదా తాత్కాలిక 500 ఎర్రర్లను తిరిగి ఇవ్వవచ్చు. వీటిని స్టాక్ ట్రేస్లుగా (stack traces) యూజర్కు చూపించినట్లయితే, మీరు మీ విశ్వసనీయతను కోల్పోతారు.
ఎక్సెప్షన్లను (exceptions) గ్లోబల్గా ఇంటర్సెప్ట్ చేయడానికి @RestControllerAdviceని ఉపయోగించండి. Spring AI ఎక్సెప్షన్లు, HttpClientErrorException, మరియు జనరిక్ RuntimeExceptionలను స్థిరమైన ఎర్రర్ రెస్పాన్స్లకు మ్యాప్ చేయండి. స్పష్టమైన సందేశం, రేట్ లిమిట్స్ కోసం 429 వంటి HTTP స్టేటస్ మరియు క్లయింట్ మళ్ళీ ప్రయత్నించడానికి లేదా సమస్యను లాగ్ చేయడానికి తగిన వివరాలతో కూడిన JSON బాడీని రిటర్న్ చేయండి. యూజర్కు జావా క్లాస్ పేర్లతో నిండిన స్క్రీన్ కాకుండా, "Service temporarily busy. Please retry in 30 seconds" వంటి సందేశం కనిపించాలి.
ఎప్పుడూ సీక్రెట్స్ను హార్డ్కోడ్ చేయకండి
మీ Azure OpenAI API కీని Gitలో సేవ్ చేసే application.propertiesలో ఉంచకండి. దానిని ఎక్స్టర్నలైజ్ చేయండి. మీ Spring కాన్ఫిగరేషన్లో ${AZURE_OPENAI_KEY} మరియు ${AZURE_OPENAI_ENDPOINT} వంటి ఎన్విరాన్మెంట్ వేరియబుల్స్ను ఉపయోగించండి. డెవలప్మెంట్ కోసం లోకల్ .env ఫైల్ను ఉంచుకోండి, దానిని .gitignoreలో చేర్చండి మరియు Spring Boot యొక్క relaxed binding ద్వారా లోడ్ చేయండి. ఒకవేళ కీ లీక్ అయితే, మీరు మీ ఆర్టిఫ్యాక్ట్ను మళ్ళీ బిల్డ్ చేయాల్సిన అవసరం లేకుండా, ఒకే చోట దానిని మార్చుకోవచ్చు (rotate).
Swagger ద్వారా టెస్టింగ్
springdoc-openapi డిపెండెన్సీ రన్టైమ్లో Swagger UI ఎండ్పాయింట్ను ఎక్స్పోజ్ చేస్తుంది. మీ అప్లికేషన్ స్టార్ట్ అయిన తర్వాత, బ్రౌజర్లో /swagger-ui.htmlని ఓపెన్ చేయండి. మీరు Goa ఉదాహరణను నేరుగా నింపవచ్చు: destination "Goa," budget 25000, days 5, interests "beaches, food." 'execute' బటన్ నొక్కితే JSON ఇటినెరరీ (itinerary) కనిపించడం మీరు చూడవచ్చు. ఇది ప్రాంప్ట్ మార్పులను వాలిడేట్ చేయడానికి, సీరియలైజేషన్ను ధృవీకరించడానికి మరియు యూనిట్ టెస్ట్ రాసే ముందు ఫ్రంటెండ్ డెవలపర్లతో లైవ్ ప్లేగ్రౌండ్ను పంచుకోవడానికి మీకు సహాయపడుతుంది.
కోడ్ను మళ్ళీ రాయకుండా ప్రొవైడర్లను మార్చడం
స్టార్టప్లు ప్రొవైడర్లను మారుస్తుంటాయి. బహుశా Azure క్రెడిట్లు ముగిసిపోవచ్చు, లేదా ఖర్చు తగ్గించడానికి మీరు లోకల్ Ollama ఇన్స్టన్స్పై ఇన్ఫరెన్స్ (inference) రన్ చేయాలనుకోవచ్చు. Spring AI, ChatModel ఇంటర్ఫేస్ను అబ్స్ట్రాక్ట్ చేస్తుంది కాబట్టి, ఈ మార్పు చాలా సులభం. Maven డిపెండెన్సీని spring-ai-starter-model-azure-openai నుండి మరొక స్టార్టర్కు మార్చండి, కొత్త ఎండ్పాయింట్ మరియు కీతో మీ ప్రాపర్టీస్ ఫైల్ను అప్డేట్ చేయండి, మీ సర్వీస్ క్లాస్ను అలాగే ఉంచండి. మీ మొబైల్ యాప్కు కనిపించే API కాంట్రాక్ట్ మారదు.
ఆ పోర్టబిలిటీ (portability) ఈ ఆర్కిటెక్చర్ను నిజమైన ఉత్పత్తులకు (real products) చాలా ఉపయోగకరంగా చేస్తుంది. మీరు Azureతో ముడిపడిపోవడం లేదు. మీరు దానిని ఒక క్లీన్ Spring పైప్లైన్కు అనుసంధానించబడిన ఒక ఇంజిన్లా ఉపయోగిస్తున్నారు.
అసలైన సారాంశం
ఒక AI మోడల్ మీ అప్లికేషన్ కాదు. అది అంచనా వేయలేని టెక్స్ట్ను రిటర్న్ చేసే ఒక ఎక్స్టర్నల్ సర్వీస్. మీరు ఒక పేమెంట్ గేట్వే లేదా థర్డ్-పార్టీ వెదర్ APIని ఎంత జాగ్రత్తగా చూసుకుంటారో, దానిని కూడా అంతే కఠినంగా చూడండి. మీ క్రెడెన్షియల్స్ను ఎక్స్టర్నలైజ్ చేయండి. ప్రతి రెస్పాన్స్ను వాలిడేట్ చేయండి. పార్సింగ్ చేసే ముందు పేలోడ్ను క్లీన్ చేయండి. ఎర్రర్లను గ్లోబల్గా హ్యాండిల్ చేయండి, తద్వారా మీ యూజర్లు ఎప్పుడూ స్టాక్ ట్రేస్ను (stack trace) చూడరు.
25,000 రూపాయల బడ్జెట్లో Goa ఇటినెరరీని రూపొందించే సృజనాత్మక పనిని AIకి వదిలేయండి. మీరు ప్లంబింగ్ (plumbing) పనులను చూసుకోండి. ఈ రెండూ విడివిడిగా ఉన్నప్పుడు, మీరు నిజంగా పని చేసే (ships) సిస్టమ్ను రూపొందించగలరు.
ఈ ఆర్టికల్కు ప్రేరణనిచ్చిన అసలు వాక్త్రూని ఇక్కడ చూడవచ్చు.
Spring AI మరియు ఇటువంటి ప్రాజెక్ట్ల గురించి చర్చించడంలో ఆసక్తి ఉందా? GyaanSetu learning communityలో చేరండి.
