LINE

107 posts

techblog.lycorp.co.jp/ko

Filter by tag

line3 min readCurated summary

On-Device Image Model Training for Mess

This post describes an on-device image captioning system for mobile messenger apps. Because autoregressive vision-language models took more than five seconds to generate captions, the team replaced them with a non-autoregressive decoder, reducing latency to roughly 200–400 ms. They then used LLM-based acceptance evaluation, caption re-generation, and multi-stage knowledge distillation to improve quality while keeping the model at 172 MB. ## Why Conventional Captioning Was Unsuitable - Models such as BLIP-2, MobileVLM, PaliGemma, and MiniCPM were too large or slow for mobile deployment. - BLIP-1 was selected as a practical baseline because of its smaller size and clear licensing, but still required more than five seconds after quantization. - Autoregressive decoding generates tokens sequentially, requiring one decoder pass per token. - On a Samsung Galaxy Fold 4, the initial model required about 142 ms per token, or approximately 2.8 seconds for 20 tokens. - Mobile UX required stable latency in the hundreds of milliseconds, including cold-start and variable-device conditions, so simple model compression was insufficient. ## Non-Autoregressive Caption Generation - The system predicts all caption tokens in parallel using a fixed set of learnable query tokens. - This changes the decoding cost from roughly O(T) for autoregressive generation to near O(1) through parallel processing. - The architecture consists of: - An image encoder reused from the previous system - Image embeddings injected as a prefix, following the ClipCap approach - A 66.4-million-parameter Transformer-based text decoder - Twenty learnable query tokens for short captions - Query-CTC loss addresses the alignment problem caused by predicting tokens simultaneously. - The resulting model generated captions in about 200 ms, achieving the required speed improvement. ## Speed Improved, but Caption Quality Declined - Standard metrics such as CIDEr and CLIPScore appeared acceptable. - Manual inspection revealed frequent: - Repeated words, such as “a desk with a computer on a desk” - Spelling errors, such as “a people ons” - Grammatical problems - Incomplete captions, such as “a” - These defects made the model unsuitable for direct use in a messaging product. ## LLM-Based Acceptance Evaluation - The team introduced an “accept ratio” based on GPT-4o mini judgments. - Captions were classified as either `accept` or `non-accept`. - The evaluation checked for: - Duplicate content - Errors - Clarity and grammatical correctness - This better reflected production usability than conventional image-captioning benchmarks. - The low acceptance rate confirmed that CIDEr and CLIPScore alone could not measure whether captions were appropriate for users. ## Data Quality and Knowledge Distillation - Analysis showed that the training data contained inconsistent and noisy captions: - A mixture of very short and overly long descriptions - Unnecessary OCR-like attempts to describe text in images - Uneven language quality - The smaller 66.4-million-parameter model also had less representational capacity than BLIP-1’s 110 million parameters. - Generating an entire sentence in one pass was especially difficult for the compact non-autoregressive model. - The training pipeline was redesigned as an iterative quality-improvement loop: - Train a baseline using the original data - Identify failures with LLM-based acceptance evaluation - Re-caption poor-quality training examples - Distill knowledge from a larger teacher model into the student model - Replace or refine rejected samples and repeat - Architectural scaling and metric optimization did not consistently improve acceptance rates, while re-captioning and knowledge distillation produced more meaningful gains. The practical recommendation is to design on-device captioning around the actual product experience: prioritize parallel decoding for latency, measure quality with production-oriented acceptance criteria, and use carefully curated data plus knowledge distillation to make compact models reliable.

Read original(opens in new tab)
line4 min readCurated summary

On-Device Image Model

