[{"data":1,"prerenderedAt":3482},["ShallowReactive",2],{"navigation_docs":3,"-engineering-contributing-back-end-llm-prompts":369,"-engineering-contributing-back-end-llm-prompts-surround":3478},[4,8,72,102,220,266,280,301,365],{"title":5,"path":6,"stem":7},"Introduction","\u002Fintroduction","0.introduction",{"title":9,"icon":10,"path":11,"stem":12,"children":13,"page":67},"Company","i-lucide-building-2","\u002Fcompany","1.company",[14,18,22,26,30,34,38,42,46,50,54,68],{"title":15,"path":16,"stem":17},"About","\u002Fcompany\u002Fabout","1.company\u002F0.about",{"title":19,"path":20,"stem":21},"Values","\u002Fcompany\u002Fvalues","1.company\u002F1.values",{"title":23,"path":24,"stem":25},"Communication","\u002Fcompany\u002Fcommunication","1.company\u002Fcommunication",{"title":27,"path":28,"stem":29},"Competition","\u002Fcompany\u002Fcompetition","1.company\u002Fcompetition",{"title":31,"path":32,"stem":33},"Hybrid Working","\u002Fcompany\u002Fhybrid-working","1.company\u002Fhybrid-working",{"title":35,"path":36,"stem":37},"Manchester Office","\u002Fcompany\u002Foffice","1.company\u002Foffice",{"title":39,"path":40,"stem":41},"Operations","\u002Fcompany\u002Foperations","1.company\u002Foperations",{"title":43,"path":44,"stem":45},"Policies","\u002Fcompany\u002Fpolicies","1.company\u002Fpolicies",{"title":47,"path":48,"stem":49},"Problem Statement","\u002Fcompany\u002Fproblem-statement","1.company\u002Fproblem-statement",{"title":51,"path":52,"stem":53},"Product Strategy","\u002Fcompany\u002Fproduct-strategy","1.company\u002Fproduct-strategy",{"title":55,"path":56,"stem":57,"children":58,"page":67},"Products","\u002Fcompany\u002Fproducts","1.company\u002Fproducts",[59,63],{"title":60,"path":61,"stem":62},"Capability Exchange","\u002Fcompany\u002Fproducts\u002Fcapability-exchange","1.company\u002Fproducts\u002Fcapability-exchange",{"title":64,"path":65,"stem":66},"ESProfiler Platform","\u002Fcompany\u002Fproducts\u002Fesprofiler","1.company\u002Fproducts\u002Fesprofiler",false,{"title":69,"path":70,"stem":71},"Security","\u002Fcompany\u002Fsecurity","1.company\u002Fsecurity",{"title":73,"icon":74,"path":75,"stem":76,"children":77,"page":67},"People Ops","i-lucide-users","\u002Fpeople-ops","2.people-ops",[78,82,86,90,94,98],{"title":79,"path":80,"stem":81},"Compensation","\u002Fpeople-ops\u002Fcompensation","2.people-ops\u002Fcompensation",{"title":83,"path":84,"stem":85},"Education","\u002Fpeople-ops\u002Feducation","2.people-ops\u002Feducation",{"title":87,"path":88,"stem":89},"Expenses","\u002Fpeople-ops\u002Fexpenses","2.people-ops\u002Fexpenses",{"title":91,"path":92,"stem":93},"Holiday & Leave","\u002Fpeople-ops\u002Fleave","2.people-ops\u002Fleave",{"title":95,"path":96,"stem":97},"Onboarding","\u002Fpeople-ops\u002Fonboarding","2.people-ops\u002Fonboarding",{"title":99,"path":100,"stem":101},"Recruitment","\u002Fpeople-ops\u002Frecruitment","2.people-ops\u002Frecruitment",{"title":103,"icon":104,"path":105,"stem":106,"children":107,"page":67},"Engineering","i-lucide-rocket","\u002Fengineering","3.engineering",[108,151,155,175,196,200,208,212,216],{"title":109,"path":110,"stem":111,"children":112,"page":67},"Contributing","\u002Fengineering\u002Fcontributing","3.engineering\u002Fcontributing",[113,117,121,125,129,142],{"title":114,"path":115,"stem":116},"Development Setup","\u002Fengineering\u002Fcontributing\u002Fdevelopment-setup","3.engineering\u002Fcontributing\u002F1.development-setup",{"title":118,"path":119,"stem":120},"Engineering Operations","\u002Fengineering\u002Fcontributing\u002Fengineering-operations","3.engineering\u002Fcontributing\u002F2.engineering-operations",{"title":122,"path":123,"stem":124},"Documentation","\u002Fengineering\u002Fcontributing\u002Fdocumentation","3.engineering\u002Fcontributing\u002F3.documentation",{"title":126,"path":127,"stem":128},"Agentic Coding","\u002Fengineering\u002Fcontributing\u002Fagentic-coding","3.engineering\u002Fcontributing\u002Fagentic-coding",{"title":130,"path":131,"stem":132,"children":133,"page":67},"Back End","\u002Fengineering\u002Fcontributing\u002Fback-end","3.engineering\u002Fcontributing\u002Fback-end",[134,138],{"title":135,"path":136,"stem":137},"API Guidelines","\u002Fengineering\u002Fcontributing\u002Fback-end\u002Fapi-guidelines","3.engineering\u002Fcontributing\u002Fback-end\u002Fapi-guidelines",{"title":139,"path":140,"stem":141},"LLM Prompts & Langfuse Integration","\u002Fengineering\u002Fcontributing\u002Fback-end\u002Fllm-prompts","3.engineering\u002Fcontributing\u002Fback-end\u002Fllm-prompts",{"title":143,"path":144,"stem":145,"children":146,"page":67},"Front End","\u002Fengineering\u002Fcontributing\u002Ffront-end","3.engineering\u002Fcontributing\u002Ffront-end",[147],{"title":148,"path":149,"stem":150},"Testing","\u002Fengineering\u002Fcontributing\u002Ffront-end\u002Ftesting","3.engineering\u002Fcontributing\u002Ffront-end\u002Ftesting",{"title":152,"path":153,"stem":154},"Production Database","\u002Fengineering\u002Fdatabase-connection","3.engineering\u002Fdatabase-connection",{"title":156,"path":157,"stem":158,"children":159},"Deployment","\u002Fengineering\u002Fdeployment","3.engineering\u002Fdeployment",[160,163,167,171],{"title":60,"path":161,"stem":162},"\u002Fengineering\u002Fdeployment\u002Fcapability-exchange","3.engineering\u002Fdeployment\u002Fcapability-exchange",{"title":164,"path":165,"stem":166},"Langfuse Deployment","\u002Fengineering\u002Fdeployment\u002Fecs-langfuse-deployment","3.engineering\u002Fdeployment\u002Fecs-langfuse-deployment",{"title":168,"path":169,"stem":170},"ESP Platform Configuration","\u002Fengineering\u002Fdeployment\u002Fesp-platform-configuration","3.engineering\u002Fdeployment\u002Fesp-platform-configuration",{"title":172,"path":173,"stem":174},"Platform","\u002Fengineering\u002Fdeployment\u002Fplatform","3.engineering\u002Fdeployment\u002Fplatform",{"title":176,"path":177,"stem":178,"children":179,"page":67},"Github","\u002Fengineering\u002Fgithub","3.engineering\u002Fgithub",[180,184,188,192],{"title":181,"path":182,"stem":183},"Packages","\u002Fengineering\u002Fgithub\u002Fpackages","3.engineering\u002Fgithub\u002Fpackages",{"title":185,"path":186,"stem":187},"Personal Access Token","\u002Fengineering\u002Fgithub\u002Fpersonal-access-token","3.engineering\u002Fgithub\u002Fpersonal-access-token",{"title":189,"path":190,"stem":191},"Troubleshooting","\u002Fengineering\u002Fgithub\u002Ftroubleshooting","3.engineering\u002Fgithub\u002Ftroubleshooting",{"title":193,"path":194,"stem":195},"Workflows","\u002Fengineering\u002Fgithub\u002Fworkflows","3.engineering\u002Fgithub\u002Fworkflows",{"title":197,"path":198,"stem":199},"Platform Ops","\u002Fengineering\u002Fplatform-ops","3.engineering\u002Fplatform-ops",{"title":172,"path":201,"stem":202,"children":203,"page":67},"\u002Fengineering\u002Fplatform","3.engineering\u002Fplatform",[204],{"title":205,"path":206,"stem":207},"useAPI","\u002Fengineering\u002Fplatform\u002Fuse-api","3.engineering\u002Fplatform\u002Fuse-api",{"title":209,"path":210,"stem":211},"Project Management","\u002Fengineering\u002Fproject-management","3.engineering\u002Fproject-management",{"title":213,"path":214,"stem":215},"Releases","\u002Fengineering\u002Frelease","3.engineering\u002Frelease",{"title":217,"path":218,"stem":219},"Tools","\u002Fengineering\u002Ftools","3.engineering\u002Ftools",{"title":221,"icon":222,"path":223,"stem":224,"children":225,"page":67},"Design","i-lucide-palette","\u002Fdesign","4.design",[226,247,251,255,259,262],{"title":227,"path":228,"stem":229,"children":230,"page":67},"Personas","\u002Fdesign\u002Fpersonas","4.design\u002F0.personas",[231,235,239,243],{"title":232,"path":233,"stem":234},"CISO - Simon","\u002Fdesign\u002Fpersonas\u002F01-ciso-simon","4.design\u002F0.personas\u002F01-ciso-simon",{"title":236,"path":237,"stem":238},"Head of Cyber - Harry","\u002Fdesign\u002Fpersonas\u002F02-head-of-cyber-harry","4.design\u002F0.personas\u002F02-head-of-cyber-harry",{"title":240,"path":241,"stem":242},"Security Architect - Sasha","\u002Fdesign\u002Fpersonas\u002F03-security-architect-sasha","4.design\u002F0.personas\u002F03-security-architect-sasha",{"title":244,"path":245,"stem":246},"Procurement Officer - Paige","\u002Fdesign\u002Fpersonas\u002F04-procurement-officer-paige","4.design\u002F0.personas\u002F04-procurement-officer-paige",{"title":248,"path":249,"stem":250},"Design Thinking","\u002Fdesign\u002Fdesign-thinking","4.design\u002F1.design-thinking",{"title":252,"path":253,"stem":254},"Design & Development","\u002Fdesign\u002Fdesign-and-development","4.design\u002F3.design-and-development",{"title":256,"path":257,"stem":258},"Branding","\u002Fdesign\u002Fbranding","4.design\u002F4.branding",{"title":217,"path":260,"stem":261},"\u002Fdesign\u002Ftools","4.design\u002F5.tools",{"title":263,"path":264,"stem":265},"Customer Success","\u002Fdesign\u002Fworking-with-customers","4.design\u002F6.working-with-customers",{"title":267,"icon":268,"path":269,"stem":270,"children":271,"page":67},"Sales","i-lucide-dollar-sign","\u002Fsales","4.sales",[272,276],{"title":273,"path":274,"stem":275},"Customer Onboarding","\u002Fsales\u002Fonboarding","4.sales\u002Fonboarding",{"title":277,"path":278,"stem":279},"Sales Tools","\u002Fsales\u002Ftools","4.sales\u002Ftools",{"title":281,"icon":282,"path":283,"stem":284,"children":285,"page":67},"Marketing","i-lucide-book-image","\u002Fmarketing","5.marketing",[286,290,294,297],{"title":287,"path":288,"stem":289},"Content","\u002Fmarketing\u002Fcontent","5.marketing\u002Fcontent",{"title":291,"path":292,"stem":293},"Messaging","\u002Fmarketing\u002Fmessaging","5.marketing\u002Fmessaging",{"title":217,"path":295,"stem":296},"\u002Fmarketing\u002Ftools","5.marketing\u002Ftools",{"title":298,"path":299,"stem":300},"Website","\u002Fmarketing\u002Fwebsite","5.marketing\u002Fwebsite",{"title":302,"icon":303,"path":304,"stem":305,"children":306,"page":67},"AI & Data Ops","i-lucide-database","\u002Fdata-ops","6.data-ops",[307,315,319,344,361],{"title":60,"path":308,"stem":309,"children":310,"page":67},"\u002Fdata-ops\u002Fcapability-exchange","6.data-ops\u002FCapability Exchange",[311],{"title":312,"path":313,"stem":314},"Leaderboard Calculation","\u002Fdata-ops\u002Fcapability-exchange\u002Fleaderboard-calculation","6.data-ops\u002FCapability Exchange\u002Fleaderboard-calculation",{"title":316,"path":317,"stem":318},"Account Portal (CAS)","\u002Fdata-ops\u002Faccount-portal","6.data-ops\u002Faccount-portal",{"title":320,"path":321,"stem":322,"children":323,"page":67},"Data Management","\u002Fdata-ops\u002Fdata-management","6.data-ops\u002Fdata-management",[324,328,332,336,340],{"title":325,"path":326,"stem":327},"Adding Products","\u002Fdata-ops\u002Fdata-management\u002Fadding-products","6.data-ops\u002Fdata-management\u002Fadding-products",{"title":329,"path":330,"stem":331},"Adding Vendors","\u002Fdata-ops\u002Fdata-management\u002Fadding-vendors","6.data-ops\u002Fdata-management\u002Fadding-vendors",{"title":333,"path":334,"stem":335},"Framework Mapping","\u002Fdata-ops\u002Fdata-management\u002Fframework-mapping","6.data-ops\u002Fdata-management\u002Fframework-mapping",{"title":337,"path":338,"stem":339},"Refreshing Vendors","\u002Fdata-ops\u002Fdata-management\u002Frefreshing-vendors","6.data-ops\u002Fdata-management\u002Frefreshing-vendors",{"title":341,"path":342,"stem":343},"Reviewing Draft Vendors","\u002Fdata-ops\u002Fdata-management\u002Freviewing-draft-vendors","6.data-ops\u002Fdata-management\u002Freviewing-draft-vendors",{"title":345,"path":346,"stem":347,"children":348,"page":67},"LLM Ops","\u002Fdata-ops\u002Fllm-ops","6.data-ops\u002Fllm-ops",[349,353,357],{"title":350,"path":351,"stem":352},"Agents","\u002Fdata-ops\u002Fllm-ops\u002Fagents","6.data-ops\u002Fllm-ops\u002F1.agents",{"title":354,"path":355,"stem":356},"ESPi Architecture & Query Flow","\u002Fdata-ops\u002Fllm-ops\u002Fespi-architecture","6.data-ops\u002Fllm-ops\u002F2.espi-architecture",{"title":358,"path":359,"stem":360},"Evaluating Agents","\u002Fdata-ops\u002Fllm-ops\u002Fevaluations","6.data-ops\u002Fllm-ops\u002F3.evaluations",{"title":362,"path":363,"stem":364},"Message Queues","\u002Fdata-ops\u002Fmessage-queues","6.data-ops\u002Fmessage-queues",{"title":366,"path":367,"stem":368},"Glossary","\u002Fglossary","glossary",{"id":370,"title":139,"body":371,"description":3472,"extension":3473,"links":3474,"meta":3475,"navigation":751,"path":140,"seo":3476,"stem":141,"__hash__":3477},"docs\u002F3.engineering\u002Fcontributing\u002Fback-end\u002Fllm-prompts.md",{"type":372,"value":373,"toc":3435},"minimark",[374,379,383,388,393,458,461,465,468,472,475,487,510,518,525,561,569,579,586,609,613,620,684,691,710,1118,1122,1142,1664,1668,1677,1679,1686,1694,1698,1701,1727,1743,1749,1755,1772,1780,1791,1812,1814,1818,1821,1866,1868,1872,1878,1881,1904,1911,1963,1969,1988,1990,1994,1997,2057,2078,2080,2084,2093,2096,2099,2101,2105,2109,2112,2135,2139,2146,2174,2176,2185,2198,2229,2235,2237,2241,2271,2273,2277,2326,2332,2346,2348,2352,2355,2373,2457,2467,2469,2473,2477,2480,2614,2618,2624,2674,2678,2727,2731,2780,2782,2784,2788,2792,2801,2899,2913,2915,2919,2922,2947,2951,2988,2990,2994,2998,3086,3090,3093,3146,3148,3152,3299,3301,3307,3313,3355,3357,3361,3431],[375,376,378],"h2",{"id":377},"overview-architecture","Overview & Architecture",[380,381,382],"p",{},"We maintain a strict separation between application code, prompt definitions, and observability:",[384,385],"mermaid",{":zoom":386,"code":387},"1","graph TD\n    A(\"\u003Cdiv align='left'>\u003Cb>platform-api \u002F api-cps\u003C\u002Fb>\u003C\u002Fdiv>\"):::client\n    B(\"\u003Cdiv align='left'>\u003Cb>esp-prompts\u003C\u002Fb> (Git Repo)\u003C\u002Fdiv>\"):::client\n    C(\"\u003Cdiv align='left'>\u003Cb>Langfuse LLMOps Platform\u003C\u002Fb>\u003Cbr\u002F>https:\u002F\u002Fesplf.esprofiler.com\u003Cbr\u002F>• Prompt Versioning & Storage\u003Cbr\u002F>• Environment Labels (staging vs production)\u003Cbr\u002F>• Traces & Generation Spans\u003C\u002Fdiv>\"):::agent\n    D(\"\u003Cdiv align='left'>\u003Cb>Spring Boot: LangfusePromptService\u003C\u002Fb>\u003Cbr\u002F>• Startup Ingestion (ApplicationReadyEvent)\u003Cbr\u002F>• Scheduled Quartz Sweep (Every 20 mins)\u003Cbr\u002F>• Instant Ingestion API (PATCH \u002Fschedules\u002Frun)\u003Cbr\u002F>• Dual-Layer Cache (In-Memory RAM + Disk)\u003Cbr\u002F>• StringTemplate Raw Compilation\u003C\u002Fdiv>\"):::domain\n\n    A -->|Fallback Classpath .st| C\n    B -->|Automated GitHub Actions| C\n    C -->|Dynamic HTTP Fetch & Caching| D\n",[389,390,392],"h3",{"id":391},"core-principles","Core Principles",[394,395,396,415,433,443,452],"ol",{},[397,398,399,403,404,414],"li",{},[400,401,402],"strong",{},"Git is the Single Source of Truth:"," All prompts live in the ",[405,406,410],"a",{"href":407,"rel":408},"https:\u002F\u002Fgithub.com\u002FES-Profiler\u002Fesp-prompts",[409],"nofollow",[411,412,413],"code",{},"esp-prompts"," repository.",[397,416,417,420,421,424,425,428,429,432],{},[400,418,419],{},"Dynamic Ingestion via Langfuse:"," At runtime, services query Langfuse (",[411,422,423],{},"https:\u002F\u002Fesplf.esprofiler.com",") for the prompt version tagged with their target environment label (",[411,426,427],{},"production"," by default, or ",[411,430,431],{},"staging"," in test environments).",[397,434,435,438,439,442],{},[400,436,437],{},"Resilient Local Fallbacks:"," Every prompt declared in code includes a local classpath fallback file (e.g. ",[411,440,441],{},"src\u002Fmain\u002Fresources\u002Fintelligence\u002Fprompts\u002F*.st",") to ensure services start reliably even if Langfuse is unreachable.",[397,444,445,448,449,451],{},[400,446,447],{},"Testing on Staging Before Production:"," Changes must always be verified on Staging before being promoted to ",[411,450,427],{},".",[397,453,454,457],{},[400,455,456],{},"Benchmarking & Evaluation (Future \u002F TBD):"," Automated evaluation pipelines and benchmark datasets by the Data\u002FAI team are planned for future releases. Developers can log data-tasks to contribute to this future benchmark suite.",[459,460],"hr",{},[375,462,464],{"id":463},"adding-new-prompts","Adding New Prompts",[380,466,467],{},"Follow these steps when creating a brand new prompt that has never existed in the platform or Langfuse.",[389,469,471],{"id":470},"workflow-summary","Workflow Summary",[384,473],{":zoom":386,"code":474},"graph TD\n    S1(\"\u003Cdiv align='left'>\u003Cb>1. Backend Implementation\u003C\u002Fb> (platform-api \u002F api-cps)\u003Cbr\u002F>• Create classpath fallback prompt (.st file)\u003Cbr\u002F>• Inject LangfusePromptService and wire ChatClient\u003Cbr\u002F>• Add LangfusePromptObservationAdvisor\u003Cbr\u002F>• Create PR and obtain review approval\u003C\u002Fdiv>\"):::infra\n    S2(\"\u003Cdiv align='left'>\u003Cb>2. Create Prompt in esp-prompts Repository\u003C\u002Fb>\u003Cbr\u002F>• Add prompt markdown file in platform\u002F or cps\u002F\u003Cbr\u002F>• Open PR in esp-prompts referencing backend PR\u003Cbr\u002F>• Merge to main → auto-syncs to Langfuse with staging label\u003C\u002Fdiv>\"):::infra\n    S3(\"\u003Cdiv align='left'>\u003Cb>3. Staging Verification & Testing\u003C\u002Fb>\u003Cbr\u002F>• Deploy\u002Ftest backend on Staging (ESP_LANGFUSE_PROMPTS_LABEL=staging)\u003Cbr\u002F>• Verify generation spans and traces in Langfuse\u003C\u002Fdiv>\"):::infra\n    S4(\"\u003Cdiv align='left'>\u003Cb>4. Open Data-Task for Benchmarking\u003C\u002Fb> (Optional \u002F TBD)\u003Cbr\u002F>• Create GitHub Issue with Data and Back-End labels\u003Cbr\u002F>• Log golden dataset \u002F test scenarios for future AI benchmark suite\u003C\u002Fdiv>\"):::infra\n    S5(\"\u003Cdiv align='left'>\u003Cb>5. Promote Prompt to Production & Release Backend\u003C\u002Fb>\u003Cbr\u002F>• Run 'Promote Prompts to Production' GitHub Action in esp-prompts\u003Cbr\u002F>• Reviewer approves production environment gate in GitHub\u003Cbr\u002F>• Prompt version is labelled production\u003Cbr\u002F>• Merge and release the backend service PR\u003C\u002Fdiv>\"):::client\n\n    S1 --> S2 --> S3 --> S4 --> S5\n",[389,476,478,479,482,483,486],{"id":477},"step-1-backend-implementation-platform-api-api-cps","Step 1: Backend Implementation (",[411,480,481],{},"platform-api"," \u002F ",[411,484,485],{},"api-cps",")",[488,489,491,494,495,498,499,501,502,505,506,509],"callout",{"icon":490},"i-lucide-lightbulb",[400,492,493],{},"Local Development Independence:"," As a backend developer, you do ",[400,496,497],{},"not"," need to wait for ",[411,500,413],{}," or Langfuse to start coding or running unit tests. The backend service is completely functional locally because ",[411,503,504],{},"LangfusePromptService"," uses your local static classpath ",[411,507,508],{},".st"," file whenever a remote prompt is not found or when running offline.",[511,512,514,515,517],"h4",{"id":513},"_1-add-the-static-fallback-prompt-st-file","1. Add the Static Fallback Prompt (",[411,516,508],{}," file)",[380,519,520,521,524],{},"Static fallback prompt templates live under ",[411,522,523],{},"src\u002Fmain\u002Fresources\u002F"," in your backend application:",[526,527,528,547],"ul",{},[397,529,530,535,536,539,540,539,543,546],{},[400,531,532],{},[411,533,534],{},"src\u002Fmain\u002Fresources\u002Fintelligence\u002Fprompts\u002F"," — Standard copilot, insight, and platform agents (e.g., ",[411,537,538],{},"insights\u002Fsignal-evaluation.st",", ",[411,541,542],{},"agent-copilot.st",[411,544,545],{},"agent-notebook.st",").",[397,548,549,554,555,539,558,546],{},[400,550,551],{},[411,552,553],{},"src\u002Fmain\u002Fresources\u002Fagent-tasks\u002F"," — Workflow-specific agents (e.g., ",[411,556,557],{},"agent-tasks\u002Fgeneral\u002F",[411,559,560],{},"agent-tasks\u002Fproduct-comparison\u002F",[380,562,563],{},[400,564,565,566],{},"Example: ",[411,567,568],{},"src\u002Fmain\u002Fresources\u002Fintelligence\u002Fprompts\u002Finsights\u002Fsignal-evaluation.st",[570,571,577],"pre",{"className":572,"code":574,"language":575,"meta":576},[573],"language-text","You are an expert Cybersecurity Intelligence Analyst. Your task is to map a new observation (Finding) to the single best matching high-level trend (Signal) from a provided list of candidate Signals.\n\nStrict Rule: A Finding can only belong to AT MOST ONE Signal.\n\nHere is the Finding to evaluate:\nTitle: \u003Cfinding.title>\nDescription: \u003Cfinding.description>\n\nHere are the candidate Signals:\n\u003CcandidateSignals:{s |\n- ID: \u003Cs.id>\n  Title: \u003Cs.title>\n  Description: \u003Cs.description>\n  Type: \u003Cs.type>\n}>\n","text","",[411,578,574],{"__ignoreMap":576},[380,580,581,582,451],{},"The variables injected are injected into the prompt when ",[405,583,585],{"href":584},"#3-calling-the-agent-service-in-java","calling the agent service in Java",[488,587,589,592,593,596,597,600,601,604,605,608],{"icon":588},"i-lucide-info",[400,590,591],{},"StringTemplate Syntax:"," Prompts support ",[411,594,595],{},"{variable}"," and ",[411,598,599],{},"\u003Cvariable>"," placeholders, object property access (",[411,602,603],{},"\u003Cfinding.title>","), and collection iterations (",[411,606,607],{},"\u003CcandidateSignals:{s | ...}>","). Prompts are synchronized raw so that Spring Boot's StringTemplate engine compiles them directly.",[511,610,612],{"id":611},"understanding-the-prompt-resolution-cache-hierarchy","Understanding the Prompt Resolution & Cache Hierarchy",[380,614,615,616,619],{},"When ",[411,617,618],{},"langfusePromptService.getPrompt(PROMPT_NAME, fallbackPrompt)"," is called at runtime, it resolves the prompt through a 4-tier hierarchy:",[394,621,622,632,651,673],{},[397,623,624,631],{},[400,625,626,627,630],{},"RAM Cache (",[411,628,629],{},"memoryCache"," Map):"," Checked first (0ms latency, zero disk I\u002FO).",[397,633,634,637,638,641,642,645,646,648,649,546],{},[400,635,636],{},"Remote Langfuse Ingestion:"," If online and configured (",[411,639,640],{},"ESP_LLM_OBSERVATION_OTLP_ENDPOINT","), fetches the version tagged with ",[411,643,644],{},"ESP_LANGFUSE_PROMPTS_LABEL"," (",[411,647,427],{}," or ",[411,650,431],{},[397,652,653,664,665,668,669,672],{},[400,654,655,656,659,660,663],{},"Disk Cache (",[411,657,658],{},"resources\u002Fprompts\u002F\u003Cprompt>.st"," & ",[411,661,662],{},".version","):"," Persisted on the container filesystem (configured via ",[411,666,667],{},"esp.langfuse.prompts.cache-dir",", defaults to ",[411,670,671],{},"resources\u002Fprompts\u002F",") so prompts survive network blips.",[397,674,675,678,679,681,682,451],{},[400,676,677],{},"Local Classpath Fallback:"," If Langfuse is unreachable, disabled, or if the prompt hasn't been created in Langfuse yet, it falls back to your local ",[411,680,508],{}," resource in ",[411,683,523],{},[511,685,687,688,690],{"id":686},"_2-wire-langfusepromptservice-and-chatclient-advisor","2. Wire ",[411,689,504],{}," and ChatClient Advisor",[380,692,693,694,697,698,701,702,705,706,709],{},"In your Spring configuration class (e.g., ",[411,695,696],{},"SignalGenerationAgentConfig.java"," in ",[400,699,700],{},"esp-platform"," project), declare a ",[411,703,704],{},"ChatClient"," bean wrapped in ",[411,707,708],{},"ReloadableChatClient",". This binds your feature to Langfuse, attaches OpenTelemetry tracing, and allows the prompt to be hot-reloaded dynamically at runtime:",[570,711,715],{"className":712,"code":713,"filename":696,"language":714,"meta":576,"style":576},"language-java shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","@Configuration\npublic class SignalGenerationAgentConfig {\n\n  private static final String SIGNAL_EVALUATION_PROMPT_NAME = \"signal-evaluation\";\n\n  @Bean\n  public ChatClient signalEvaluationAgent(\n      @Value(\"classpath:intelligence\u002Fprompts\u002Finsights\u002Fsignal-evaluation.st\") Resource systemPrompt,\n      GoogleGenAiChatModel chatModel,\n      ObservedChatClientBuilder observedChatClientBuilder,\n      LangfusePromptService langfusePromptService\n  ) {\n    \u002F\u002F ReloadableChatClient enables zero-downtime hot-swapping of prompt updates\n    return new ReloadableChatClient(SIGNAL_EVALUATION_PROMPT_NAME, () ->\n        observedChatClientBuilder.from(chatModel, \"signal-evaluation\")\n            \u002F\u002F Dynamically loads from Langfuse with fallback to local classpath\n            .defaultSystem(\n                langfusePromptService.getPrompt(SIGNAL_EVALUATION_PROMPT_NAME, systemPrompt))\n            .defaultOptions(GoogleGenAiChatOptions.builder()\n                .model(IntelligenceLevel.MEDIUM.model)\n                .includeThoughts(false))\n            .defaultAdvisors(\n                \u002F\u002F Links OTel spans and Langfuse generation traces to this prompt & version\n                new LangfusePromptObservationAdvisor(SIGNAL_EVALUATION_PROMPT_NAME,\n                    langfusePromptService)\n            )\n            .build()\n    );\n  }\n}\n","java",[411,716,717,730,746,753,788,793,802,818,849,860,871,880,888,895,922,949,955,966,988,1009,1034,1045,1055,1061,1076,1084,1090,1100,1106,1112],{"__ignoreMap":576},[718,719,722,726],"span",{"class":720,"line":721},"line",1,[718,723,725],{"class":724},"sMK4o","@",[718,727,729],{"class":728},"spNyl","Configuration\n",[718,731,733,736,739,743],{"class":720,"line":732},2,[718,734,735],{"class":728},"public",[718,737,738],{"class":728}," class",[718,740,742],{"class":741},"sBMFI"," SignalGenerationAgentConfig",[718,744,745],{"class":724}," {\n",[718,747,749],{"class":720,"line":748},3,[718,750,752],{"emptyLinePlaceholder":751},true,"\n",[718,754,756,759,762,765,768,772,775,778,782,785],{"class":720,"line":755},4,[718,757,758],{"class":728},"  private",[718,760,761],{"class":728}," static",[718,763,764],{"class":728}," final",[718,766,767],{"class":728}," String",[718,769,771],{"class":770},"sTEyZ"," SIGNAL_EVALUATION_PROMPT_NAME ",[718,773,774],{"class":724},"=",[718,776,777],{"class":724}," \"",[718,779,781],{"class":780},"sfazB","signal-evaluation",[718,783,784],{"class":724},"\"",[718,786,787],{"class":724},";\n",[718,789,791],{"class":720,"line":790},5,[718,792,752],{"emptyLinePlaceholder":751},[718,794,796,799],{"class":720,"line":795},6,[718,797,798],{"class":724},"  @",[718,800,801],{"class":728},"Bean\n",[718,803,805,808,811,815],{"class":720,"line":804},7,[718,806,807],{"class":728},"  public",[718,809,810],{"class":728}," ChatClient",[718,812,814],{"class":813},"s2Zo4"," signalEvaluationAgent",[718,816,817],{"class":724},"(\n",[718,819,821,824,827,830,832,835,837,839,842,846],{"class":720,"line":820},8,[718,822,823],{"class":724},"      @",[718,825,826],{"class":728},"Value",[718,828,829],{"class":724},"(",[718,831,784],{"class":724},[718,833,834],{"class":780},"classpath:intelligence\u002Fprompts\u002Finsights\u002Fsignal-evaluation.st",[718,836,784],{"class":724},[718,838,486],{"class":724},[718,840,841],{"class":728}," Resource",[718,843,845],{"class":844},"sHdIc"," systemPrompt",[718,847,848],{"class":724},",\n",[718,850,852,855,858],{"class":720,"line":851},9,[718,853,854],{"class":728},"      GoogleGenAiChatModel",[718,856,857],{"class":844}," chatModel",[718,859,848],{"class":724},[718,861,863,866,869],{"class":720,"line":862},10,[718,864,865],{"class":728},"      ObservedChatClientBuilder",[718,867,868],{"class":844}," observedChatClientBuilder",[718,870,848],{"class":724},[718,872,874,877],{"class":720,"line":873},11,[718,875,876],{"class":728},"      LangfusePromptService",[718,878,879],{"class":844}," langfusePromptService\n",[718,881,883,886],{"class":720,"line":882},12,[718,884,885],{"class":724},"  )",[718,887,745],{"class":724},[718,889,891],{"class":720,"line":890},13,[718,892,894],{"class":893},"sHwdD","    \u002F\u002F ReloadableChatClient enables zero-downtime hot-swapping of prompt updates\n",[718,896,898,902,905,908,910,913,916,919],{"class":720,"line":897},14,[718,899,901],{"class":900},"s7zQu","    return",[718,903,904],{"class":900}," new",[718,906,907],{"class":813}," ReloadableChatClient",[718,909,829],{"class":724},[718,911,912],{"class":770},"SIGNAL_EVALUATION_PROMPT_NAME",[718,914,915],{"class":724},",",[718,917,918],{"class":724}," ()",[718,920,921],{"class":728}," ->\n",[718,923,925,928,930,933,935,938,940,942,944,946],{"class":720,"line":924},15,[718,926,927],{"class":770},"        observedChatClientBuilder",[718,929,451],{"class":724},[718,931,932],{"class":813},"from",[718,934,829],{"class":724},[718,936,937],{"class":770},"chatModel",[718,939,915],{"class":724},[718,941,777],{"class":724},[718,943,781],{"class":780},[718,945,784],{"class":724},[718,947,948],{"class":724},")\n",[718,950,952],{"class":720,"line":951},16,[718,953,954],{"class":893},"            \u002F\u002F Dynamically loads from Langfuse with fallback to local classpath\n",[718,956,958,961,964],{"class":720,"line":957},17,[718,959,960],{"class":724},"            .",[718,962,963],{"class":813},"defaultSystem",[718,965,817],{"class":724},[718,967,969,972,974,977,979,981,983,985],{"class":720,"line":968},18,[718,970,971],{"class":770},"                langfusePromptService",[718,973,451],{"class":724},[718,975,976],{"class":813},"getPrompt",[718,978,829],{"class":724},[718,980,912],{"class":770},[718,982,915],{"class":724},[718,984,845],{"class":770},[718,986,987],{"class":724},"))\n",[718,989,991,993,996,998,1001,1003,1006],{"class":720,"line":990},19,[718,992,960],{"class":724},[718,994,995],{"class":813},"defaultOptions",[718,997,829],{"class":724},[718,999,1000],{"class":770},"GoogleGenAiChatOptions",[718,1002,451],{"class":724},[718,1004,1005],{"class":813},"builder",[718,1007,1008],{"class":724},"()\n",[718,1010,1012,1015,1018,1020,1023,1025,1028,1030,1032],{"class":720,"line":1011},20,[718,1013,1014],{"class":724},"                .",[718,1016,1017],{"class":813},"model",[718,1019,829],{"class":724},[718,1021,1022],{"class":770},"IntelligenceLevel",[718,1024,451],{"class":724},[718,1026,1027],{"class":770},"MEDIUM",[718,1029,451],{"class":724},[718,1031,1017],{"class":770},[718,1033,948],{"class":724},[718,1035,1037,1039,1042],{"class":720,"line":1036},21,[718,1038,1014],{"class":724},[718,1040,1041],{"class":813},"includeThoughts",[718,1043,1044],{"class":724},"(false))\n",[718,1046,1048,1050,1053],{"class":720,"line":1047},22,[718,1049,960],{"class":724},[718,1051,1052],{"class":813},"defaultAdvisors",[718,1054,817],{"class":724},[718,1056,1058],{"class":720,"line":1057},23,[718,1059,1060],{"class":893},"                \u002F\u002F Links OTel spans and Langfuse generation traces to this prompt & version\n",[718,1062,1064,1067,1070,1072,1074],{"class":720,"line":1063},24,[718,1065,1066],{"class":900},"                new",[718,1068,1069],{"class":813}," LangfusePromptObservationAdvisor",[718,1071,829],{"class":724},[718,1073,912],{"class":770},[718,1075,848],{"class":724},[718,1077,1079,1082],{"class":720,"line":1078},25,[718,1080,1081],{"class":770},"                    langfusePromptService",[718,1083,948],{"class":724},[718,1085,1087],{"class":720,"line":1086},26,[718,1088,1089],{"class":724},"            )\n",[718,1091,1093,1095,1098],{"class":720,"line":1092},27,[718,1094,960],{"class":724},[718,1096,1097],{"class":813},"build",[718,1099,1008],{"class":724},[718,1101,1103],{"class":720,"line":1102},28,[718,1104,1105],{"class":724},"    );\n",[718,1107,1109],{"class":720,"line":1108},29,[718,1110,1111],{"class":724},"  }\n",[718,1113,1115],{"class":720,"line":1114},30,[718,1116,1117],{"class":724},"}\n",[511,1119,1121],{"id":1120},"_3-calling-the-agent-service-in-java","3. Calling the Agent Service in Java",[380,1123,1124,1125,1127,1128,1134,1135,648,1138,1141],{},"Inject your configured ",[411,1126,704],{}," bean into your service (e.g., ",[405,1129,1131],{"href":1130},"file:\u002F\u002F\u002Fc:\u002Fdevelopment\u002Fbackend\u002Fapplications\u002Fesp-platform\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fesprofiler\u002Fplatform\u002Finsight\u002Fservice\u002FSignalGenerationService.java",[411,1132,1133],{},"SignalGenerationService.java","), passing parameters into the prompt using ",[411,1136,1137],{},".system(s -> s.param(...))",[411,1139,1140],{},".system(s -> s.params(map))",":",[570,1143,1145],{"className":712,"code":1144,"language":714,"meta":576,"style":576},"package com.esprofiler.platform.insight.service;\n\nimport com.esprofiler.platform.insight.dto.SignalGenerationResponses.SignalMatchResponse;\nimport com.esprofiler.platform.insight.entity.FindingEntity;\nimport com.esprofiler.platform.insight.entity.SignalEntity;\nimport java.util.List;\nimport lombok.RequiredArgsConstructor;\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.ai.chat.client.ChatClient;\nimport org.springframework.beans.factory.annotation.Qualifier;\nimport org.springframework.stereotype.Service;\n\n@Slf4j\n@Service\n@RequiredArgsConstructor\npublic class SignalGenerationService {\n\n  @Qualifier(\"signalEvaluationAgent\")\n  private final ChatClient signalEvaluationAgent;\n\n  public SignalMatchResponse evaluateFinding(FindingEntity finding, List\u003CSignalEntity> candidates) {\n    return signalEvaluationAgent.prompt()\n        \u002F\u002F Passes 'finding' object and 'candidateSignals' collection into the template\n        .system(s -> s\n            .param(\"finding\", finding)\n            .param(\"candidateSignals\", candidates))\n        .user(\"Please evaluate this finding against the candidate signals.\")\n        .call()\n        .entity(SignalMatchResponse.class);\n  }\n}\n",[411,1146,1147,1178,1182,1218,1248,1277,1296,1310,1333,1366,1398,1420,1424,1431,1438,1445,1456,1460,1477,1489,1493,1530,1543,1548,1567,1589,1610,1628,1637,1655,1659],{"__ignoreMap":576},[718,1148,1149,1153,1156,1158,1161,1163,1166,1168,1171,1173,1176],{"class":720,"line":721},[718,1150,1152],{"class":1151},"sbssI","package",[718,1154,1155],{"class":728}," com",[718,1157,451],{"class":724},[718,1159,1160],{"class":728},"esprofiler",[718,1162,451],{"class":724},[718,1164,1165],{"class":728},"platform",[718,1167,451],{"class":724},[718,1169,1170],{"class":728},"insight",[718,1172,451],{"class":724},[718,1174,1175],{"class":728},"service",[718,1177,787],{"class":724},[718,1179,1180],{"class":720,"line":732},[718,1181,752],{"emptyLinePlaceholder":751},[718,1183,1184,1187,1189,1191,1193,1195,1197,1199,1201,1203,1206,1208,1211,1213,1216],{"class":720,"line":748},[718,1185,1186],{"class":1151},"import",[718,1188,1155],{"class":728},[718,1190,451],{"class":724},[718,1192,1160],{"class":728},[718,1194,451],{"class":724},[718,1196,1165],{"class":728},[718,1198,451],{"class":724},[718,1200,1170],{"class":728},[718,1202,451],{"class":724},[718,1204,1205],{"class":728},"dto",[718,1207,451],{"class":724},[718,1209,1210],{"class":728},"SignalGenerationResponses",[718,1212,451],{"class":724},[718,1214,1215],{"class":728},"SignalMatchResponse",[718,1217,787],{"class":724},[718,1219,1220,1222,1224,1226,1228,1230,1232,1234,1236,1238,1241,1243,1246],{"class":720,"line":755},[718,1221,1186],{"class":1151},[718,1223,1155],{"class":728},[718,1225,451],{"class":724},[718,1227,1160],{"class":728},[718,1229,451],{"class":724},[718,1231,1165],{"class":728},[718,1233,451],{"class":724},[718,1235,1170],{"class":728},[718,1237,451],{"class":724},[718,1239,1240],{"class":728},"entity",[718,1242,451],{"class":724},[718,1244,1245],{"class":728},"FindingEntity",[718,1247,787],{"class":724},[718,1249,1250,1252,1254,1256,1258,1260,1262,1264,1266,1268,1270,1272,1275],{"class":720,"line":790},[718,1251,1186],{"class":1151},[718,1253,1155],{"class":728},[718,1255,451],{"class":724},[718,1257,1160],{"class":728},[718,1259,451],{"class":724},[718,1261,1165],{"class":728},[718,1263,451],{"class":724},[718,1265,1170],{"class":728},[718,1267,451],{"class":724},[718,1269,1240],{"class":728},[718,1271,451],{"class":724},[718,1273,1274],{"class":728},"SignalEntity",[718,1276,787],{"class":724},[718,1278,1279,1281,1284,1286,1289,1291,1294],{"class":720,"line":795},[718,1280,1186],{"class":1151},[718,1282,1283],{"class":728}," java",[718,1285,451],{"class":724},[718,1287,1288],{"class":728},"util",[718,1290,451],{"class":724},[718,1292,1293],{"class":728},"List",[718,1295,787],{"class":724},[718,1297,1298,1300,1303,1305,1308],{"class":720,"line":804},[718,1299,1186],{"class":1151},[718,1301,1302],{"class":728}," lombok",[718,1304,451],{"class":724},[718,1306,1307],{"class":728},"RequiredArgsConstructor",[718,1309,787],{"class":724},[718,1311,1312,1314,1316,1318,1321,1323,1326,1328,1331],{"class":720,"line":820},[718,1313,1186],{"class":1151},[718,1315,1302],{"class":728},[718,1317,451],{"class":724},[718,1319,1320],{"class":728},"extern",[718,1322,451],{"class":724},[718,1324,1325],{"class":728},"slf4j",[718,1327,451],{"class":724},[718,1329,1330],{"class":728},"Slf4j",[718,1332,787],{"class":724},[718,1334,1335,1337,1340,1342,1345,1347,1350,1352,1355,1357,1360,1362,1364],{"class":720,"line":851},[718,1336,1186],{"class":1151},[718,1338,1339],{"class":728}," org",[718,1341,451],{"class":724},[718,1343,1344],{"class":728},"springframework",[718,1346,451],{"class":724},[718,1348,1349],{"class":728},"ai",[718,1351,451],{"class":724},[718,1353,1354],{"class":728},"chat",[718,1356,451],{"class":724},[718,1358,1359],{"class":728},"client",[718,1361,451],{"class":724},[718,1363,704],{"class":728},[718,1365,787],{"class":724},[718,1367,1368,1370,1372,1374,1376,1378,1381,1383,1386,1388,1391,1393,1396],{"class":720,"line":862},[718,1369,1186],{"class":1151},[718,1371,1339],{"class":728},[718,1373,451],{"class":724},[718,1375,1344],{"class":728},[718,1377,451],{"class":724},[718,1379,1380],{"class":728},"beans",[718,1382,451],{"class":724},[718,1384,1385],{"class":728},"factory",[718,1387,451],{"class":724},[718,1389,1390],{"class":728},"annotation",[718,1392,451],{"class":724},[718,1394,1395],{"class":728},"Qualifier",[718,1397,787],{"class":724},[718,1399,1400,1402,1404,1406,1408,1410,1413,1415,1418],{"class":720,"line":873},[718,1401,1186],{"class":1151},[718,1403,1339],{"class":728},[718,1405,451],{"class":724},[718,1407,1344],{"class":728},[718,1409,451],{"class":724},[718,1411,1412],{"class":728},"stereotype",[718,1414,451],{"class":724},[718,1416,1417],{"class":728},"Service",[718,1419,787],{"class":724},[718,1421,1422],{"class":720,"line":882},[718,1423,752],{"emptyLinePlaceholder":751},[718,1425,1426,1428],{"class":720,"line":890},[718,1427,725],{"class":724},[718,1429,1430],{"class":728},"Slf4j\n",[718,1432,1433,1435],{"class":720,"line":897},[718,1434,725],{"class":724},[718,1436,1437],{"class":728},"Service\n",[718,1439,1440,1442],{"class":720,"line":924},[718,1441,725],{"class":724},[718,1443,1444],{"class":728},"RequiredArgsConstructor\n",[718,1446,1447,1449,1451,1454],{"class":720,"line":951},[718,1448,735],{"class":728},[718,1450,738],{"class":728},[718,1452,1453],{"class":741}," SignalGenerationService",[718,1455,745],{"class":724},[718,1457,1458],{"class":720,"line":957},[718,1459,752],{"emptyLinePlaceholder":751},[718,1461,1462,1464,1466,1468,1470,1473,1475],{"class":720,"line":968},[718,1463,798],{"class":724},[718,1465,1395],{"class":728},[718,1467,829],{"class":724},[718,1469,784],{"class":724},[718,1471,1472],{"class":780},"signalEvaluationAgent",[718,1474,784],{"class":724},[718,1476,948],{"class":724},[718,1478,1479,1481,1483,1485,1487],{"class":720,"line":990},[718,1480,758],{"class":728},[718,1482,764],{"class":728},[718,1484,810],{"class":728},[718,1486,814],{"class":770},[718,1488,787],{"class":724},[718,1490,1491],{"class":720,"line":1011},[718,1492,752],{"emptyLinePlaceholder":751},[718,1494,1495,1497,1500,1503,1505,1507,1510,1512,1515,1518,1520,1523,1526,1528],{"class":720,"line":1036},[718,1496,807],{"class":728},[718,1498,1499],{"class":728}," SignalMatchResponse",[718,1501,1502],{"class":813}," evaluateFinding",[718,1504,829],{"class":724},[718,1506,1245],{"class":728},[718,1508,1509],{"class":844}," finding",[718,1511,915],{"class":724},[718,1513,1514],{"class":728}," List",[718,1516,1517],{"class":724},"\u003C",[718,1519,1274],{"class":728},[718,1521,1522],{"class":724},">",[718,1524,1525],{"class":844}," candidates",[718,1527,486],{"class":724},[718,1529,745],{"class":724},[718,1531,1532,1534,1536,1538,1541],{"class":720,"line":1047},[718,1533,901],{"class":900},[718,1535,814],{"class":770},[718,1537,451],{"class":724},[718,1539,1540],{"class":813},"prompt",[718,1542,1008],{"class":724},[718,1544,1545],{"class":720,"line":1057},[718,1546,1547],{"class":893},"        \u002F\u002F Passes 'finding' object and 'candidateSignals' collection into the template\n",[718,1549,1550,1553,1556,1558,1561,1564],{"class":720,"line":1063},[718,1551,1552],{"class":724},"        .",[718,1554,1555],{"class":813},"system",[718,1557,829],{"class":724},[718,1559,1560],{"class":770},"s ",[718,1562,1563],{"class":728},"->",[718,1565,1566],{"class":770}," s\n",[718,1568,1569,1571,1574,1576,1578,1581,1583,1585,1587],{"class":720,"line":1078},[718,1570,960],{"class":724},[718,1572,1573],{"class":813},"param",[718,1575,829],{"class":724},[718,1577,784],{"class":724},[718,1579,1580],{"class":780},"finding",[718,1582,784],{"class":724},[718,1584,915],{"class":724},[718,1586,1509],{"class":770},[718,1588,948],{"class":724},[718,1590,1591,1593,1595,1597,1599,1602,1604,1606,1608],{"class":720,"line":1086},[718,1592,960],{"class":724},[718,1594,1573],{"class":813},[718,1596,829],{"class":724},[718,1598,784],{"class":724},[718,1600,1601],{"class":780},"candidateSignals",[718,1603,784],{"class":724},[718,1605,915],{"class":724},[718,1607,1525],{"class":770},[718,1609,987],{"class":724},[718,1611,1612,1614,1617,1619,1621,1624,1626],{"class":720,"line":1092},[718,1613,1552],{"class":724},[718,1615,1616],{"class":813},"user",[718,1618,829],{"class":724},[718,1620,784],{"class":724},[718,1622,1623],{"class":780},"Please evaluate this finding against the candidate signals.",[718,1625,784],{"class":724},[718,1627,948],{"class":724},[718,1629,1630,1632,1635],{"class":720,"line":1102},[718,1631,1552],{"class":724},[718,1633,1634],{"class":813},"call",[718,1636,1008],{"class":724},[718,1638,1639,1641,1643,1645,1647,1649,1652],{"class":720,"line":1108},[718,1640,1552],{"class":724},[718,1642,1240],{"class":813},[718,1644,829],{"class":724},[718,1646,1215],{"class":770},[718,1648,451],{"class":724},[718,1650,1651],{"class":770},"class",[718,1653,1654],{"class":724},");\n",[718,1656,1657],{"class":720,"line":1114},[718,1658,1111],{"class":724},[718,1660,1662],{"class":720,"line":1661},31,[718,1663,1117],{"class":724},[511,1665,1667],{"id":1666},"_4-open-backend-pull-request","4. Open Backend Pull Request",[380,1669,1670,1671,648,1673,1676],{},"Push your branch and open a PR in ",[411,1672,700],{},[411,1674,1675],{},"esp-cps",". Follow standard code review guidelines and obtain approval.",[459,1678],{},[389,1680,1682,1683,1685],{"id":1681},"step-2-create-prompt-in-esp-prompts-repository","Step 2: Create Prompt in ",[411,1684,413],{}," Repository",[380,1687,1688,1689,451],{},"Once your backend PR is reviewed and approved, create the prompt definition in ",[405,1690,1692],{"href":407,"rel":1691},[409],[411,1693,413],{},[511,1695,1697],{"id":1696},"_1-add-the-prompt-file","1. Add the Prompt File",[380,1699,1700],{},"Place your prompt file in the corresponding folder:",[526,1702,1703,1711,1719],{},[397,1704,1705,1710],{},[400,1706,1707],{},[411,1708,1709],{},"platform\u002Fespi\u002F"," — Copilot conversation agents and skills.",[397,1712,1713,1718],{},[400,1714,1715],{},[411,1716,1717],{},"platform\u002Finsights\u002F"," — Automated findings, signals, and synthesis agents.",[397,1720,1721,1726],{},[400,1722,1723],{},[411,1724,1725],{},"cps\u002F"," — Central Provider Service categorization and mapping engines.",[380,1728,1729,1732,1733,1736,1737,648,1740,546],{},[400,1730,1731],{},"Naming Convention:"," Use short, lowercase, hyphenated names matching your ",[411,1734,1735],{},"PROMPT_NAME"," constant (e.g. ",[411,1738,1739],{},"platform\u002Finsights\u002Fsignals\u002Fmy-feature.md",[411,1741,1742],{},"platform\u002Fespi\u002Fskills\u002Fmy-feature-skill\u002FSKILL.md",[511,1744,1746,1747],{"id":1745},"_2-open-pr-in-esp-prompts","2. Open PR in ",[411,1748,413],{},[380,1750,1751,1752,1754],{},"Open a PR in ",[411,1753,413],{}," referencing your backend PR:",[570,1756,1760],{"className":1757,"code":1758,"language":1759,"meta":576,"style":576},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","Relates to ES-Profiler\u002Fplatform-apim#1234\nAdds the new prompt definition for the MyFeature assistant.\n","markdown",[411,1761,1762,1767],{"__ignoreMap":576},[718,1763,1764],{"class":720,"line":721},[718,1765,1766],{},"Relates to ES-Profiler\u002Fplatform-apim#1234\n",[718,1768,1769],{"class":720,"line":732},[718,1770,1771],{},"Adds the new prompt definition for the MyFeature assistant.\n",[511,1773,1775,1776,1779],{"id":1774},"_3-merge-to-main-automatic-staging-sync","3. Merge to ",[411,1777,1778],{},"main"," (Automatic Staging Sync)",[380,1781,1782,1783,697,1785,1787,1788,1141],{},"When merged into ",[411,1784,1778],{},[411,1786,413],{},", GitHub Actions automatically triggers ",[411,1789,1790],{},".github\u002Fworkflows\u002Fsync-prompts-staging.yml",[526,1792,1793,1796,1803],{},[397,1794,1795],{},"It uploads the new prompt to Langfuse.",[397,1797,1798,1799,451],{},"Labels the version as ",[400,1800,1801],{},[411,1802,431],{},[397,1804,1805,1806,539,1809,546],{},"Applies routing tags (e.g. ",[411,1807,1808],{},"service-platform",[411,1810,1811],{},"domain-insights",[459,1813],{},[389,1815,1817],{"id":1816},"step-3-staging-verification-testing","Step 3: Staging Verification & Testing",[380,1819,1820],{},"Verify that your new prompt works end-to-end on Staging:",[394,1822,1823,1837,1840],{},[397,1824,1825,1826],{},"Deploy your backend branch\u002Fbuild to Staging with the staging label enabled:\n",[570,1827,1831],{"className":1828,"code":1829,"language":1830,"meta":576,"style":576},"language-properties shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ESP_LANGFUSE_PROMPTS_LABEL=staging\n","properties",[411,1832,1833],{"__ignoreMap":576},[718,1834,1835],{"class":720,"line":721},[718,1836,1829],{},[397,1838,1839],{},"Trigger the feature in the staging UI or via API endpoint.",[397,1841,1842,1843,1847,1848],{},"Open the ",[405,1844,1846],{"href":423,"rel":1845},[409],"Langfuse Console",":\n",[526,1849,1850,1860],{},[397,1851,1852,1853,1856,1857,1859],{},"Under ",[400,1854,1855],{},"Prompts",", verify that your prompt appears and the ",[411,1858,431],{}," label is assigned.",[397,1861,1852,1862,1865],{},[400,1863,1864],{},"Tracing",", inspect the execution trace and confirm that the generation span is linked to your prompt name and version.",[459,1867],{},[389,1869,1871],{"id":1870},"step-4-open-a-data-task-for-benchmarking-optional-future-tbd","Step 4: Open a Data-Task for Benchmarking (Optional \u002F Future TBD)",[488,1873,1874,1877],{"icon":588},[400,1875,1876],{},"Benchmarking Status (TBD):"," Formal automated evaluation suites with the Data\u002FAI team are currently under active design. While not currently a blocking requirement for releasing prompts today, logging test scenarios helps populate the future evaluation pipeline.",[380,1879,1880],{},"If you wish to log a task for future benchmarking:",[394,1882,1883,1897],{},[397,1884,1885,1886,1889,1890,451],{},"In the repository, go to ",[400,1887,1888],{},"Issues"," > ",[405,1891,1894],{"href":1892,"rel":1893},"https:\u002F\u002Fgithub.com\u002FES-Profiler\u002Fplatform-api\u002Fissues\u002Fnew\u002Fchoose",[409],[400,1895,1896],{},"New Issue",[397,1898,1899,1900,1903],{},"Select the ",[400,1901,1902],{},"Data Benchmarking & Evaluation Task (AI \u002F Prompts)"," template:",[380,1905,1906],{},[1907,1908],"img",{"alt":1909,"src":1910},"GitHub Issue Template Selection","\u002Fimages\u002Fengineering\u002Fllm-prompts\u002Fissue-template-selection.png",[394,1912,1913],{"start":748},[397,1914,1915,1916],{},"Fill out the pre-populated form fields:\n",[526,1917,1918,1926,1937,1945,1951,1957],{},[397,1919,1920,1923,1924],{},[400,1921,1922],{},"Prompt Name in Langfuse:"," e.g. ",[411,1925,781],{},[397,1927,1928,1923,1931,1934,1935,486],{},[400,1929,1930],{},"Langfuse Version:",[411,1932,1933],{},"v1"," (currently tagged ",[411,1936,431],{},[397,1938,1939,1923,1942],{},[400,1940,1941],{},"Target Service & Related PRs:",[411,1943,1944],{},"platform-api (ES-Profiler\u002Fplatform-api#1234, ES-Profiler\u002Fesp-prompts#56)",[397,1946,1947,1950],{},[400,1948,1949],{},"Objective & Functional Role:"," Purpose, input context parameters, and expected JSON output structure.",[397,1952,1953,1956],{},[400,1954,1955],{},"Test Scenarios & Golden Dataset:"," Test cases or edge cases to populate the evaluation suite.",[397,1958,1959,1962],{},[400,1960,1961],{},"Langfuse Reference URLs:"," Direct links to the prompt in Langfuse and sample staging trace.",[380,1964,1965],{},[1907,1966],{"alt":1967,"src":1968},"GitHub Issue Form Fields","\u002Fimages\u002Fengineering\u002Fllm-prompts\u002Fissue-template-form.png",[394,1970,1971],{"start":755},[397,1972,1973,1974,596,1979,1984,1985,451],{},"The template automatically attaches the ",[400,1975,1976],{},[411,1977,1978],{},"Data",[400,1980,1981],{},[411,1982,1983],{},"Back-End"," labels. Click ",[400,1986,1987],{},"Submit new issue",[459,1989],{},[389,1991,1993],{"id":1992},"step-5-promote-prompt-to-production-release-backend","Step 5: Promote Prompt to Production & Release Backend",[380,1995,1996],{},"Once staging testing is complete:",[394,1998,1999,2035],{},[397,2000,2001,2006],{},[400,2002,2003,2004,1141],{},"Promote Prompt in ",[411,2005,413],{},[526,2007,2008,2019,2029],{},[397,2009,2010,2011,1889,2014,451],{},"Go to ",[400,2012,2013],{},"Actions",[405,2015,2018],{"href":2016,"rel":2017},"https:\u002F\u002Fgithub.com\u002FES-Profiler\u002Fesp-prompts\u002Factions\u002Fworkflows\u002Fpromote-prompts.yml",[409],"Promote Prompts to Production",[397,2020,2021,2022,2025,2026,546],{},"Enter your prompt name in the ",[411,2023,2024],{},"prompts"," input (e.g. ",[411,2027,2028],{},"my-feature",[397,2030,2031,2032,2034],{},"Run workflow. Review the dry-run plan, and have a required reviewer approve the ",[411,2033,427],{}," environment gate.",[397,2036,2037,2040],{},[400,2038,2039],{},"Release Backend Code:",[526,2041,2042,2050],{},[397,2043,2044,2045,482,2047,2049],{},"Merge and release the ",[411,2046,481],{},[411,2048,485],{}," PR.",[397,2051,2052,2053,2056],{},"Production containers boot up, query Langfuse for ",[411,2054,2055],{},"label=production",", and ingest the newly promoted prompt.",[488,2058,2059,2062,2063,2065,2066,2070,2071,2074,2075,2077],{"icon":588},[400,2060,2061],{},"How Version Promotion Works:"," The promotion workflow does ",[400,2064,497],{}," blindly promote the latest unverified version number. Instead, it explicitly targets the version currently tagged with the ",[400,2067,2068],{},[411,2069,431],{}," label (the version you tested), prints a dry-run diff in the ",[411,2072,2073],{},"plan"," step, and applies the ",[411,2076,427],{}," label only after review approval.",[459,2079],{},[375,2081,2083],{"id":2082},"modifying-existing-prompts","Modifying Existing Prompts",[380,2085,2086,2087,648,2090,451],{},"When modifying a prompt that already exists in production, determine whether the change is ",[400,2088,2089],{},"prompt-content only",[400,2091,2092],{},"requires backend code changes",[389,2094,471],{"id":2095},"workflow-summary-1",[384,2097],{":zoom":386,"code":2098},"graph TD\n    Start{\"Modifying an Existing Prompt\"}:::agent\n\n    ScenA(\"\u003Cdiv align='left'>\u003Cb>Scenario A: Content-Only\u003C\u002Fb>\u003Cbr\u002F>Tuning wording, system instructions,\u003Cbr\u002F>few-shot examples, reasoning steps\u003C\u002Fdiv>\"):::infra\n    ScenB(\"\u003Cdiv align='left'>\u003Cb>Scenario B: With Code Changes\u003C\u002Fb>\u003Cbr\u002F>Adding\u002Fremoving template variables,\u003Cbr\u002F>changing DTO schema, modifying tools\u003C\u002Fdiv>\"):::infra\n\n    BCode(\"\u003Cdiv align='left'>\u003Cb>1. Update .st fallback & Java code\u003C\u002Fb>\u003Cbr\u002F>\u003Cb>2. Open PR in platform-api \u002F api-cps\u003C\u002Fb>\u003C\u002Fdiv>\"):::domain\n\n    Sync(\"\u003Cdiv align='left'>\u003Cb>1. Edit prompt file in esp-prompts\u003C\u002Fb>\u003Cbr\u002F>\u003Cb>2. Open PR in esp-prompts\u003C\u002Fb>\u003Cbr\u002F>\u003Cb>3. Merge to main → auto-syncs with staging label\u003C\u002Fb>\u003C\u002Fdiv>\"):::client\n\n    Stage(\"\u003Cdiv align='left'>\u003Cb>2. Test changes on Staging\u003C\u002Fb>\u003Cbr\u002F>ESP_LANGFUSE_PROMPTS_LABEL=staging\u003C\u002Fdiv>\"):::infra\n\n    Promote(\"\u003Cdiv align='left'>\u003Cb>3. Promote prompt to Production via\u003C\u002Fb>\u003Cbr\u002F>GitHub Action in esp-prompts\u003C\u002Fdiv>\"):::agent\n\n    Ingest(\"\u003Cdiv align='left'>\u003Cb>4. Ingest Prompt Updates:\u003C\u002Fb>\u003Cbr\u002F>• Automatic: Quartz (Every 20 mins)\u003Cbr\u002F>• OR Instant: PATCH \u002Fapi\u002Fv1\u002Fschedules\u002Frun\u003C\u002Fdiv>\"):::domain\n\n    Start -->|Content Only| ScenA\n    Start -->|Code Changes| ScenB\n    ScenB --> BCode\n    BCode --> Sync\n    ScenA --> Sync\n    Sync --> Stage\n    Stage --> Promote\n    Promote --> Ingest\n",[459,2100],{},[389,2102,2104],{"id":2103},"step-1-determine-modification-type-content-only-vs-code-changes","Step 1: Determine Modification Type (Content-Only vs Code Changes)",[511,2106,2108],{"id":2107},"scenario-a-content-only-modification-zero-downtime-no-backend-redeploy","Scenario A: Content-Only Modification (Zero-Downtime, No Backend Redeploy)",[380,2110,2111],{},"If you are refining prompt instructions, improving persona prompts, tuning few-shot examples, or reducing hallucinations:",[394,2113,2114,2125,2131],{},[397,2115,2116,2117,2119,2120,648,2122,2124],{},"You do ",[400,2118,497],{}," need to touch ",[411,2121,481],{},[411,2123,485],{}," code immediately.",[397,2126,2127,2128,2130],{},"Go directly to ",[411,2129,413],{}," and edit the markdown prompt file.",[397,2132,1751,2133,451],{},[411,2134,413],{},[511,2136,2138],{"id":2137},"scenario-b-modification-with-backend-code-changes","Scenario B: Modification with Backend Code Changes",[380,2140,2141,2142,2145],{},"If your prompt change involves adding\u002Fremoving StringTemplate variables (e.g. ",[411,2143,2144],{},"\u003CnewVariable>","), altering input\u002Foutput JSON DTOs, or changing tool calls:",[394,2147,2148,2159,2166],{},[397,2149,2150,2151,2153,2154,648,2156,2158],{},"Update the fallback ",[411,2152,508],{}," file in ",[411,2155,481],{},[411,2157,485],{}," and modify the corresponding Java classes.",[397,2160,1751,2161,482,2163,2165],{},[411,2162,481],{},[411,2164,485],{}," and obtain review approval.",[397,2167,2168,2169,2171,2172,451],{},"Update the prompt file in ",[411,2170,413],{}," to match the new variable schema and open a matching PR in ",[411,2173,413],{},[459,2175],{},[389,2177,2179,2180,697,2182,2184],{"id":2178},"step-2-merge-to-main-in-esp-prompts-staging-sync","Step 2: Merge to ",[411,2181,1778],{},[411,2183,413],{}," (Staging Sync)",[380,2186,2187,2188,2190,2191,2193,2194,2197],{},"When your ",[411,2189,413],{}," PR merges to ",[411,2192,1778],{},", the ",[411,2195,2196],{},"sync-prompts-staging.yml"," workflow triggers automatically:",[526,2199,2200,2211,2219],{},[397,2201,2202,2203,2206,2207,2210],{},"Langfuse creates a ",[400,2204,2205],{},"new version"," (e.g. ",[411,2208,2209],{},"v3",") with your updated prompt.",[397,2212,2213,2214,2218],{},"The ",[400,2215,2216],{},[411,2217,431],{}," label moves to this new version.",[397,2220,2213,2221,2225,2226,546],{},[400,2222,2223],{},[411,2224,427],{}," label remains untouched on the existing live version (e.g. ",[411,2227,2228],{},"v2",[570,2230,2233],{"className":2231,"code":2232,"language":575},[573],"Before Sync:   staging -> v2 (live)      production -> v2 (live)\nAfter Sync:    staging -> v3 (updated)   production -> v2 (live)\n",[411,2234,2232],{"__ignoreMap":576},[459,2236],{},[389,2238,2240],{"id":2239},"step-3-verify-on-staging","Step 3: Verify on Staging",[394,2242,2243,2250],{},[397,2244,2245,2246,2249],{},"On the Staging environment (",[411,2247,2248],{},"ESP_LANGFUSE_PROMPTS_LABEL=staging","), execute the modified workflow.",[397,2251,2252,2253,2257,2258],{},"Check the ",[405,2254,2256],{"href":423,"rel":2255},[409],"Langfuse Tracing dashboard"," to verify:\n",[526,2259,2260,2268],{},[397,2261,2262,2263,2265,2266,546],{},"The trace links to the new ",[411,2264,431],{}," version number (e.g. ",[411,2267,2209],{},[397,2269,2270],{},"The LLM response meets expectations and adheres to formatting.",[459,2272],{},[389,2274,2276],{"id":2275},"step-4-promote-prompt-to-production","Step 4: Promote Prompt to Production",[394,2278,2279,2288,2296],{},[397,2280,2010,2281,697,2283,1889,2285,451],{},[400,2282,2013],{},[411,2284,413],{},[405,2286,2018],{"href":2016,"rel":2287},[409],[397,2289,2290,2291,2025,2293,2295],{},"Enter the specific prompt name in the ",[411,2292,2024],{},[411,2294,2028],{},") to promote only the targeted prompt.",[397,2297,2298,2299,1847,2302],{},"Click ",[400,2300,2301],{},"Run workflow",[526,2303,2304,2311,2319],{},[397,2305,2213,2306,2310],{},[400,2307,2308],{},[411,2309,2073],{}," job prints a dry-run diff of the versions that will move.",[397,2312,2313,2314,2318],{},"The workflow pauses at the ",[400,2315,2316],{},[411,2317,427],{}," environment review gate.",[397,2320,2321,2322,451],{},"Once approved, the job copies the staging version and labels it ",[400,2323,2324],{},[411,2325,427],{},[570,2327,2330],{"className":2328,"code":2329,"language":575},[573],"After Promotion:   staging -> v3             production -> v4 (copy of v3)\n",[411,2331,2329],{"__ignoreMap":576},[488,2333,2334,2337,2338,2342,2343,2345],{"icon":588},[400,2335,2336],{},"Targeting the Verified Version:"," Promotion does not select untracked or raw drafts; it targets the specific version currently tagged with ",[400,2339,2340],{},[411,2341,431],{},", allowing you to inspect the version diff during the ",[411,2344,2073],{}," step prior to approval.",[459,2347],{},[389,2349,2351],{"id":2350},"step-5-ingest-prompt-updates-automatic-vs-instant-refresh","Step 5: Ingest Prompt Updates (Automatic vs Instant Refresh)",[380,2353,2354],{},"After promoting a prompt in Langfuse, backend services pick up the change without restarting:",[394,2356,2357,2367],{},[397,2358,2359,2362,2363,2366],{},[400,2360,2361],{},"Automatic Quartz Refresh:"," The backend background job runs every ",[400,2364,2365],{},"20 minutes"," and automatically fetches updated prompt versions.",[397,2368,2369,2372],{},[400,2370,2371],{},"Instant Manual Trigger:"," If you need the change to take effect immediately without waiting for the 20-minute timer, trigger the prompt refresh Quartz job via the API endpoint:",[570,2374,2378],{"className":2375,"code":2376,"language":2377,"meta":576,"style":576},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -X PATCH \"https:\u002F\u002Fplatform.esprofiler.com\u002Fapi\u002Fv1\u002Fschedules\u002Frun\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer \u003CAPI_OR_SSO_TOKEN>\" \\\n  -d '{\n    \"jobName\": \"langfusePromptRefreshJob\",\n    \"groupName\": \"DEFAULT\"\n  }'\n","bash",[411,2379,2380,2401,2415,2428,2439,2444,2449],{"__ignoreMap":576},[718,2381,2382,2385,2388,2391,2393,2396,2398],{"class":720,"line":721},[718,2383,2384],{"class":741},"curl",[718,2386,2387],{"class":780}," -X",[718,2389,2390],{"class":780}," PATCH",[718,2392,777],{"class":724},[718,2394,2395],{"class":780},"https:\u002F\u002Fplatform.esprofiler.com\u002Fapi\u002Fv1\u002Fschedules\u002Frun",[718,2397,784],{"class":724},[718,2399,2400],{"class":770}," \\\n",[718,2402,2403,2406,2408,2411,2413],{"class":720,"line":732},[718,2404,2405],{"class":780},"  -H",[718,2407,777],{"class":724},[718,2409,2410],{"class":780},"Content-Type: application\u002Fjson",[718,2412,784],{"class":724},[718,2414,2400],{"class":770},[718,2416,2417,2419,2421,2424,2426],{"class":720,"line":748},[718,2418,2405],{"class":780},[718,2420,777],{"class":724},[718,2422,2423],{"class":780},"Authorization: Bearer \u003CAPI_OR_SSO_TOKEN>",[718,2425,784],{"class":724},[718,2427,2400],{"class":770},[718,2429,2430,2433,2436],{"class":720,"line":755},[718,2431,2432],{"class":780},"  -d",[718,2434,2435],{"class":724}," '",[718,2437,2438],{"class":780},"{\n",[718,2440,2441],{"class":720,"line":790},[718,2442,2443],{"class":780},"    \"jobName\": \"langfusePromptRefreshJob\",\n",[718,2445,2446],{"class":720,"line":795},[718,2447,2448],{"class":780},"    \"groupName\": \"DEFAULT\"\n",[718,2450,2451,2454],{"class":720,"line":804},[718,2452,2453],{"class":780},"  }",[718,2455,2456],{"class":724},"'\n",[488,2458,2460,2463,2464,2466],{"icon":2459},"i-lucide-check-circle",[400,2461,2462],{},"Zero-Downtime Live Update:"," For content-only changes (Scenario A), ",[411,2465,481],{}," updates its RAM and disk cache immediately upon running the schedule action. No container restart or deployment is required!",[459,2468],{},[375,2470,2472],{"id":2471},"quartz-scheduled-ingestion-manual-refresh-api","Quartz Scheduled Ingestion & Manual Refresh API",[389,2474,2476],{"id":2475},"quartz-background-job-configuration","Quartz Background Job Configuration",[380,2478,2479],{},"Backend services run a background Quartz job dedicated to refreshing dynamic prompts:",[2481,2482,2483,2499],"table",{},[2484,2485,2486],"thead",{},[2487,2488,2489,2493,2496],"tr",{},[2490,2491,2492],"th",{},"Attribute",[2490,2494,2495],{},"Value \u002F Default",[2490,2497,2498],{},"Description",[2500,2501,2502,2518,2533,2548,2566,2584,2599],"tbody",{},[2487,2503,2504,2510,2515],{},[2505,2506,2507],"td",{},[400,2508,2509],{},"Job Name",[2505,2511,2512],{},[411,2513,2514],{},"langfusePromptRefreshJob",[2505,2516,2517],{},"Identifier of the Quartz job bean.",[2487,2519,2520,2525,2530],{},[2505,2521,2522],{},[400,2523,2524],{},"Job Group",[2505,2526,2527],{},[411,2528,2529],{},"DEFAULT",[2505,2531,2532],{},"Quartz job group.",[2487,2534,2535,2540,2545],{},[2505,2536,2537],{},[400,2538,2539],{},"Trigger Name",[2505,2541,2542],{},[411,2543,2544],{},"Langfuse Prompt Refresh Trigger",[2505,2546,2547],{},"Quartz trigger bean name.",[2487,2549,2550,2555,2563],{},[2505,2551,2552],{},[400,2553,2554],{},"Startup Delay",[2505,2556,2557,645,2560,486],{},[411,2558,2559],{},"15 minutes",[411,2561,2562],{},"TimeUnit.MINUTES.toMillis(15)",[2505,2564,2565],{},"Initial delay after server boot before first periodic sweep.",[2487,2567,2568,2573,2581],{},[2505,2569,2570],{},[400,2571,2572],{},"Repeat Interval",[2505,2574,2575,645,2577,2580],{},[411,2576,2365],{},[411,2578,2579],{},"1200000"," ms)",[2505,2582,2583],{},"Frequency of automatic prompt refresh sweeps.",[2487,2585,2586,2591,2596],{},[2505,2587,2588],{},[400,2589,2590],{},"Configuration Property",[2505,2592,2593],{},[411,2594,2595],{},"esp.langfuse.prompts.refresh-interval-ms",[2505,2597,2598],{},"Config property to customize the repeat interval.",[2487,2600,2601,2606,2611],{},[2505,2602,2603],{},[400,2604,2605],{},"Environment Variable",[2505,2607,2608],{},[411,2609,2610],{},"ESP_LANGFUSE_PROMPTS_REFRESH_INTERVAL_MS",[2505,2612,2613],{},"Override via container environment variable.",[389,2615,2617],{"id":2616},"triggering-manual-prompt-refresh-via-api","Triggering Manual Prompt Refresh via API",[380,2619,2620,2621,2623],{},"You can trigger ",[411,2622,2514],{}," at any time using the Schedule Management API:",[526,2625,2626,2635,2643,2661],{},[397,2627,2628,2631,2632],{},[400,2629,2630],{},"Endpoint:"," ",[411,2633,2634],{},"PATCH \u002Fapi\u002Fv1\u002Fschedules\u002Frun",[397,2636,2637,2631,2640],{},[400,2638,2639],{},"Controller:",[411,2641,2642],{},"ScheduleController.admScheduleRunAction",[397,2644,2645,2648,2649,2652,2653,645,2658,486],{},[400,2646,2647],{},"Swagger UI:"," Accessible at ",[411,2650,2651],{},"\u002Fapi\u002Fv1\u002Fdocs\u002Fui"," under tag ",[400,2654,2655],{},[411,2656,2657],{},"Z1 - Schedule Management",[411,2659,2660],{},"Z2.02 -- admScheduleRunAction",[397,2662,2663,2666,2667,2670,2671,451],{},[400,2664,2665],{},"Security:"," Requires ",[411,2668,2669],{},"ESP-SSO"," authentication or ",[411,2672,2673],{},"X-API-KEY",[511,2675,2677],{"id":2676},"request-example-json","Request Example (JSON)",[570,2679,2683],{"className":2680,"code":2681,"language":2682,"meta":576,"style":576},"language-http shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","PATCH \u002Fapi\u002Fv1\u002Fschedules\u002Frun HTTP\u002F1.1\nHost: platform.esprofiler.com\nContent-Type: application\u002Fjson\nAuthorization: Bearer \u003CAUTH_TOKEN>\n\n{\n  \"jobName\": \"langfusePromptRefreshJob\",\n  \"groupName\": \"DEFAULT\"\n}\n","http",[411,2684,2685,2690,2695,2700,2705,2709,2713,2718,2723],{"__ignoreMap":576},[718,2686,2687],{"class":720,"line":721},[718,2688,2689],{},"PATCH \u002Fapi\u002Fv1\u002Fschedules\u002Frun HTTP\u002F1.1\n",[718,2691,2692],{"class":720,"line":732},[718,2693,2694],{},"Host: platform.esprofiler.com\n",[718,2696,2697],{"class":720,"line":748},[718,2698,2699],{},"Content-Type: application\u002Fjson\n",[718,2701,2702],{"class":720,"line":755},[718,2703,2704],{},"Authorization: Bearer \u003CAUTH_TOKEN>\n",[718,2706,2707],{"class":720,"line":790},[718,2708,752],{"emptyLinePlaceholder":751},[718,2710,2711],{"class":720,"line":795},[718,2712,2438],{},[718,2714,2715],{"class":720,"line":804},[718,2716,2717],{},"  \"jobName\": \"langfusePromptRefreshJob\",\n",[718,2719,2720],{"class":720,"line":820},[718,2721,2722],{},"  \"groupName\": \"DEFAULT\"\n",[718,2724,2725],{"class":720,"line":851},[718,2726,1117],{},[511,2728,2730],{"id":2729},"success-response","Success Response",[570,2732,2736],{"className":2733,"code":2734,"language":2735,"meta":576,"style":576},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"success\": true,\n  \"message\": \"Task run request processed!\"\n}\n","json",[411,2737,2738,2742,2757,2776],{"__ignoreMap":576},[718,2739,2740],{"class":720,"line":721},[718,2741,2438],{"class":724},[718,2743,2744,2747,2750,2752,2754],{"class":720,"line":732},[718,2745,2746],{"class":724},"  \"",[718,2748,2749],{"class":728},"success",[718,2751,784],{"class":724},[718,2753,1141],{"class":724},[718,2755,2756],{"class":724}," true,\n",[718,2758,2759,2761,2764,2766,2768,2770,2773],{"class":720,"line":748},[718,2760,2746],{"class":724},[718,2762,2763],{"class":728},"message",[718,2765,784],{"class":724},[718,2767,1141],{"class":724},[718,2769,777],{"class":724},[718,2771,2772],{"class":780},"Task run request processed!",[718,2774,2775],{"class":724},"\"\n",[718,2777,2778],{"class":720,"line":755},[718,2779,1117],{"class":724},[459,2781],{},[459,2783],{},[375,2785,2787],{"id":2786},"technical-reference-best-practices","Technical Reference & Best Practices",[389,2789,2791],{"id":2790},"environment-configuration-target-labels","Environment Configuration & Target Labels",[380,2793,2794,2795,2797,2798,663],{},"Backend services configure which prompt versions to fetch via the ",[411,2796,644],{}," environment variable (mapped to ",[411,2799,2800],{},"esp.langfuse.prompts.label",[2481,2802,2803,2818],{},[2484,2804,2805],{},[2487,2806,2807,2810,2815],{},[2490,2808,2809],{},"Environment",[2490,2811,2812,2813,486],{},"Configured Label (",[411,2814,644],{},[2490,2816,2817],{},"Behavior & Purpose",[2500,2819,2820,2848,2869],{},[2487,2821,2822,2830,2834],{},[2505,2823,2824],{},[400,2825,2826,2827,486],{},"Staging (",[411,2828,2829],{},"stage",[2505,2831,2832],{},[411,2833,431],{},[2505,2835,2836,2842,2843,697,2845,2847],{},[400,2837,2838,2839,2841],{},"Always reads ",[411,2840,431],{}," prompts."," Picks up the latest prompts merged into ",[411,2844,1778],{},[411,2846,413],{}," for verification before release.",[2487,2849,2850,2858,2862],{},[2505,2851,2852],{},[400,2853,2854,2855,486],{},"Production (",[411,2856,2857],{},"prod",[2505,2859,2860],{},[411,2861,427],{},[2505,2863,2864,2868],{},[400,2865,2838,2866,2841],{},[411,2867,427],{}," Strictly uses versions that have passed through the promotion review gate in GitHub Actions.",[2487,2870,2871,2880,2888],{},[2505,2872,2873],{},[400,2874,2875,2876,2879],{},"Development (",[411,2877,2878],{},"dev"," \u002F Local)",[2505,2881,2882,2631,2884],{},[411,2883,427],{},[2885,2886,2887],"em",{},"(default)",[2505,2889,2890,2895,2896,2898],{},[400,2891,2892,2893],{},"Defaults to ",[411,2894,427],{}," so local development mirrors live production behavior. Can be overridden to ",[411,2897,431],{}," in local properties or IDE run configurations to test upcoming prompts.",[570,2900,2902],{"className":1828,"code":2901,"language":1830,"meta":576,"style":576},"# Example: Switch local or test environment to read staging prompts\nESP_LANGFUSE_PROMPTS_LABEL=staging\n",[411,2903,2904,2909],{"__ignoreMap":576},[718,2905,2906],{"class":720,"line":721},[718,2907,2908],{},"# Example: Switch local or test environment to read staging prompts\n",[718,2910,2911],{"class":720,"line":732},[718,2912,1829],{},[459,2914],{},[389,2916,2918],{"id":2917},"disabling-langfuse-prompt-sync-during-local-testing","Disabling Langfuse Prompt Sync During Local Testing",[380,2920,2921],{},"When testing local prompt changes or debugging offline, you can completely disable remote Langfuse prompt synchronization:",[570,2923,2925],{"className":1828,"code":2924,"language":1830,"meta":576,"style":576},"# In application-local.properties or your IDE Environment Variables\nESP_LANGFUSE_PROMPTS_ENABLED=false\n# or in application.yml \u002F properties:\nesp.langfuse.prompts.enabled=false\n",[411,2926,2927,2932,2937,2942],{"__ignoreMap":576},[718,2928,2929],{"class":720,"line":721},[718,2930,2931],{},"# In application-local.properties or your IDE Environment Variables\n",[718,2933,2934],{"class":720,"line":732},[718,2935,2936],{},"ESP_LANGFUSE_PROMPTS_ENABLED=false\n",[718,2938,2939],{"class":720,"line":748},[718,2940,2941],{},"# or in application.yml \u002F properties:\n",[718,2943,2944],{"class":720,"line":755},[718,2945,2946],{},"esp.langfuse.prompts.enabled=false\n",[511,2948,2950],{"id":2949},"what-happens-when-prompt-sync-is-disabled","What happens when prompt sync is disabled?",[394,2952,2953,2961,2973,2979],{},[397,2954,2955,2631,2958,2960],{},[400,2956,2957],{},"Zero Remote Calls:",[411,2959,504],{}," completely skips remote HTTP requests to Langfuse.",[397,2962,2963,2966,2967,2969,2970,2972],{},[400,2964,2965],{},"Direct Classpath Fallback:"," Services immediately use your local ",[411,2968,508],{}," template files from ",[411,2971,534],{}," on every invocation.",[397,2974,2975,2978],{},[400,2976,2977],{},"Bypasses Cache:"," Disk cache reads\u002Fwrites and Quartz periodic refresh sweeps are bypassed.",[397,2980,2981,2984,2985,2987],{},[400,2982,2983],{},"Instant Iteration:"," You can modify your local ",[411,2986,508],{}," file and test changes immediately without any remote sync or cache invalidation.",[459,2989],{},[389,2991,2993],{"id":2992},"langfuse-labels-tags-reference","Langfuse Labels & Tags Reference",[511,2995,2997],{"id":2996},"_1-version-labels-prompt-routing","1. Version Labels (Prompt Routing)",[2481,2999,3000,3015],{},[2484,3001,3002],{},[2487,3003,3004,3007,3010,3013],{},[2490,3005,3006],{},"Label",[2490,3008,3009],{},"Managed By",[2490,3011,3012],{},"Environment Target",[2490,3014,2498],{},[2500,3016,3017,3040,3063],{},[2487,3018,3019,3025,3029,3033],{},[2505,3020,3021],{},[400,3022,3023],{},[411,3024,431],{},[2505,3026,3027],{},[411,3028,2196],{},[2505,3030,2826,3031,486],{},[411,3032,2829],{},[2505,3034,3035,3036,697,3038,451],{},"Automatically assigned when a PR merges into ",[411,3037,1778],{},[411,3039,413],{},[2487,3041,3042,3048,3053,3060],{},[2505,3043,3044],{},[400,3045,3046],{},[411,3047,427],{},[2505,3049,3050],{},[411,3051,3052],{},"promote-prompts.yml",[2505,3054,2854,3055,3057,3058,486],{},[411,3056,2857],{},"), Dev (",[411,3059,2878],{},[2505,3061,3062],{},"Assigned when a prompt is approved and promoted via the GitHub Action.",[2487,3064,3065,3072,3075,3080],{},[2505,3066,3067],{},[400,3068,3069],{},[411,3070,3071],{},"latest",[2505,3073,3074],{},"Langfuse Internal",[2505,3076,3077],{},[2885,3078,3079],{},"None",[2505,3081,3082,3083],{},"Internal Langfuse pointer to the newest draft. ",[400,3084,3085],{},"DO NOT USE in application code.",[511,3087,3089],{"id":3088},"_2-metadata-tags-filtering-categorization","2. Metadata Tags (Filtering & Categorization)",[380,3091,3092],{},"Prompts in Langfuse are automatically tagged during CI sync to allow easy filtering:",[526,3094,3095,3116],{},[397,3096,3097,3100],{},[400,3098,3099],{},"Service Tags:",[526,3101,3102,3109],{},[397,3103,3104,3106,3107,451],{},[411,3105,1808],{}," — Prompts consumed by ",[411,3108,481],{},[397,3110,3111,3106,3114,451],{},[411,3112,3113],{},"service-cps",[411,3115,485],{},[397,3117,3118,3121],{},[400,3119,3120],{},"Domain \u002F Subsystem Tags:",[526,3122,3123,3128,3134,3140],{},[397,3124,3125,3127],{},[411,3126,1811],{}," — Finding and Signal generation, emergence, and evaluation agents.",[397,3129,3130,3133],{},[411,3131,3132],{},"domain-copilot"," — Interactive chat assistants, skills, and conversation namers.",[397,3135,3136,3139],{},[411,3137,3138],{},"domain-tasks"," — Deep research, report generation, and background analyst workflows.",[397,3141,3142,3145],{},[411,3143,3144],{},"domain-changelog"," — Changelog and revision comparison agents.",[459,3147],{},[389,3149,3151],{"id":3150},"environment-variables-summary","Environment Variables Summary",[2481,3153,3154,3169],{},[2484,3155,3156],{},[2487,3157,3158,3161,3164,3167],{},[2490,3159,3160],{},"Variable",[2490,3162,3163],{},"Property",[2490,3165,3166],{},"Default",[2490,3168,2498],{},[2500,3170,3171,3195,3218,3237,3255,3277],{},[2487,3172,3173,3178,3183,3188],{},[2505,3174,3175],{},[411,3176,3177],{},"ESP_LANGFUSE_PROMPTS_ENABLED",[2505,3179,3180],{},[411,3181,3182],{},"esp.langfuse.prompts.enabled",[2505,3184,3185],{},[411,3186,3187],{},"true",[2505,3189,3190,3191,3194],{},"Enable\u002Fdisable remote Langfuse prompt fetching. Set ",[411,3192,3193],{},"false"," for offline local testing.",[2487,3196,3197,3201,3205,3209],{},[2505,3198,3199],{},[411,3200,644],{},[2505,3202,3203],{},[411,3204,2800],{},[2505,3206,3207],{},[411,3208,427],{},[2505,3210,3211,3212,3214,3215,3217],{},"Target prompt label (",[411,3213,427],{}," in Prod\u002FDev, ",[411,3216,431],{}," in Staging).",[2487,3219,3220,3225,3229,3234],{},[2505,3221,3222],{},[411,3223,3224],{},"ESP_LANGFUSE_PROMPTS_CACHE_DIR",[2505,3226,3227],{},[411,3228,667],{},[2505,3230,3231],{},[411,3232,3233],{},"resources\u002Fprompts",[2505,3235,3236],{},"Local container directory for caching fetched prompt templates on disk.",[2487,3238,3239,3243,3247,3252],{},[2505,3240,3241],{},[411,3242,2610],{},[2505,3244,3245],{},[411,3246,2595],{},[2505,3248,3249,3251],{},[411,3250,2579],{}," (20m)",[2505,3253,3254],{},"Interval in ms for the periodic Quartz background prompt refresh job.",[2487,3256,3257,3261,3266,3271],{},[2505,3258,3259],{},[411,3260,640],{},[2505,3262,3263],{},[411,3264,3265],{},"esp.llm.observation.otlp.endpoint",[2505,3267,3268],{},[411,3269,3270],{},"\"\"",[2505,3272,3273,3274,546],{},"Langfuse OTLP endpoint (e.g. ",[411,3275,3276],{},"https:\u002F\u002Fesplf.esprofiler.com\u002Fapi\u002Fpublic\u002Fotel\u002Fv1\u002Ftraces",[2487,3278,3279,3284,3289,3293],{},[2505,3280,3281],{},[411,3282,3283],{},"ESP_LLM_OBSERVATION_OTLP_AUTH",[2505,3285,3286],{},[411,3287,3288],{},"esp.llm.observation.otlp.auth",[2505,3290,3291],{},[411,3292,3270],{},[2505,3294,3295,3296,546],{},"Base64-encoded Langfuse public and secret key (",[411,3297,3298],{},"Basic \u003Cauth>",[459,3300],{},[389,3302,3304,3305,486],{"id":3303},"caching-architecture-in-spring-boot-langfusepromptservice","Caching Architecture in Spring Boot (",[411,3306,504],{},[380,3308,3309,3310,3312],{},"To eliminate latency and avoid external API limits, ",[411,3311,504],{}," implements a resilient multi-tier cache:",[394,3314,3315,3323,3333,3346],{},[397,3316,3317,3322],{},[400,3318,626,3319,663],{},[411,3320,3321],{},"ConcurrentHashMap"," Instant prompt lookup during request processing.",[397,3324,3325,3332],{},[400,3326,655,3327,596,3329,663],{},[411,3328,658],{},[411,3330,3331],{},"\u003Cprompt>.version"," Persisted locally across container restarts.",[397,3334,3335,3338,3339,3342,3343,3345],{},[400,3336,3337],{},"Startup Ingestion:"," During ",[411,3340,3341],{},"ApplicationReadyEvent",", the service performs a remote ingestion sweep of all registered ",[411,3344,708],{}," beans.",[397,3347,3348,3351,3352,3354],{},[400,3349,3350],{},"Periodic Refresh:"," Scheduled background Quartz job (",[411,3353,2514],{},") periodically sweeps and reloads prompt updates from Langfuse every 20 minutes.",[459,3356],{},[389,3358,3360],{"id":3359},"troubleshooting-common-issues","Troubleshooting Common Issues",[526,3362,3363,3391,3412],{},[397,3364,3365,3368],{},[400,3366,3367],{},"Prompt returns fallback content on startup:",[526,3369,3370,3378,3388],{},[397,3371,3372,3373,3375,3376,546],{},"Check that ",[411,3374,640],{}," is configured correctly (e.g. ",[411,3377,3276],{},[397,3379,3380,3381,3383,3384,648,3386,546],{},"Verify that ",[411,3382,644],{}," matches the label present in Langfuse (",[411,3385,431],{},[411,3387,427],{},[397,3389,3390],{},"Check that the prompt name passed in Java matches the prompt name in Langfuse exactly.",[397,3392,3393,3396],{},[400,3394,3395],{},"HTTP 403 \u002F Cloudflare WAF block during sync:",[526,3397,3398,3401],{},[397,3399,3400],{},"Some prompts contain HTML\u002FJavaScript snippets. Cloudflare WAF rules may block POST requests containing script tags.",[397,3402,3403,3404,3407,3408,3411],{},"Ensure the Cloudflare WAF skip rule is configured for ",[411,3405,3406],{},"\u002Fapi\u002Fpublic\u002F"," or that ",[411,3409,3410],{},"LANGFUSE_EXTRA_HEADERS"," contains the appropriate bypass secret.",[397,3413,3414,3417],{},[400,3415,3416],{},"Span not linked in Langfuse Traces:",[526,3418,3419],{},[397,3420,3421,3422,3425,3426,3428,3429,451],{},"Ensure ",[411,3423,3424],{},"new LangfusePromptObservationAdvisor(PROMPT_NAME, langfusePromptService)"," is registered in ",[411,3427,1052],{}," on the ",[411,3430,704],{},[3432,3433,3434],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":576,"searchDepth":732,"depth":732,"links":3436},[3437,3440,3450,3459,3463],{"id":377,"depth":732,"text":378,"children":3438},[3439],{"id":391,"depth":748,"text":392},{"id":463,"depth":732,"text":464,"children":3441},[3442,3443,3445,3447,3448,3449],{"id":470,"depth":748,"text":471},{"id":477,"depth":748,"text":3444},"Step 1: Backend Implementation (platform-api \u002F api-cps)",{"id":1681,"depth":748,"text":3446},"Step 2: Create Prompt in esp-prompts Repository",{"id":1816,"depth":748,"text":1817},{"id":1870,"depth":748,"text":1871},{"id":1992,"depth":748,"text":1993},{"id":2082,"depth":732,"text":2083,"children":3451},[3452,3453,3454,3456,3457,3458],{"id":2095,"depth":748,"text":471},{"id":2103,"depth":748,"text":2104},{"id":2178,"depth":748,"text":3455},"Step 2: Merge to main in esp-prompts (Staging Sync)",{"id":2239,"depth":748,"text":2240},{"id":2275,"depth":748,"text":2276},{"id":2350,"depth":748,"text":2351},{"id":2471,"depth":732,"text":2472,"children":3460},[3461,3462],{"id":2475,"depth":748,"text":2476},{"id":2616,"depth":748,"text":2617},{"id":2786,"depth":732,"text":2787,"children":3464},[3465,3466,3467,3468,3469,3471],{"id":2790,"depth":748,"text":2791},{"id":2917,"depth":748,"text":2918},{"id":2992,"depth":748,"text":2993},{"id":3150,"depth":748,"text":3151},{"id":3303,"depth":748,"text":3470},"Caching Architecture in Spring Boot (LangfusePromptService)",{"id":3359,"depth":748,"text":3360},"Step-by-step guide for backend developers on adding new prompts, modifying existing prompts across platform-api and api-cps, integrating with Langfuse and esp-prompts, Quartz reload scheduling, and coordinating Data\u002FAI team benchmarking.","md",null,{},{"title":139,"description":3472},"4bX8TIzh7cvLEdIGO9MhbsP3gFrAGshWkR4thV3vRGk",[3479,3481],{"title":135,"path":136,"stem":137,"description":3480,"children":-1},"This guide provides a set of guidelines for designing and implementing APIs in the back-end of ESProfiler",{"title":148,"path":149,"stem":150,"description":576,"children":-1},1790076750107]