{"slug": "what-to-do-in-such-situations-developing-an-app-integrated-with-generative-ai", "title": "What to do in such situations: Developing an app integrated with generative AI", "summary": "Engineer pj-corridor developed a generative AI-integrated personality assessment app and detailed the trade-offs involved in prompt tuning, abuse mitigation, and cost control. The developer kept rule-based scoring deterministic and limited generative AI to supplementary text to contain hallucinations, and deployed AWS WAF rules, rate limiting, and cookie-based access controls against bot abuse. The engineer noted that WAF's fixed cost exceeded Bedrock usage costs at the app's traffic scale and is considering suspending it in favor of DynamoDB-based POST request limits.", "body_md": "Hello, I’m pj-corridor, an engineer. In this article, I will introduce the challenges I faced while developing an application integrated with generative AI, such as dealing with abuse and navigating trial-and-error and trade-offs in prompt tuning. I previously had the opportunity to work with Synergy Marketing, and I am grateful that they kindly agreed to publish this article on the TECHSCORE BLOG 😊 Thank you very much.\n\nFirst, please try the personality assessment app I initially developed. The annoying ads 😆 can be hidden by adjusting the window width.\n\nLike the popular MBTI, CAPS and DiSC are so-called pseudoscientific personality assessments. They should not be used as a basis for decision-making, but for example, having workshop participants share their results can help energize self-introduction sessions and warm up the atmosphere. Please consider using this assessment app on such occasions.\n\nFor reference, here is my CAPS assessment result.\n\nThe advice and user manual are generated by AI, but the sudden appearance of “Respondent” in Japanese sentences feels a bit unnatural. In this way, while generative AI provides rich expressive capabilities, it also introduces quality risks. That said, I wanted to keep the cost of ensuring quality within the scope of a hobby project. Therefore, I kept the rule-based scoring logic deterministic and limited the generative AI output to supplementary text, thereby controlling the impact of hallucinations.\n\nFrom here, I will introduce concrete examples of trial and error and how I approached trade-offs, divided into three chapters.\n\nThe assessment app can be accessed anonymously, but the backend uses a paid generative AI service (Amazon Bedrock). Therefore, being overwhelmed by bot abuse is a plausible scenario. However, rather than aiming to eliminate all threats, I adopted a basic policy of considering the attacker’s incentives: “accept threats with low manifestation risk, and mitigate the rest.”\n\nFor WAF, referring to AWS’s standard protection pack, I adopted:\n\n`GeoRule` (blocking IPs from regions with frequent attacks)`AWS-AWSManagedRulesAmazonIpReputationList` (blocking known malicious IPs)`AWS-AWSManagedRulesAnonymousIpList` (blocking anonymized/tunneled IPs)`GlobalRateBasedRule` for the assessment app (request rate limiting)`RateBasedRulePOST` (limiting POST/PUT/DELETE requests)\nand removed unnecessary rules such as `AWS-AWSManagedRulesSQLiRuleSet`. However, when using a Lambda Function URL as a public endpoint, there is concern that requests not routed through CloudFront could bypass the WAF. While it is possible to enforce CloudFront (and thus WAF) routing, doing so would require AWS-specific implementations, such as:\n\n`AuthType` to `AWS_IAM` and using CloudFront OAC\n👉 This requires support for `x-amz-content-sha256` in POST requests\nIn any case, AWS-dependent implementation would be necessary. Considering the risk that a malicious actor could discover the Lambda Function URL and bypass the WAF, I decided not to implement this measure for now.\n\nAs a side note, settings configured in the AWS console are easy to forget. Forgetting to revert temporary settings can cause issues. To avoid this, I recommend managing managed service configurations in a repository (something close to IaC).\n\nFor example, for a WAF protection pack:\n\nAlso, as a follow-up: with the traffic scale of this app, the fixed cost of WAF ended up exceeding the usage-based cost of Bedrock. A good lesson in estimating costs 😅. Going forward, I am considering suspending WAF until traffic increases and instead implementing POST request limits using DynamoDB.\n\nFor access control, I implemented:\n\n`Set-Cookie`\n`credentials: 'include'`\nAdditionally, I applied:\n\n`SameSite=Strict` to block cookies in cross-domain POST requests (see `Access-Control-Allow-Origin` to a whitelist to limit browser-based access\nThese measures can be bypassed by more sophisticated bots, but I decided to start within the scope of the basic policy and consider additional measures while monitoring access patterns.\n\nHere I describe trial and error related to Lambda and API Gateway.\n\nLambda was a reasonable choice for the runtime environment, but I initially preferred:\n\nI leaned toward (1) because I already had a local PHP testing environment, which seemed suitable for agile development and testing. However, considering compatibility with Lambda and concerns about CI complexity, I ultimately chose (2). In hindsight, I spent more time dealing with AWS environment nuances and black-box behavior, so it turned out to be the right choice.\n\nSpeaking of trial and error, repeatedly creating Lambda functions via the AWS console automatically generates new IAM roles each time. Not just these remnants, but leaving unused resources can become technical debt, so they should be cleaned up promptly.\n\nI resisted the urge to jump into development and prepared a mechanism to handle Lambda and test environments transparently.\n\nThis later became the foundation for prompt tuning.\n\nAs for whether to use API Gateway:\n\n| Feature | Implementation | \n|---|---|\n| Authentication | Custom access control | \n| Routing | Handled within Lambda | \n| Throttling | Handled by WAF (planned to change) | \n\nGiven this, I decided not to use API Gateway at this stage, as the cost outweighed the benefits.\n\nWith abuse prevention and technology selection in place, it was time for development. Once completed, I wanted to share it globally via Reddit. That led to the motivation to support multiple languages, so I implemented a simple i18n class to support 9 languages.\n\n``` js\nconst GREETING = i18n.text({\n    en : 'Hello',\n    ja : 'こんにちは',\n    fr : 'Bonjour',\n    de : 'Hallo',\n    es : 'Hola',\n    pt : 'Olá',\n    hi : 'नमस्ते',\n    ko : '안녕하세요',\n    zh : '你好'\n})\n```\n\nTo stabilize AI output quality, I used the user’s native language for UI but fixed the AI input language to English.\n\nI also unified state management, UI components, and interfaces with Lambda/test environments between DiSC and CAPS, enabling reuse for future assessments like MBTI.\n\nFinally, I focused on improving and stabilizing AI output quality through prompt tuning. Instead of rushing, I first built a foundation:\n\nDuring this process, I discovered missing outputs in `hi`, `ko`, and `zh`, likely due to token differences across languages.\n\nAlso, AI suggestions tend to bloat prompts with redundant instructions, so consolidating and refactoring prompt structure is recommended.\n\nFinally, about “Respondent”: the requirement was to fix the subject as colleagues/friends while referring to the user consistently. Attempts like:\n\n```\n...use the {{lang}} term for \"Respondent\".\n```\n\nresulted in “you,” while banning pronouns led to “Respondent.” To stabilize output, I used:\n\n```\nalways use the fixed keyword \"_RESPONDENT_\"\n```\n\nand replaced it client-side 😅\n\n``` js\nconst RESPONDENT = i18n.text({\n    en : 'Respondent',\n    ja : '回答者',\n    fr : 'Répondant',\n    de : 'Befragter',\n    es : 'Encuestado',\n    pt : 'Respondente',\n    hi : 'उत्तरदाता',\n    ko : '응답자',\n    zh : '受访者'\n});\n```\n\nThank you for reading. In this project, I focused on structuring prompt tuning while controlling hallucination impact. Future improvements may include automated output quality checks:\n\nI hope my trial-and-error and trade-off decisions are helpful to you.", "url": "https://wpnews.pro/news/what-to-do-in-such-situations-developing-an-app-integrated-with-generative-ai", "canonical_source": "https://dev.to/pj-corridor/what-to-do-in-such-situations-developing-an-app-integrated-with-generative-ai-21f4", "published_at": "2026-09-22 05:04:43+00:00", "updated_at": "2026-09-22 05:22:48.426709+00:00", "lang": "en", "topics": ["generative-ai", "ai-products", "ai-tools", "ai-infrastructure"], "entities": ["pj-corridor", "Amazon Bedrock", "AWS", "CloudFront", "AWS WAF", "Lambda", "DynamoDB", "Synergy Marketing"], "alternates": {"html": "https://wpnews.pro/news/what-to-do-in-such-situations-developing-an-app-integrated-with-generative-ai", "markdown": "https://wpnews.pro/news/what-to-do-in-such-situations-developing-an-app-integrated-with-generative-ai.md", "text": "https://wpnews.pro/news/what-to-do-in-such-situations-developing-an-app-integrated-with-generative-ai.txt", "jsonld": "https://wpnews.pro/news/what-to-do-in-such-situations-developing-an-app-integrated-with-generative-ai.jsonld"}}