The post describes building an on-device image understanding system for messaging apps, with semantic image search as the first focus. Its central strategy was knowledge distillation: a multilingual student text encoder learned to reproduce the embedding space of a strong, English-only teacher model. This preserved most English retrieval quality while enabling Japanese, Traditional Chinese, Thai, and Korean search, achieving an average Recall@5 above 78%. ## Why Messaging Apps Need On-Device Image Understanding - Images are often treated simply as “a photo,” unlike text messages, which can support search, summaries, and notification previews. - Image understanding could improve: - Notifications: “Sent one photo” → “Sent a photo of a dog” - Search: queries such as “dog,” “puppy,” or “a cat inside a box” - Recommendations: automatic image classification and organization - Shared image-text embeddings allow semantically equivalent phrases—such as “dog,” “puppy,” and “개”—to retrieve the same images. ## Why the Model Had to Run On-Device - **Latency:** Network round trips make notifications and search less predictable and responsive. - **Privacy:** Sending photos, captions, or embeddings to a server increases privacy risks. - **Offline support:** The feature should work in subways, airplanes, roaming environments, and unstable networks. - **Mobile constraints:** The model needed to run on both Android and iOS with limited memory and compute resources. - The project targeted a model under **200 MB**, response times within a few hundred milliseconds including cold start, and LiteRT compatibility. ## Project Goals and Evaluation - The image search system needed to: - Retrieve images by semantic meaning rather than keyword matching. - Support English, Japanese, Traditional Chinese, Thai, and Korean. - A separate captioning system was designed to generate short, natural descriptions of roughly eight words or fewer. - Search quality was measured using: - Image-to-Text Recall@5 - Text-to-Image Recall@5 - Caption quality was evaluated with CIDEr, CLIPScore, and an LLM-based acceptance ratio designed to detect repetition, typos, and grammatical problems. ## Why Translation Was Not Enough The initial approach translated each query into English before using an English-only image-text model: ```text Query → Language detection → Translation → English text encoder → Embedding → Search ``` This approach introduced several problems: - **Quality loss:** Informal terms or short queries could be mistranslated. For example, “멍멍이” might be interpreted as “barking” instead of “dog.” - **Additional latency:** Translation adds a fixed cost before text encoding. - **Inconsistent results:** Translation quality varies by language pair and wording. - **Operational complexity:** Each additional language requires more models, updates, and failure handling. Training a multilingual image-text model from scratch would require substantial data and compute. Instead, the project retained the proven English image embedding space and expanded only the text encoder. ## Knowledge Distillation for Multilingual Search - The original English text encoder served as the frozen **teacher**. - A copied text encoder served as the trainable **student**. - English text was passed to the teacher, while corresponding multilingual text was passed to the student. - The student was trained to match the teacher’s embeddings using mean squared error (MSE). ```text teacher_embedding = teacher(English text) student_embedding = student(Multilingual text) loss = MSE(teacher_embedding, student_embedding) ``` The image encoder remained frozen so that the established image-text embedding space would not be disrupted. Important implementation considerations included: - Ensuring the tokenizer handled multilingual characters correctly. - Defining consistent case-insensitivity rules. - Balancing training samples across languages. - Matching training-time preprocessing and tokenization with mobile inference behavior. ## Retrieval Results - English performance declined slightly: - Image-to-Text Recall@5: **79.58% → 76.56%** - Text-to-Image Recall@5: **75.89% → 74.47%** - Multilingual performance improved from below **10% average Recall@5** to above **78%**, roughly a sevenfold improvement. - Japanese achieved **81.94%**, exceeding the original English model in the reported evaluation. - Traditional Chinese, Thai, and Korean also reached practically usable retrieval quality. The trade-off—slightly lower English performance in exchange for four additional languages—provided substantially greater overall product value. ## Converting the Model to LiteRT - LiteRT was selected because it officially supports both Android and iOS and provides mobile-oriented operators, quantization, and optimization tools. - Core ML was rejected because it is iOS-specific and introduced conversion and long-term cross-platform maintenance concerns. - Conversion required addressing unsupported PyTorch operators. - For example, LiteRT did not support `erf`, so the model’s implementation had to replace it with a compatible pseudo-`erf` operation. The resulting approach demonstrates that knowledge distillation can efficiently extend an existing English image-text model to multiple languages while preserving its on-device deployment advantages.

Read original(opens in new tab)
line4 min readCurated summary

Sharing the journey of LINE DEV

AI adoption at LY Corporation has moved beyond experimentation toward learning how to use these tools effectively in real work. The LINE DEV AI Reporters program connects scattered individual and team experiences through internal sharing sessions, helping practical lessons spread across the organization. Its central conclusion is that AI productivity depends not only on tools, but also on clear specifications, sound engineering practices, and a culture of continuous sharing. ## Turning Individual Experiments into Organizational Knowledge - AI enthusiasts across LY Corporation were independently experimenting with tools such as ChatGPT and Claude Code. - These experiences often remained limited to individuals or small teams. - AI Reporters brought together members of different roles and seniority who had experience sharing AI-related work. - Their goal was to turn personal trial and error into reusable organizational knowledge. ## Starting with Informal Personal Experiments - Early AI sharing sessions emphasized accessibility rather than polished success stories. - Multimedia Platform Dev’s Choi Jeong-min shared a “one service a day” vibe-coding experiment using Claude Code and Antigravity. - The experiment demonstrated that rapid implementation increases the importance of clearly defining what to build. - Sharing failures and unfinished experiments reduced the pressure to perform and encouraged more employees to try AI themselves. ## Applying AI to Real Development Work - As interest grew, discussions shifted from fun experiments to practical workplace applications. - Data Dev4’s Lee Yun-seong shared more than a month of project experience using Claude Code, project templates, and Vibe Kanban. - Developers spent more time on planning, design, review, and coordination while agents handled implementation. - Because the current codebase becomes the context for future agent work, poor architecture and coding styles can quickly be reproduced and amplified. - Continuous testing, refactoring, documentation, interface management, and architectural cleanup are therefore essential. - Skipping automated tests before commits led to increasing numbers of broken changes during later merges. - Humans remain responsible for ensuring that AI-generated code actually contributes to the project. - The most valuable skills increasingly involve task design, project management, system context, and meta-programming rather than implementation alone. - Developers can work in parallel with agents by planning the next task, researching requirements, and reviewing completed code while agents execute current work. ## Expanding from Teams to Organization-Wide Programs - Fintech Engineering organized a hands-on workshop covering the full path from idea to deployment. - Participants connected ChatGPT, Claude Code, and Stitch AI to plan, design, build, and complete a working service. - The integrated workflow helped participants understand how AI tools can support an entire product-development process, not just prototyping. - The GAI Study Group in the advertising organization broadened discussions to AI strategy, trends, agent behavior, developer workflows, and business applications. - Topics included: - AI agent reliability - Implementing interactions between PyTorch-based LLMs and MCP servers - Senior and junior developers’ vibe-coding workflows - NotebookLM-based RAG using wiki pages and Slack conversations - One session examined MCP internals by implementing JSON-RPC messaging and session-state management directly, revealing complexities hidden by libraries such as FastMCP. - Sessions were opened to participants and presenters from other teams, with some content published online for wider access. ## Building a Culture of Continuous Sharing - The most useful AI knowledge came from real workplace attempts, failures, and revisions—not only from polished documentation or external trends. - AI Reporters made existing but scattered experiences visible and connected them through presentations, Slack discussions, and monthly meetings. - Informal conversations such as “I tried this—how did it work for you?” helped normalize experimentation and learning from mistakes. - AI adoption is treated as an ongoing practice because tools and workflows continue to change. LY Corporation’s experience suggests that organizations should create lightweight, recurring forums where employees can share practical AI experiments. The combination of rapid experimentation, disciplined engineering, and open knowledge exchange allows individual discoveries to become lasting organizational capability.

Read original(opens in new tab)
line3 min readCurated summary

Claude Code Action: Platformizing AI Code

LINE NEXT transformed Claude Code from an individual productivity tool into an organization-wide code review platform integrated with GitHub Actions. The goal was to reduce review-quality variation, standardize policies, and make AI feedback part of the existing pull request workflow. Its central design separates simple repository-level invocation from centrally managed execution, prompts, permissions, and infrastructure. ## Why AI Code Review Needed to Be Platformized - As LINE NEXT’s services and repositories grew, human code review quality varied according to each reviewer’s experience and preferences. - Developers were already using Claude Code locally, but individual usage created several problems: - Inconsistent review criteria and perspectives - No organization-wide quality process - AI feedback disconnected from pull request workflows - Difficulty providing new employees with a consistent review experience - DevOps therefore treated the issue as a decentralized quality-process problem rather than merely a tooling problem. ## Why GitHub Actions and Claude Code - GitHub Actions was already the foundation for CI/CD and automation across LINE NEXT repositories. - It allowed the team to: - Apply a common workflow repository by repository - Centrally manage execution environments and permissions - Avoid requiring each service team to build additional infrastructure - Claude Code Action integrated directly with pull requests: - Developers could trigger reviews with an `@claude` mention. - Results appeared as GitHub comments or PR reviews. - Developers did not need to learn a separate interface. - A shared GitHub App Runner environment provided consistent execution and centralized security controls. ## Centralized Caller–Executor Architecture - Service repositories act as **callers**: - They invoke the standard workflow. - They provide only basic parameters such as service name and review type. - A centrally managed DevOps repository acts as the **executor**: - Stores prompts and review personas - Defines review policies and priorities - Manages permissions and authentication - Contains the actual execution logic - This design makes AI review an organization-wide platform capability rather than a separate configuration maintained by every project. ### Benefits of Central Control - **Consistent quality:** Central prompts and personas ensure common review depth, tone, security checks, stability checks, and priorities. - **Faster adoption:** New repositories need only add the standard workflow and specify a few parameters. - **Improved governance:** GitHub Apps, centrally managed secrets, and shared runners make it possible to track who accessed which code and with what permissions. - **Lower operational overhead:** Service teams use the platform without managing AI infrastructure themselves. ## Handling Fork-Based Pull Requests - The official Claude Code Action initially assumed that a PR branch existed in the base repository’s `origin`. - For pull requests created from forks, this caused failures such as: ```text couldn't find remote ref ``` - The original implementation fetched and checked out the branch by name: ```text git fetch origin <branch> git checkout <branch> ``` - This failed because fork branches exist in the external repository, not necessarily in the base repository. - From a platform perspective, this was a structural limitation because it blocked external contributors and collaboration repositories. - The proposed direction was to redesign the execution flow rather than simply add an exception, using GitHub’s special pull-request reference: ```text refs/pull/<PR number>/head ``` This approach allows the workflow to retrieve the actual pull request head commit regardless of whether the PR originated from the main repository or a fork.

Read original(opens in new tab)
line3 min readCurated summary

Slow Query Resolution: Optimizing Bit

LINE VOOM’s post server experienced intermittent timeouts when loading profiles belonging to users with hundreds of thousands of posts. The root cause was bitwise filtering on `category_flag` and `access_flag`, which prevented MySQL from efficiently using indexes and forced scans of all posts for a user. The team resolved the issue with MySQL 8.0.13 functional indexes and by changing the query predicates to exact decimal comparisons, reducing scanned rows from 805 to 31 in testing. ## The Slow Query and Its Root Cause - Post metadata was distributed across shards and partitioned tables. - `category_flag` and `access_flag` were stored as `bit(64)` values containing multiple status flags. - The problematic query filtered by: - `user_id` - `category_flag & 0x0100` - `access_flag & 0x0001` - For heavy users, the query scanned hundreds of thousands of posts and ran for more than 30 seconds. - Bitwise expressions operated on computed results rather than raw column values, preventing normal indexes from filtering efficiently. ## Choosing Functional Indexes - The team considered hardware upgrades, caching, and additional partitioning, but none addressed the root cause adequately. - MySQL 8.0.13 functional indexes could index expression results without changing the table schema. - The proposed composite index was: ```sql ALTER TABLE post_metadata ADD INDEX idx_user_premium_searchable ( user_id, (category_flag & 0x0100), (access_flag & 0x0001) ); ``` - Functional indexes rely on the query expression matching the index definition precisely. ## Discovering the Required Query Form - Initial attempts failed to use the index: - Truthy checks such as `category_flag & 0x0100` - Comparisons using `> 0` - Equality against hexadecimal values such as `= 0x0100` - The successful form used decimal equality: ```sql WHERE user_id = '{user_id}' AND (category_flag & 0x0100) = 256 AND (access_flag & 0x0001) = 1 ``` - In testing, scanned rows dropped from 805 to 31. - Index storage increased by approximately 24%, but the DBA team determined that production capacity was sufficient. ## Rolling Out the Indexes in Production - Indexes were created before changing the application queries. - The team used online schema changes to avoid service downtime and support pausing or rollback during replication problems. - Because dozens of tables across multiple shards were affected: - One shard was handled first for validation. - Only one or two tables were processed per day. - Work was avoided during periods when emergency DBA support was unavailable. - Index creation increased replication lag, causing newly created posts to temporarily disappear from read replicas. - The team reduced the cache expiration time for the affected post lists and accepted the remaining replication delay before resuming the rollout. ## Gradual Query Deployment and a Bitwise Logic Bug - Query changes were deployed gradually through a dynamic configuration system. - Each query pattern was tested on one shard before being expanded to the remaining shards. - This allowed changes to be rolled back immediately through configuration. - During rollout, a serious visibility bug was found. - The original condition: ```sql category_flag & 0x0110 ``` matched when either `0x0100` or `0x0010` was present, effectively representing an OR condition. - Rewriting it as: ```sql (category_flag & 0x0110) = 272 ``` required both bits to be set, creating an AND condition. - Because production data stored only the premium bit, some profiles returned no content. - The incident highlighted the need to verify the semantic meaning of bit flags before converting bitwise predicates into equality comparisons. ## Practical Recommendation For slow queries involving bit flags, consider functional indexes when using MySQL 8.0.13 or later. Ensure the query expression exactly matches the index definition, validate bitwise logic carefully, and use staged schema and query rollouts with monitoring and fast rollback mechanisms.

Read original(opens in new tab)
line4 min readCurated summary

Creating the Cloud of the Future

LY Corporation is consolidating Yahoo! JAPAN and LINE’s internal cloud services into Flava, a private cloud for application development. The article outlines how Flava could evolve over the next two to three years through unified developer platforms, stronger yet more usable security, scalable multimedia storage, AI infrastructure, and intelligent cloud management. Its ultimate goal is to make complex infrastructure easier to consume while automating operational work. ## Platform Flavaization - Flava currently focuses on infrastructure, databases, and containers, while other development services are spread across separate internal platforms. - Developers must learn different systems for: - Access control and approvals - Logging, monitoring, metering, and billing - APIs, CLIs, and user interfaces - Multi-region and availability-zone operations - “Flavaization” means offering all development platforms through a consistent cloud experience. - LY expects much of this integration to be completed within the next one to two years. ## Stronger, More Usable Security - Flava incorporates security governance from the architecture and product-planning stages, working with the CISO organization. - Data environments are separated by security level: - Default - Secret - Top secret - Sensitive changes require role-based permissions, organizational reporting, expert review, and formal approval. - The main challenge is usability: - Resources can now be provisioned within minutes, but access may still require around ten workflows, such as VDI and Box account creation, taking up to two months. - VPC ACL controls can add several milliseconds of latency, which may affect latency-sensitive services such as LINE messaging. - Flava must provide “usable security” that preserves strong governance without making development excessively slow or difficult. ## Storage for Growing Multimedia Data - Users continuously generate and retain large volumes of photos, videos, and other multimedia content. - Storage demand can grow even when service traffic remains stable. - Flava needs storage technologies suited to different data lifecycles, balancing: - Cost - Throughput and latency - Searchability - Compression and deduplication - Encryption - Efficient tiered storage will be essential for managing long-lived user data economically. ## AI Operations Platforms - LY is adopting AI tools and agents across its organizations, creating demand for shared AIOps infrastructure. - Potential platform capabilities include: - Approved MCP server development and management - Vector databases - AI observability tools such as Langfuse - AI model management - Because AI systems handle internal data, these platforms must comply with company security and data-processing policies. - Flava aims to rapidly evaluate emerging AI technologies and provide compliant, standardized services across the company. ## Network and Storage Infrastructure for AI - AI workloads process larger datasets while requiring very low network latency and high throughput. - Relevant technologies include: - DPUs - Smart NICs - High-speed NVMe storage - Automated storage tiering - Operating networks and storage at cloud scale introduces major challenges in latency, reliability, fault tolerance, throughput, change management, and security. - Flava’s existing network and storage engineering teams have experience supporting LINE and Yahoo! JAPAN at large scale and will adapt that expertise for AI workloads. ## The Intelligent Cloud - Future users may describe infrastructure requirements in natural language rather than manually configuring resources through consoles, APIs, CLIs, or Terraform. - For example, Flava could translate requirements for image processing, AI-based content labeling, messaging, and tiered storage into an architecture and deployable system. - An intelligent Flava could also: - Generate network diagrams and ACL matrices - Identify vulnerabilities and prioritize remediation - Recommend cost optimizations - Detect underutilized resources - Find unencrypted personal information - Manage OSS vulnerability responses - Chatbots could automate tasks such as identifying low-utilization resources while excluding standby failover servers or proposing cost reductions for them. - Operational campaigns currently requiring substantial engineer participation could increasingly be handled by AI agents. Flava’s recommended direction is to combine a unified cloud experience with practical security, lifecycle-aware storage, AI-ready infrastructure, and natural-language automation. The article argues that building this future cloud requires both deep infrastructure expertise and strong attention to developer and user experience.

Read original(opens in new tab)
line4 min readCurated summary

Scaling to Infinity: LY Corporation’s

LY Corporation’s observability team evolved its time-series database to handle rapidly growing infrastructure and Kubernetes workloads. After outgrowing MySQL and OpenTSDB, the team built an engine optimized for high-cardinality metrics, low-latency queries, and seamless API compatibility. Its architecture now combines in-memory, Cassandra, and S3-compatible storage, enabling cost-efficient scaling while supporting trillions of daily metrics. ## Why Time-Series Storage Matters - Metrics record system state as timestamped numerical values. - They support dashboards, threshold-based alerts, and predictive analysis using tools such as ARIMA and Prophet. - Even a small metric record can consume about 280 bytes when timestamps, values, and tags are included. - One CPU metric collected every 15 seconds requires roughly 562 MiB per server annually; across 1,000 servers, this grows to about 548 GiB before adding memory, disk, and network metrics. - High-cardinality cloud environments make both storage cost and query latency critical operational concerns. ## Moving Beyond MySQL and OpenTSDB - MySQL initially became inadequate as the organization moved from SOA to MSA: - Write load increased sharply. - Storage costs and capacity requirements grew. - Query latency worsened for large datasets. - Rigid schemas could not easily represent changing cloud resources. - MySQL sharding provided temporary relief but could not support high-resolution metrics collected at intervals under one minute. - OpenTSDB, introduced in 2016 on Apache HBase, improved write performance but had important limitations: - Tag growth harmed UID-table lookup performance. - Metadata was restricted to a narrow character set. - Large queries required cache warm-up procedures. - These constraints led to the development of an internal database beginning in 2018. ## Building the Internal Time-Series Database - The 2019 engine was designed around: - Flexible protocol support independent of a particular agent. - Linear scalability without downtime. - Low-latency processing of high-resolution metrics. - Strong availability during failures. - Inspired by Meta’s Gorilla research, the team used access patterns in which most queries target recent data. - Frequently accessed metrics were kept in an in-memory database, while colder data was stored in Apache Cassandra. - The new engine enabled metric volumes to grow by more than 200 billion records annually while preserving existing APIs. - Users benefited from the new backend without migration work or code changes. ## Scaling for Kubernetes Workloads - Kubernetes introduced rapidly changing pods, dynamically allocated volumes, and much higher metric churn. - Both major storage layers encountered scaling problems: - IMDB initially required adding identical hardware, limiting expansion options. - Cassandra rebalancing could take tens of hours because of its data volume. - The team improved IMDB with weighted load balancing so nodes with different capacities could be used effectively. - Storage was divided into tiers: - Recent 14-day data remained in Cassandra for high-performance access. - Older data was moved to S3-compatible storage. - This reduced Cassandra dependency, lowered costs, simplified operations, and enabled more flexible hardware and Kubernetes-based deployment. ## Writing and Reading Through S3 - The write path separates data processing from long-term storage: - A Dumper reads metric slots from IMDB. - It converts them into internally defined sub-blocks. - A Block Dumper combines sub-blocks into blocks and writes them to S3. - A Storage Gateway reads the blocks for queries and caches them on local disks. - Disk caching initially caused excessive page-cache use and rapid memory exhaustion. - Direct I/O was considered but withdrawn after the cloud storage team warned that it consumed too much shared bandwidth. - Through cross-team collaboration, the team adopted a B+ tree-based cache that made better use of the kernel page cache without overloading infrastructure. ## Future Direction: From Storage to Intelligence - The team aims to move beyond recording metrics toward prediction and AI-assisted operations. - Achieving this requires consolidating time-series data currently scattered across internal systems. - A key requirement is to perform this integration without imposing migration work or breaking changes on users. - The broader goal is an observability platform that turns unified metrics into predictive and intelligent operational capabilities. The main recommendation is to design time-series platforms around real access patterns, tier storage according to data age, and preserve compatibility while evolving the backend. At extreme scale, careful storage architecture and collaboration across infrastructure teams are as important as raw database performance.

Read original(opens in new tab)
lineOriginal article

Code Quality Improvement Techniques Part 30 (opens in new tab)

Code quality often suffers when functions share implicit dependencies, where the correct behavior of one relies on the state or validation provided by another. This "invisible" connection creates fragile code that is prone to runtime errors and logic mismatches during refactoring or feature expansion. To solve this, developers should consolidate related logic or make dependencies explicit to ensure consistency and safety. ## Problems with Implicit Function Dependencies When logic is split across separate functions—such as one for validation (`isContentValid`) and another for processing (`getMessageText`)—developers often rely on undocumented preconditions. * **Fragile Runtime Safety:** In the provided example, `getMessageText` throws a runtime error if called on invalid data, assuming the caller has already checked `isContentValid`. * **Maintenance Burden:** When new data types (e.g., a new message type) are added, developers must remember to update both functions to keep them in sync, increasing the risk of "forgotten" updates. * **Hidden Logic Flow:** Callers might not realize the two functions are linked, leading to improper usage where the transformation function is called without the necessary prior validation. ## Consolidating Logic for Single-Source Truth The most effective way to eliminate implicit dependencies is to merge filtering and transformation into a single function. This ensures that the code cannot reach a processing state without passing through the necessary logic. * **Nullable Returns:** By changing the transformation function to return a nullable type (`String?`), the function can signal that a piece of data is "invalid" or "empty" directly through its return value. * **Simplified Caller Logic:** The UI layer no longer needs to call two separate functions; it simply checks if the result of the transformation is null to determine visibility. * **Elimination of Redundant Branches:** This approach reduces the number of `when` or `if-else` blocks that need to be maintained across the codebase. ## Establishing Explicit Consistency In scenarios where separate functions for validation and transformation are required for clarity or architectural reasons, the validation logic should be defined in terms of the transformation. * **Dependent Validation:** Instead of writing a separate `when` block for `isContentValid`, the function should simply check if `getMessageText` returns a non-null value. * **Guaranteed Synchronization:** This structure makes the relationship between the two functions explicit and guarantees that if a message is deemed "valid," it will always produce a valid text output. * **Improved Documentation:** Defining functions this way serves as self-documenting code, showing future developers exactly how the two operations are linked. When functions share a "red thread" of logic, they should either be merged or structured so that one acts as the source of truth for the other. By removing the need for callers to remember implicit preconditions, you reduce the surface area for bugs and make the codebase significantly easier to extend.

lineOriginal article

Code Quality Improvement Techniques Part (opens in new tab)

Complexity in software often arises from "Gordian Variables," where tangled data dependencies make the logic flow difficult to trace and maintain. By identifying and designing an ideal intermediate data structure, developers can decouple these dependencies and simplify complex operations. This approach replaces convoluted conditional checks with a clean, structured data flow that highlights the core business logic. ## The Complexity of Tangled Dependencies Synchronizing remote data with local storage often leads to fragmented logic when the relationship between data IDs and objects is not properly managed. * Initial implementations frequently use set operations like `subtract` on ID lists to determine which items to create, update, or delete. * This approach forces the program to re-access original data sets multiple times, creating a disconnected flow between identifying a change and executing it. * Dependency entanglements often necessitate "impossible" runtime error handling (e.g., `error("This must not happen")`) because the compiler cannot guarantee data presence within maps during the update phase. * Inconsistent processing patterns emerge, where "add" and "update" logic might follow one sequence while "delete" logic follows an entirely different one. ## Designing Around Intermediate Data Structures To untangle complex flows, developers should work backward from an ideal data representation that categorizes all possible states—additions, updates, and deletions. * The first step involves creating lookup maps for both remote and local entries to provide O(1) access to data objects. * A unified collection of all unique IDs from both sources serves as the foundation for a single, comprehensive transformation pass. * A specialized utility function, such as `partitionByNullity`, can transform a sequence of data pairs (`Pair<Remote?, Local?>`) into three distinct, non-nullable lists. * This transformation results in a `Triple` containing `createdEntries`, `updatedEntries` (as pairs), and `deletedEntries`, effectively separating data preparation from business execution. ## Improved Synchronization Flow Restructuring the function around categorized lists allows the primary synchronization logic to remain concise and readable. * The synchronization function becomes a sequence of two phases: data categorization followed by execution loops. * By using the `partitionByNullity` pattern, the code eliminates the need for manual null checks or "impossible" error branches during the update process. * The final implementation highlights the most important part of the code—the `forEach` blocks for adding, updating, and deleting—by removing the noise of ID-based lookups and set mathematics. When faced with complex data dependencies, prioritize the creation of a clean intermediate data structure over-optimizing individual logical branches. Designing a data flow that naturally represents the different states of your business logic will result in more robust, self-documenting, and maintainable code.

lineOriginal article

Building an Enterprise LLM (opens in new tab)

LY Corporation’s engineering team developed an AI assistant for their private cloud platform, Flava, by prioritizing "context engineering" over traditional prompt engineering. To manage a complex environment of 260 APIs and hundreds of technical documents, they implemented a strategy of progressive disclosure to ensure the LLM receives only the most relevant information for any given query. This approach allows the assistant to move beyond simple RAG-based document summarization to perform active diagnostics and resource management based on real-time API data. ### Performance Limitations of Long Contexts * Research indicates that LLM performance can drop by 13.9% to 85% as context length increases, even if the model technically supports a large token window. * The phenomenon of "context rot" occurs when low-quality or irrelevant information is mixed into the input, causing the model to generate confident but incorrect answers. * Because LLMs are stateless, maintaining conversation history and processing dense JSON responses from multiple APIs quickly exhausts context windows and degrades reasoning quality. ### Progressive Disclosure and Tool Selection * The system avoids loading all 260+ API definitions at once; instead, it analyzes the user's intent to select only the necessary tools, such as loading only Redis-related APIs when a user asks about a cluster. * Specific product usage hints, such as the distinction between private and CDN settings for Object Storage, are injected only when those specific services are invoked. * This phased approach significantly reduces token consumption and prevents the model from being overwhelmed by irrelevant technical specifications. ### Response Guidelines and the "Mock Tool Message" Strategy * The team distinguished between "System Prompts" (global rules) and "Response Guidelines" (situational instructions), such as directing users to a console UI before suggesting CLI commands. * Injecting specific guidelines into the system prompt often caused "instruction conflict," where the LLM might hallucinate information to satisfy a guideline while ignoring core requirements like using search tools. * To resolve these conflicts, the team utilized "ToolMessages" to inject guidelines; by formatting instructions as if they were results from a tool execution, the LLM treats the information as factual context rather than a command that might override the system prompt. To build a robust enterprise LLM service, developers should focus on dynamic context management rather than static prompt optimization. Treating operational guidelines as external data via mock tool messages, rather than system instructions, provides a scalable way to reduce hallucinations and maintain high performance across hundreds of integrated services.

lineOriginal article

Code Quality Improvement Techniques Part (opens in new tab)

LY Corporation’s technical review highlights that making a class open for inheritance imposes a "tax" on its internal constraints, particularly immutability. While developers often use inheritance to create specialized versions of a class, doing so with immutable types can allow subclasses to inadvertently or intentionally break the parent class's guarantees. To ensure strict data integrity, the post concludes that classes intended to be immutable should be made final or designed around read-only interfaces rather than open for extension. ### The Risks of Open Immutable Classes * Kotlin developers often wrap `IntArray` in an `ImmutableIntList` to avoid the overhead of boxed types while ensuring the collection remains unchangeable. * If `ImmutableIntList` is marked as `open`, a developer might create a `MutableIntList` subclass that adds a `set` method to modify the internal `protected valueArray`, violating the "Immutable" contract of the parent type. * Even if the internal state is `private`, a subclass can override the `get` method to return dynamic or state-dependent values, effectively breaking the expectation that the data remains constant. * These issues demonstrate that any class with a "fundamental" name should be carefully guarded against unexpected inheritance in different modules or packages. ### Establishing Safe Inheritance Hierarchies * Mutable objects should not inherit from immutable objects, as this inherently violates the immutability constraints established by the parent. * Conversely, immutable objects should not inherit from mutable ones; this often leads to runtime errors (such as `UnsupportedOperationException`) when a user attempts to call modification methods like `add` or `set` on an immutable instance. * The most effective design pattern is to use a "read-only" (unmodifiable) interface as a common parent, similar to how Kotlin distinguishes between `List` and `MutableList`. * In this structure, mutable classes can inherit from the read-only parent without issue (adding new methods), and immutable classes can inherit from the read-only parent while adding stricter internal constraints. To maintain high code quality and prevent logic errors, developers should default to making classes final when immutability is a core requirement. If shared functionality is needed across different types of lists, utilize composition or a shared read-only interface to ensure that the "immutable" label remains a truthful guarantee.

lineOriginal article

A Business Trip to Japan After Only One (opens in new tab)

Joining the Developer Relations (DevRel) team at LINE Plus, a new employee was immediately thrust into a high-stakes business trip to Japan just one week after onboarding to support major global tech events. This immersive experience allowed the recruit to rapidly grasp the company’s engineering culture by facilitating cross-border collaboration and managing large-scale technical conferences. Ultimately, the journey highlights how a proactive onboarding strategy and a culture of creative freedom enable DevRel professionals to bridge the gap between complex engineering feats and community engagement. ### Global Collaboration at Tech Week * The trip centered on participating in **Tech-Verse**, a global conference featuring simultaneous interpretation in Korean, English, and Japanese, where the focus was on maintaining operational detail across diverse technical sessions. * Operational support was provided for **Hack Day**, an in-house hackathon that brought together engineers from various countries to collaborate on rapid prototyping and technical problem-solving. * The experience facilitated direct coordination with DevRel teams from Japan, Thailand, Taiwan, and Vietnam, establishing a unified approach to technical branding and regional community support. * Post-event responsibilities included translating live experiences into digital assets, such as "Shorts" video content and technical blog recaps, to maintain engagement after the physical event concluded. ### Modernizing Internal Technical Sharing * The **Tech Talk** series, a long-standing tradition with over 78 sessions, was used as a platform to experiment with "B-grade" humorous marketing—including quirky posters and cup holders—to drive offline participation in a remote-friendly work environment. * To address engineer feedback, the format shifted from passive lectures to **hands-on practical sessions** focusing on AI implementation. * Specific technical workshops demonstrated how to use tools like **Claude Code** and **ChatGPT** to automate workflows, such as generating weekly reports by integrating **Jira tickets with internal Wikis**. * Preparation for these sessions involved creating detailed environment setup guides and troubleshooting protocols to ensure a seamless experience for participating developers. ### Scaling AI Literacy via AI Campus Day * The **AI Campus Day** was a large-scale event designed for over 3,000 participants, aimed at lowering the barrier to entry for AI adoption across all departments. * The "Event & Operation" role involved creating interactive AI photo zones using **Gemini** to familiarize employees with new internal AI tools in a low-pressure setting. * Event production utilized AI-driven assets, including AI-generated voices and icons, to demonstrate the practical utility of these tools within standard business communication and video guides. * The success of the event relied on "participation design," ensuring that even non-technical staff could engage with AI concepts through hands-on play and peer mentoring. For organizations looking to strengthen their technical culture, this experience suggests that integrating new hires into high-impact global projects immediately can be a powerful onboarding tool. Providing DevRel teams the psychological safety to experiment with unconventional marketing and hands-on technical workshops is essential for maintaining developer engagement in a hybrid work era.

lineOriginal article

Code Quality Improvement Techniques Part 2 (opens in new tab)

Over-engineering through excessive Dependency Injection (DI) can introduce unnecessary complexity and obscure a system's logic. While DI is a powerful tool for modularity, applying it to simple utility functions or data models often creates a maintenance burden without providing tangible benefits. Developers should aim to balance flexibility with simplicity by only injecting dependencies that serve a specific architectural purpose. ### The Risks of Excessive Dependency Injection Injecting every component, including simple formatters and model factories, can lead to several technical issues that degrade code maintainability: * **Obscured Logic Flow:** When utilities are hidden behind interfaces and injected via constructors, tracing the actual execution path requires navigating through multiple callers and implementation files, making the code harder to read. * **Increased Caller Responsibility:** Requiring dependencies for every small component forces the calling class to manage a "bloated" set of objects, often leading to a chain reaction where high-level classes must resolve dozens of unrelated dependencies. * **Data Inconsistency:** Injecting multiple utilities that rely on a shared state (like a `Locale`) creates a risk where a caller might accidentally pass mismatched configurations to different components, breaking the expected association between values. ### Valid Use Cases for Dependency Injection DI should be reserved for scenarios where the benefits of abstraction outweigh the cost of complexity. Proper use cases include: * **Lifecycle and Scope Management:** Sharing objects with specific lifecycles, such as those managing global state or cross-cutting concerns. * **Dependency Inversion:** Breaking circular dependencies between modules or ensuring the code adheres to specific architectural boundaries (e.g., Clean Architecture). * **Implementation Switching:** Enabling the replacement of components for different environments, such as swapping a real network repository for a mock implementation during unit testing or debugging. * **Decoupling for Build Performance:** Separating implementations into different modules to improve incremental build speeds or to isolate proprietary third-party libraries. ### Strategies for Refactoring and Simplification To improve code quality, developers should identify "transparent" dependencies that can be internalized or simplified: * **Direct Instantiation:** For simple data models like `NewsSnippet`, replace factory functions with direct constructor calls to clarify the intent and reduce boilerplate. * **Internalize Simple Utilities:** Classes like `TimeTextFormatter` or `StringTruncator` that perform basic logic can be maintained as private properties within the class or as stateless `object` singletons rather than being injected. * **Selective Injection:** Reserve constructor parameters for complex objects (e.g., repositories that handle network or database access) and environment-dependent values (e.g., a user's `Locale`). The core principle for maintaining a clean codebase is to ensure every injected dependency has a clear, documented purpose. By avoiding the trap of "injecting everything by default," developers can create systems that are easier to trace, test, and maintain.

lineOriginal article

We held AI Campus Day to improve (opens in new tab)

LY Corporation recently hosted "AI Campus Day," a large-scale internal event designed to bridge the gap between AI theory and practical workplace application for over 3,000 employees. By transforming their office into a learning campus, the company successfully fostered a culture of "AI Transformation" through peer-led mentorship and task-specific experimentation. The event demonstrated that internal context and hands-on participation are far more effective than traditional external lectures for driving meaningful AI literacy and productivity gains. ## Hands-on Experience and Technical Support * The curriculum featured 10 specialized sessions across three tracks—Common, Creative, and Engineering—to ensure relevance for every job function. * Sessions ranged from foundational prompt engineering for non-developers to advanced technical topics like building Model Context Protocol (MCP) servers for engineers. * To ensure smooth execution, the organizers provided comprehensive "Session Guides" containing pre-configured account settings and specific prompt templates. * The event utilized a high support ratio, with 26 teaching assistants (TAs) available to troubleshoot technical hurdles in real-time and dedicated Slack channels for sharing live AI outputs. ## Peer-Led Mentorship and Internal Context * Instead of hiring external consultants, the program featured 10 internal "AI Mentors" who shared how they integrated AI into their actual daily workflows at LY Corporation. * Training focused exclusively on company-approved tools, including ChatGPT Enterprise, Gemini, and Claude Code, ensuring all demonstrations complied with internal security protocols. * Internal mentors were able to provide specific "company context" that external lecturers lack, such as integrating AI with existing proprietary systems and data. * A rigorous three-stage quality control process—initial flow review, final end-to-end dry run, and technical rehearsal—was implemented to ensure the educational quality of mentor-led sessions. ## Gamification and Cultural Engagement * The event was framed as a "festival" rather than a mandatory training, using campus-themed motifs like "enrollment" and "school attendance" to reduce psychological barriers. * A "Stamp Rally" system encouraged participation by offering tiered rewards, including welcome kits, refreshments, and subscriptions to premium AI tools. * Interactive exhibition booths allowed employees to experience AI utility firsthand, such as an AI photo zone using Gemini to generate "campus-style" portraits and an AI Agent Contest booth. * Strong executive support played a crucial role, with leadership encouraging staff to pause routine tasks for the day to focus entirely on AI experimentation and "playing" with new technologies. To effectively scale AI literacy within a large organization, it is recommended to move away from passive, one-size-fits-all lectures. Success lies in leveraging internal experts who understand the specific security and operational constraints of the business, and creating a low-pressure environment where employees can experiment with hands-on tasks relevant to their specific roles.

lineOriginal article

Safety is a Given, Cost (opens in new tab)

AI developers often rely on system prompts to enforce safety rules, but this integrated approach frequently leads to "over-refusal" and unpredictable shifts in model performance. To ensure both security and operational efficiency, it is increasingly necessary to decouple safety mechanisms into separate guardrail systems that operate independently of the primary model's logic. ## Negative Impact on Model Utility * Integrating safety instructions directly into system prompts often leads to a high False Positive Rate (FPR), where the model rejects harmless requests alongside harmful ones. * Technical analysis using Principal Component Analysis (PCA) reveals that guardrail prompts shift the model's embedding results in a consistent direction toward refusal, regardless of the input's actual intent. * Studies show that aggressive safety prompting can cause models to refuse benign technical queries—such as "how to kill a Python process"—because the model adopts an overly conservative decision boundary. ## Positional Bias and Context Neglect * Research on the "Lost in the Middle" phenomenon indicates that LLMs are most sensitive to information at the beginning and end of a prompt, while accuracy drops significantly for information placed in the center. * The "Constraint Difficulty Distribution Index" (CDDI) demonstrates that the order of instructions matters; models generally follow instructions better when difficult constraints are placed at the beginning of the prompt. * In complex system prompts where safety rules are buried in the middle, the model may fail to prioritize these guardrails, leading to inconsistent safety enforcement depending on the prompt's structure. ## The Butterfly Effect of Prompt Alterations * Small, seemingly insignificant changes to a system prompt—such as adding a single whitespace, a "Thank you" note, or changing the output format to JSON—can alter more than 10% of a model's predictions. * Modifying safety-related lines within a unified system prompt can cause "catastrophic performance collapse," where the model's internal reasoning path is diverted, affecting unrelated tasks. * Because LLMs treat every part of the prompt as a signal that moves their decision boundaries, managing safety and task logic in a single string makes the system brittle and difficult to iterate upon. To build robust and high-performing AI applications, developers should move away from bloated system prompts and instead implement external guardrails. This modular approach allows for precise security filtering without compromising the model's creative or logical capabilities.