TECH PLAY

キャディ株匏䌚瀟

キャディ株匏䌚瀟 の技術ブログ

å…š234ä»¶

Introduction Every AI session starts blank. You open a new chat, and you're back at square one: your preferred approach to error handling, the architectural constraint you settled on three weeks ago, the trade-off you already reasoned through and documented. None of it is there. So you explain it again. And again tomorrow. This is the baseline problem, and most engineers solve it eventually. But how they solve it is where things go sideways. The first failure mode is overreaching. Someone reads about vector databases, knowledge graphs, or shared memory layers and jumps straight to building that. Five hours of setup, a new dependency in the stack, and three weeks of maintenance later, they realize they just needed to paste some instructions into a config file. The problem was simple. The solution was not. That mismatch costs real time. The second failure mode runs in the opposite direction. A team builds a production agent system and stitches together memory as an afterthought: some context stuffed into a prompt, a few hardcoded facts, no real persistence strategy. It works at first. Five months later, the system needs to track state across users, or share knowledge between agents, or handle ten times the volume. Fixing it now means redesigning the memory layer from scratch, around code that was never built to accommodate it. Both failures have the same root: choosing a memory approach without a clear model of what "memory" actually means across different complexity levels. This blog is a map. It covers five levels of AI memory, from the session context that every tool ships by default up to memory-as-a-service infrastructure for multi-agent platforms. Higher level does not mean better. It means more capable in specific ways, and more complex to build and operate. The goal is to match the level to the actual continuity need, not to the most interesting solution in the space. Two groups of engineers will find this useful: Track A is engineers customizing a personal AI coding assistant: tuning Claude Code, Cursor, or similar tools to maintain context about their projects, preferences, and workflows across sessions. Track B is engineers designing memory for a production agent system: something customer-facing, multi-user, or running autonomously at scale. The five levels apply equally to both. Where the right stopping point differs between tracks, the post calls it out explicitly. What this article means by memory Memory is one of those terms that sounds obvious until you try to define it. Depending on who you ask, "AI memory" might mean conversation history, vector databases, user profiles, knowledge graphs, long-term storage, learned behaviors, agent state, or all of the above. Different tools and frameworks use the same word to describe very different things. For the purposes of this article, memory means information that survives beyond the immediate interaction and can influence future interactions. That includes things like: Past conversations and decisions User preferences and project context Facts extracted from interactions Documentation, notes, and research Entities, relationships, and historical changes In other words, memory is about preserving and retrieving information over time. There is another category worth mentioning: procedural memory. Procedural memory is memory about how to do things rather than what is true. Examples include deployment playbooks, investigation workflows, tool usage patterns, reusable execution plans, and strategies that improve through repeated use. Many modern agent systems rely heavily on this kind of memory. The reason procedural memory does not appear as its own level in this framework is that it cuts across several levels rather than fitting neatly into one of them. A deployment playbook might start life as a simple instruction file, evolve through observations gathered from previous executions, and eventually become part of a structured knowledge resource. The same procedural knowledge can exist in multiple forms depending on how mature the system becomes. This article therefore focuses primarily on information memory: conversations, facts, knowledge, decisions, entities, and relationships. Not because procedural memory is less important, but because it follows a different set of design concerns and would deserve its own discussion. With that scope established, we can look at the dimensions that distinguish one memory system from another. Memory has three dimensions Before we walk through the five levels, it helps to understand what makes them different from each other. The levels aren't a ranking. They're positions on a map, and the map has three axes. Depth The first is depth: how rich and structured is the thing being stored? At the shallow end, you have raw conversation (the literal back-and-forth that happened in a session). Move further along and you get extracted facts and summaries, where some processing has already been done to make the content useful. At the deep end sit interconnected knowledge graphs, where entities, relationships, and temporal changes are all modeled explicitly. Higher depth means more work was done to make stored information usable, and more complexity to build and maintain. It's not automatically better. A summary is faster to retrieve and cheaper to store than a graph traversal, and for many use cases that's exactly the right trade. Persistence The second dimension is persistence: how long does stored memory survive? Some systems hold context only for the duration of the current session. Close the window and it's gone. Others persist across sessions within a project, so you can pick up a conversation thread days later. The most durable approaches store memory permanently, independently of any session or tool: the information outlives whatever generated it. Scope The third is scope: who can access what's stored? At one end, memory is personal and sometimes locked to a single tool (only you, only in this editor). Some systems share memory across a team, so knowledge one person captured becomes available to everyone. At the widest scope, memory is exposed via an open protocol so any compliant AI tool can read from and write to the same store, regardless of vendor. The important thing is that these three dimensions are independent of each other. A system can have high depth but be session-only: a sophisticated knowledge graph that evaporates when the process exits. Another can be permanent but strictly personal, surviving indefinitely while staying locked to one user and one tool. Depth doesn't imply persistence, and persistence doesn't imply scope. The levels we're about to cover are anchors at specific positions on this three-dimensional map, not rungs on a ladder where the goal is to climb as high as possible. Memory level positioning Level Depth Persistence Scope L1: Session Minimal Session Personal L2: Instruction Low Permanent (manual) Personal → Team L3: Episodic Medium Project / Long-term Personal L4: Semantic High Permanent Personal → Team L5: Infrastructure High Permanent Team / Platform A note on levels versus architectures Before continuing, it's worth clarifying something that often causes confusion when people discuss AI memory. The five levels are not a strict hierarchy where each level replaces the previous one. They describe different combinations of memory representation, persistence, and deployment scope. The lower levels primarily differ in what is remembered: L1 stores recent context. L2 stores instructions and preferences. L3 stores experiences and interactions. L4 stores synthesized knowledge. L5 is slightly different. It does not describe a new form of memory so much as a new ownership model for memory. The memory becomes infrastructure that can be shared across tools, agents, and users. This means the levels are not mutually exclusive. An L5 memory platform might expose simple L3-style conversation summaries, a compiled knowledge base from L4, a knowledge graph, or all three simultaneously. Think of L3 and L4 as describing the shape of memory. Think of L5 as describing where that memory lives and who can access it. L1 and L2: The foundations L1: Session memory Every AI tool ships with some form of memory out of the box. Conversation history, project workspaces, the sliding context window keeping your recent messages available: it's all there without any configuration. This is L1. It solves exactly one problem well: continuity within a single session. Ask a follow-up, reference something you said ten minutes ago, iterate on a design: it all works. Zero setup, zero maintenance. The wall appears the moment you close the conversation. Start a new session the next day and everything is gone: no memory of the architecture decision you landed on yesterday, no awareness of the other three projects you're juggling, no accumulated sense of how you prefer to work. The slate is blank. For Track A , L1 is fine for one-off tasks and exploratory sessions where continuity genuinely doesn't matter. The mistake is staying here for work that spans days or weeks and then wondering why the AI keeps asking questions you've already answered. For Track B , L1 is always present as the foundation and is rarely sufficient on its own once continuity matters. Every agent system starts here. Most production systems eventually need more than this. Tools at this level (as of mid-2026) See the tools reference table at the end of this article for a fuller view. L2: Instruction memory The first meaningful upgrade is also the simplest: you write things down and make sure the AI reads them at the start of every session. This is L2. System prompts, rules files, project context documents, conventions lists: anything structured that loads automatically when a conversation begins. Some tools support hooks that inject these files without you thinking about it. Others require pasting them in or configuring a project workspace. The mechanism varies; the idea is the same. What L2 actually solves is the re-explanation tax. Every engineer who uses AI tools regularly has felt it: the first ten minutes of a session spent re-establishing who you are, what project you're on, how you name things, what you've already tried. L2 eliminates most of that. Write your preferences once, point the tool at them, and the next session starts with that context already in place. It scales to teams in a way that surprises people. A shared conventions file checked into a repository means everyone's AI assistant follows the same patterns (consistent naming, consistent code style, consistent architectural constraints) without anyone having to configure their tool individually. The file becomes a single source of truth that both humans and AI tools read. The appeal of L2 is that it asks almost nothing from you technically. No infrastructure, no databases, no vector embeddings, no background processes. Just files and text, working with mechanisms every AI tool already supports. For most engineers, this is where 80% of the "my AI doesn't know me" friction disappears. An important pattern appears once teams start using L2 and L3 together. Most decisions begin life as history. A discussion happens, alternatives are evaluated, a tradeoff is accepted, and a conclusion is reached. Initially that information belongs in L3 because it reflects something that happened. Over time, some of those decisions stop being history and become policy. "We chose SQS instead of Kafka" eventually becomes "Use SQS for asynchronous processing." At that point the information has effectively been promoted from L3 into L2. Healthy memory systems tend to do this continuously. Episodic memory captures what happened. Stable learnings are promoted into instructions. This keeps the memory layer compact while ensuring important decisions become durable guidance rather than forgotten conversations. The limitation is just as simple to understand: the instructions are static. They reflect what should happen, not what did happen. If the project evolves and nobody updates the file, the AI keeps following outdated rules. If a key decision was made in a session yesterday, it doesn't automatically appear in the rules tomorrow. L2 captures intent; it doesn't capture history. The moment you need the AI to remember what actually occurred across sessions, you've outgrown L2 and are looking at the next level. For Track A , this is the first upgrade almost every engineer should make. A project context file and a personal preferences file together cover the majority of continuity friction with minimal ongoing effort. For Track B , L2 is present in almost every production system, whether explicitly recognized or not. Every agent needs a system prompt defining its behavior, persona, and constraints. It's always present, even in the most sophisticated systems: other levels build on top of it, not in place of it. Tools at this level (as of mid-2026) See the tools reference table at the end of this article for a fuller view. L3: Episodic memory The problem that L2 doesn't solve is accumulation. You can write excellent instructions for how the AI should behave, but it still has no idea what you actually worked on last week. You re-explain the same project context. You re-share the same decisions. After a few months of this, the appeal of "the AI remembers what we've discussed" starts to feel less like a feature and more like a basic expectation. L3 is where that expectation gets met. The core pattern is simple: at session end, a background process captures what happened, processes and stores the content, and on the next session automatically injects whatever past context seems most relevant. No manual maintenance. The AI just gradually accumulates working knowledge of your projects, preferences, and decisions over time. The appeal is real. After a few weeks, the AI starts referencing things without being prompted: the architectural decision you made last Tuesday, the library you ruled out and why, the naming convention your team settled on. That kind of continuity changes how the tool feels to work with. The lossy versus lossless spectrum Before picking a tool at this level, there is one distinction worth understanding clearly: what gets stored, and what gets thrown away. On the lossy end, when a session ends an LLM reads the conversation and extracts key facts, decisions, and preferences into a compact summary. The raw transcript is discarded. This approach is token-efficient and scales well over months, since the stored memory stays compact regardless of how many sessions accumulate. The tradeoff is that you lose the ability to reconstruct what was actually said. You get a distilled view of the past, not the past itself. This works well for long-running projects where accumulated context matters more than exact recall. On the lossless end, the raw conversation is preserved and a searchable index is built on top. Full-text search, vector embeddings, or both. This enables exact retrieval: you can find a specific exchange from five weeks ago, reconstruct the reasoning behind a decision, or debug why an agent behaved a certain way. The cost is higher storage and more infrastructure. It suits audit trails and situations where "what was actually said" carries weight. Most mature tools today sit somewhere between these extremes. They may store verbatim content but surface LLM-generated summaries as the primary retrieval interface. When you are evaluating a tool here, it is worth checking both sides separately: what gets stored (the raw conversation, a summary, structured facts) and what gets surfaced at retrieval time (matched chunks, a synthesized answer, a flat list of facts). Those are often different things, and the gap between them is where retrieval quality problems tend to hide. How retrieval typically works At session end, the background process captures the conversation and splits it into chunks. Each chunk is converted into a vector embedding and written to a store. At the next session start, the current context (what you just typed, the project you opened) is used to query the store, and the top-matching chunks are injected into the context window automatically. Some tools add keyword search or hybrid retrieval on top for better precision when semantic similarity alone isn't enough. The quality of this whole pipeline depends heavily on chunking strategy and retrieval tuning, which is why two tools using the same underlying model can feel very different in practice. Where this level breaks L3 is primarily personal and local. Most tools at this level store memory for one user, on one machine, for one AI tool. Sharing that accumulated context across teammates, or making it accessible from a different AI tool, requires moving to L5. This is a meaningful constraint if you are thinking about team-level continuity. Language support is also worth checking before committing. Much of the tooling here was built with English-first assumptions, and retrieval quality for Japanese content varies considerably between tools. For Track A engineers, this is the main upgrade worth making. Once the setup is done it runs in the background. The value accumulates gradually and quietly, which means you probably won't notice it working until you realize you stopped explaining yourself so much. For Track B , this level maps to what agent frameworks call episodic memory: the record of what an agent has done in past interactions. The lossy-versus-lossless decision has clearer stakes here. A user-facing agent that makes specific commitments ("I'll follow up by Friday," "we agreed to disable that feature") may need accurate recall of those commitments, which pushes toward the lossless end. Getting this wrong in a production system tends to surface in support tickets rather than evaluation runs. Tools at this level (as of mid-2026) See the tools reference table at the end of this article for a fuller view. L4: Semantic memory Everything below this level is about remembering. L4 is about compiling. The levels before it capture what happened: which files were read, what preferences were stated, which decisions were logged. Useful, but passive. L4 takes raw material and builds something from it: a structured, interconnected knowledge resource that gets more valuable the longer you use it. The goal shifts from "remember this conversation" to "build something I can reason over." There are two distinct architectural models at this level. They solve different problems, require different infrastructure, and represent genuinely different design choices rather than variations on the same idea. The compilation model Think of this as an AI-maintained encyclopedia. Raw source material (research papers, documentation, articles, internal notes) arrives in an immutable input layer. An LLM reads that material and writes structured articles: encyclopedia-style entries with cross-references, organized by concept, updated as new sources arrive. The knowledge resource is the compiled output, not the raw sources themselves. The contrast with standard retrieval-augmented generation is worth being precise about. In a typical RAG setup, you embed raw documents and retrieve chunks at query time. The retrieved knowledge does not accumulate into a maintained representation. Every query starts from the underlying source documents, even if the retrieval layer itself becomes richer over time. In the compilation model, synthesis happens upfront. Articles build on each other, contradictions get flagged, and the index evolves as the domain does. The trade-off is scale. A flat index works well up to a few hundred articles, where the full index still fits in a context window and the LLM can check for gaps and overlap. Beyond that, hybrid retrieval becomes necessary, and the operational complexity grows with it. But for sustained research within a bounded domain, this model performs in a way raw retrieval simply cannot. This is the right choice for engineers doing months of sustained research in a specific technical area: a new language runtime, a framework you're adopting, a domain like security or distributed consensus where foundational concepts keep resurfacing. If you find yourself re-establishing the same background context you've already read through and summarized, L4 with a compilation model is the upgrade you're looking for. The graph model Where the compilation model produces readable articles, the graph model produces a knowledge graph: entities (people, products, decisions, concepts) and the relationships between them, with temporal indexing on every fact. The distinctive capability is temporal reasoning and multi-hop queries. Every fact in the graph carries a validity period. When something changes, the old fact is marked as superseded rather than deleted. This means you can ask "what was the customer's infrastructure configuration at the end of Q3?" and get the right answer, even if that configuration has since changed significantly. You can also traverse relationships across entity types: "which users are affected by this architectural decision?" or "what decisions did this team make during the incident period?" This requires a graph database backend, which adds real operational overhead compared to the compilation model. There is also a latency characteristic that matters for system design: entity extraction and relationship building happen in background processing, so newly ingested information is not immediately queryable. Write-then-read consistency is not a given. This is an architectural tradeoff, not a bug, but teams need to design around it explicitly. The graph model is the right foundation for agent platforms that need to track evolving entities across time: customer accounts, organizational structure, system configurations, incident timelines. Any use case where "what was true at time T" is a real query belongs here. On retrieval at this level Both models benefit from hybrid retrieval, combining semantic vector search, keyword matching (BM25), and graph traversal. Community benchmarks consistently show hybrid approaches outperforming any single method at scale, and the gap widens as the knowledge base grows. This is an implementation choice within L4 rather than a reason to prefer one model over the other. For Track A engineers: L4 is worth the investment when you are doing sustained research in a specific technical domain over weeks or months. Most people do not need it, and adding it prematurely just creates maintenance overhead. The signal that you are ready for it is noticing you keep re-reading the same foundational material because you cannot trust your notes to reflect the current state of your understanding. For Track B teams: this is the knowledge retrieval layer of any serious agent platform. The compilation versus graph decision is an early architectural choice with long-term consequences, because retrofitting temporal and relational reasoning onto a compilation-based system later is painful. Compilation is simpler to operate and the right default when relationship traversal is not a core requirement. Graph unlocks capabilities that are genuinely difficult to approximate otherwise. Tools at this level (as of mid-2026) See the tools reference table at the end of this article for a fuller view. L5: Memory infrastructure At this level, memory stops being a feature of a specific AI tool and becomes infrastructure. A dedicated memory store is exposed via an API or open protocol, and any compliant client can read from and write to it. The AI assistant no longer owns the memory; the memory layer does. This shift in ownership matters more than it might initially seem. At lower levels, memory follows the tool. If you switch tools, you start over. At L5, memory is independent of any tool. What one AI learned in one session, a different AI can access in the next. What one agent discovered about a user, another agent serving that same user already knows. The memory layer becomes the stable part of the system, and the AI tools sitting on top become interchangeable. The open standard increasingly used for this is MCP (Model Context Protocol), which defines a common interface for connecting AI clients to external services. A memory store exposed over MCP can in principle be queried by any MCP-compatible client, which gives you real portability between tools. Two variants worth distinguishing The first is shared personal memory: one person, multiple AI tools, one central store. Set up a database, expose it over MCP, and any AI client you use can contribute to and draw from the same pool of context. Your preferences, project history, past decisions: accessible regardless of which tool you open that day. If you use Claude Code for implementation, Cursor for exploratory edits, and a chat interface for design conversations, they all draw from the same memory. This is still relatively rare in personal setups, mostly because the setup cost is non-trivial and the benefits only become visible once you actually use multiple tools regularly. The second is shared platform memory: multiple users, multiple agents, one central layer with per-user isolation. This is the architecture for a production multi-user system. Memory is namespaced by user ID or organization ID. Each agent retrieves the right user's context at the start of an interaction and writes new context at the end. The memory store becomes a service with the same operational expectations as any other stateful service in your stack. Concerns that appear only at this level Several problems don't exist at lower levels and become real the moment memory moves to a network service. Latency is the first one to check. At lower levels, memory retrieval is local. At L5 it's a network call, and memory retrieval involves both a query embedding step and a vector search, which takes time. As of writing, some memory systems have retrieval latency in the tens of seconds at the 95th percentile under load. Putting that on the synchronous path of a user-facing agent produces visible delays that users notice immediately. Verify latency characteristics before committing to a system, and where possible design retrieval to run asynchronously or speculatively before it's needed. Multi-tenancy isolation is the application's responsibility, not the memory store's. The standard pattern is to namespace every memory entry by user ID or organization ID and enforce that boundary on every read and write at the application layer. This sounds simple and is worth getting exactly right. A failure here doesn't just produce wrong answers; it exposes one user's context to another, which is a trust failure that tends to get noticed. Data residency and ownership become real operational questions. Running an L5 memory layer means operating a database containing user context: where it lives, who has access to it, what happens when a user deletes their account, how long data is retained and why. These questions have answers at smaller scale too, but at platform scale they need written policies and enforcement. Self-hosted deployments give full control at the cost of operational burden. Managed cloud services trade that control for simplicity. Neither choice is wrong; it's worth making it explicitly rather than by default. Cost compounds at scale. Storage, embedding computation, and retrieval operations all carry per-operation costs that are easy to ignore during development and harder to ignore once real users arrive. Where it breaks The hardest memory bugs in AI systems tend to live here. Stale memory that contradicts current reality, with no clear way for the agent to know which source to trust. Contradictory facts written by different agents into the same store, with no reconciliation. Isolation failures that are silent until they cause a visible problem. None of these are unsolvable, but they require deliberate design rather than optimism. L5 is also real infrastructure with real overhead. For personal use, the setup cost rarely justifies the benefit unless you genuinely use multiple AI tools and want one shared context layer across all of them. Most individual continuity needs are covered by L3 at a fraction of the complexity. For Track A , this is probably not where to invest time right now. If you use only one AI tool, or your tools don't yet support MCP-based memory retrieval, the abstraction adds cost without benefit. It's worth keeping an eye on as tooling matures. For Track B , this is where a new architectural conversation begins: memory is no longer just something agents consume, but infrastructure that other systems depend on. The decisions made here (what protocol to use, what database to run, how to handle isolation, how to manage retrieval latency) shape everything built on top. The mistake to avoid is designing agents first and memory last. Memory architecture is a prerequisite, not an afterthought, and retrofitting it into a system that wasn't designed for it is significantly harder than getting it right from the start. Tools at this level (as of mid-2026) See the tools reference table at the end of this article for a fuller view. How to pick your level Routing guide The framework is best thought of as a map rather than a maturity ladder. L1-L4 describe different forms of memory. L5 describes when memory becomes shared infrastructure Personal use (Track A) Start at L2. A well-written system prompt and a project instructions file cover most of the friction engineers describe as "the AI doesn't know me" or "I have to re-explain my setup every time." Most people underestimate how far this gets them before anything more complex is needed. Add L3 or L4 when losing context across sessions becomes genuinely painful: re-explaining a decision you made last week, re-establishing which branch of a design you landed on, re-orienting the AI to where you left off on a project. That's the signal. Not "this might be useful someday" but "this is costing me real time right now." Consider L4 if you're doing sustained research in a specific domain over months and you want knowledge to accumulate and stay findable rather than scattering across session summaries. Not every engineer reaches this point, and that's fine. L5 is rarely worth the setup cost for personal use. The main case where it makes sense is if you actively use multiple AI tools and want one shared context layer across all of them. If you use one tool consistently, L3 handles continuity at much lower complexity. Agent platforms and production systems (Track B) L2 is mandatory. Every agent needs a system prompt, behavioral guardrails, and clear instructions about what it should and shouldn't do. Treating this as optional produces agents that behave inconsistently under novel inputs. L3 gives agents memory of past interactions. The lossy vs lossless choice matters more here than in personal use: too much context and you hit cost and latency ceilings; too little and the agent feels stateless in ways users notice. Getting that balance right requires profiling real usage, not guessing at design time. L4 is where agents go from retrieving chunks of text to reasoning over structured knowledge. The compilation model and the graph model serve genuinely different use cases, and the architectural consequences of that choice compound over time. It's worth thinking through carefully before committing. If L5 is likely to be part of the future architecture, it is worth recognizing that early. Retrofitting shared memory infrastructure into an established platform is usually more expensive than planning for it upfront. Quick routing "I just want it to remember my preferences": L2 "I want it to remember what we worked on last week": L3 "I want to stop re-explaining domain background": L4, compilation model "I need it to track how something changed over time": L4, graph model "Multiple agents or users need shared context": L5 Choosing the right level solves the architectural question of where memory should live and how it should be represented. In practice, however, selecting a level is only part of the challenge. As memory systems become more capable and accumulate more information, a different set of concerns begins to dominate: memory quality, lifecycle management, governance, and trust. Cross-cutting concerns The levels in this framework describe where memory lives, how long it survives, how structured it becomes, and how broadly it is shared. Some challenges, however, appear regardless of which level you choose or combine. In practice, these concerns often have a larger impact on system quality than the choice of storage technology or retrieval algorithm. They emerge as soon as a system starts remembering information, and they become more important as memory accumulates over time. Memory consolidation: how information moves between levels The framework can make the levels appear static. Real memory systems are usually not. Information tends to move between levels as its importance becomes clearer. A conversation starts as an interaction. Parts of it may later be summarized. Important facts may be extracted from those summaries. Over time, stable facts may become structured knowledge, and repeated lessons may eventually become instructions or policies. Conversation → Summary → Fact → Knowledge → Instruction This process is often called memory consolidation . Human memory behaves similarly. Individual experiences become generalized knowledge. Repeated observations become habits and rules. Most long-term knowledge does not enter memory in its final form; it evolves through successive stages of refinement. Modern agent systems increasingly follow the same pattern. An agent may initially record every interaction, but storing everything forever is rarely useful. As memory grows, systems need mechanisms that transform information into more compact, durable, and reusable forms. The goal is not simply to remember more. The goal is to remember the right things. The challenge is deciding what deserves promotion. Promote information too aggressively and important nuance disappears. Promote too little and memory grows without bound, making retrieval slower, more expensive, and less reliable. As memory systems mature, consolidation often becomes more important than storage. The question shifts from: How do we remember more? to: How do we remember what matters? Memory quality becomes the real problem Most discussions about memory focus on storage and retrieval. Which vector database should you use? How should chunks be split? What embedding model performs best? Those questions matter, but they are rarely the first thing that breaks. The moment a system begins writing memory automatically, a different problem appears: memory quality. The agent may misunderstand a conversation and extract an incorrect fact. A user may change their mind while an outdated preference remains stored. Two agents may write contradictory information about the same entity. A hallucinated conclusion may be captured and later retrieved as if it were established truth. The risk exists at every level beyond simple instructions, but the consequences become more severe as memory becomes more structured and more widely shared. At L3, an incorrect memory may simply cause a future conversation to start from the wrong assumption. At L4, that same incorrect memory may become part of a structured knowledge resource, influencing future reasoning and synthesis. At L5, the problem expands further. Incorrect or contradictory memories can propagate across multiple agents, tools, or users, turning a local mistake into a system-wide one. This is sometimes described as memory poisoning, but the underlying issue is broader: a memory system is only as trustworthy as the process that decides what enters it, and what stays in. As systems mature, questions like these become increasingly important: Who is allowed to write memory? Can memories be edited or deleted? How are contradictory memories reconciled? Should memories expire automatically? How much confidence should be attached to a stored fact? Should users be able to inspect and correct their own memory? The retrieval pipeline matters. The quality of what enters the pipeline often matters more. What the levels don't capture The framework is useful for making architectural decisions. It's less useful for a few problems that cut across levels. Self-improving agents (systems that rewrite their own behavioral instructions based on experience, blurring the boundary between L2 and L3) are a real design pattern that doesn't fit cleanly into any single level. The tooling around this is still maturing. It's worth following, but not worth building on top of today unless you have a specific reason to. Team memory governance is a policy problem, not a technology problem. Once memory is shared at L5, questions emerge that no level framework answers: who owns a memory entry, who can delete it, what happens when someone leaves the team, how long things are retained and under what legal obligations. The levels tell you what to build. They don't tell you how to govern it. The ecosystem moves faster than the framework does. Specific tools and platforms will look different in a year. The architectural decision (which level) is more durable than the implementation choice (which specific tool). When something changes in the ecosystem, revisit the tools. Revisit the framework only if the underlying problem has actually changed. Closing The most expensive mistake in building AI-assisted systems isn't picking the wrong tool. It's picking the wrong level and spending months building on top of it. If you're customizing a personal setup, starting low is genuinely the right call. The path from L2 to L3 is easy, and the friction tells you when you're ready to move up. If you're building a production agent system, the advice is different. You can implement incrementally — you don't need everything on day one — but you should think about your target level upfront. L5 shapes the entire memory architecture. Discovering mid-build that you need multi-tenancy or cross-tool access isn't an upgrade; it's a redesign. Know where you're heading before writing the first agent, even if you build toward it gradually. Tools reference Examples as of mid-2026. This space moves fast — treat this as a starting point for evaluation, not a definitive list. Many of the tools listed below span multiple layers and do not fit cleanly into a single category. Their placement in this table is intended to be indicative of their primary focus, not a definitive classification. Level Example tools Pattern they represent Watch out for L1: Session memory Claude Projects, ChatGPT, Gemini Workspace, Cursor, GitHub Copilot Platform-native session memory, no additional setup Memory resets at conversation end; nothing persists across sessions L2: Instruction memory CLAUDE.md / system prompts (any tool), Claude Code memory hooks, Cursor .cursorrules, GitHub Copilot instructions Structured instructions loaded at session start — human-written, static Instructions go stale if not maintained as the project evolves; doesn't capture what happened, only what should happen L3: Episodic memory Mem0, MemSearch, MemPalace, Hermes Agent, claude-mem Automatic session capture with retrieval injection — lossy (summaries) to lossless (verbatim + index) spectrum Language bias: many tools have English-first retrieval quality; verify before committing for non-English content L4: Semantic memory Compilation : LLM Wiki (Karpathy pattern), ktundwal/librarian Graph : Zep / Graphiti, Cognee, LangMem, Hindsight (local) Compilation model compiles raw sources into a maintained encyclopedia; graph model extracts entities and relationships with temporal indexing Compilation: scale ceiling around 200-500 docs before hybrid retrieval is needed. Graph: write-then-read latency due to background processing. LangMem: 59s p95 search latency — background use only L5: Memory infrastructure OpenBrain, AWS AgentCore Memory, Google Memory Bank, Any of the L3/L4 solution you would self-host and share or go with their cloud offer if any Memory as infrastructure exposed via MCP or REST — persists across tools and users Retrieval latency is now a network call (verify p95 before using on sync path); multi-tenancy isolation is the application's responsibility; data residency requires explicit policy decisions
こんにちは、2026幎5月に入瀟し、AI for applicationチヌムにゞョむンしたした村䞊です。 キャディ株匏䌚瀟では、プロダクトが解くべき課題を正しく捉えるには珟堎業務ぞの解像床が䞍可欠だずいう考えから、ドメむン知識をキャッチアップするための仕組みが瀟内に甚意されおいたす。その䞀぀が「調達もくもくワヌク」ずいう䜓隓型トレヌニングです。 私自身、前職では補造業ずは党く関係のない業界でML゚ンゞニアをしおいたした。そのため補造業のバックグラりンドはれロです。 今回、ドメむン知識を身に぀ける機䌚ずしお䞊長にお勧めされ、「調達もくもくワヌク」に参加したした。 この蚘事では、補造業未経隓のML゚ンゞニアである筆者がこのワヌクに参加し、調達業務のペむンを䜓隓したうえで感じたこずを曞きたす。 甚語の敎理 調達業務の抂芁 調達もくもくワヌクずは ワヌクでの䜓隓 1.芋積先の遞定 手䜜業 CADDi Quote 2.芋積䟝頌 手䜜業 CADDi Quote 3.芋積結果の査定 手䜜業 CADDi Quote 䜓隓しおどう倉わったか AIやシステムが匕き受けるべき仕事 補造業党䜓の最適化の難しさ We are hiring 甚語の敎理 この蚘事で䜿う䞻芁な補造業甚語をたずめたす。その他の甚語は本文䞭で適宜補足したす。 調達 : 自瀟補品に必芁な郚品や材料を倖郚から賌入・手配する業務党般を指したす。賌買ずほが同矩ですが、サプラむダヌの遞定や䟡栌亀枉たで含む広い意味で䜿われたす。 サプラむダヌ : 郚品を補造・玍品する倖郚の加工䌚瀟のこずです。「協力䌚瀟」「倖泚先」ずも呌ばれたす。 バむダヌ : 調達担圓者のこずです。サプラむダヌに芋積を䟝頌し、発泚先を決定する偎を指したす。 図面 : 補造する郚品の蚭蚈曞です。圢状・寞法・材質・衚面凊理などを蚘茉した技術文曞で、調達業務ではPDFや玙でやり取りされたす。 芋積 : サプラむダヌが図面をもずに提瀺する䟡栌・玍期の回答です。耇数瀟から芋積を取るこずを「盞芋積」ず呌びたす。 QCD : Quality品質・Costコスト・Delivery玍期の頭文字です。調達刀断の際に考慮すべきパラメヌタです。 CADDi Quote : キャディが提䟛する補造業AI芋積クラりドです。図面のアップロヌドから芋積䟝頌・回答比范たでをカバヌしたす。 CADDi Drawer : キャディが提䟛する補造業デヌタ掻甚クラりドです。図面からの情報の構造化や図面の圢状認識が匷みの䞀぀になっおおり、類䌌した図面の怜玢が可胜になっおいたす。 調達業務の抂芁 調達担圓者の仕事は、蚭蚈郚門から受け取った図面をもずに倖郚のサプラむダヌに郚品の補造を䟝頌し、QCDを守っお玍品しおもらうこずです。倧たかな流れは以䞋のずおりです。 図面受領・確認 : 蚭蚈郚門から郚品衚ず図面を受け取る。 カテゎリ分け : 図面を芋お、切削・板金・賌入品などに仕分けるサプラむダヌは加工皮別ごずに専門が分かれおいるため、ここでの振り分けが必芁。 芋積先遞定 : サプラむダヌリストから察応可胜なサプラむダヌを遞ぶ。過去の発泚実瞟ず突合し、新芏品かリピヌト品かを刀定しお加味する必芁がある。 芋積䟝頌の送付 : 芋積䟝頌曞を䜜成し、図面を添付しおメヌルで送付する。 芋積回答の査定 : サプラむダヌからの回答を比范し、QCD芳点で発泚先を決める。 発泚 : 発泚曞を䜜成しおサプラむダヌに送る 調達もくもくワヌクずは 調達もくもくワヌクは、CADDi Quoteのナヌザヌである調達担圓者の業務を、サンプルの図面や発泚実瞟などを䜿っお実際に手を動かしながら远䜓隓するトレヌニングです。調達業務の䞀郚に぀いおたずCADDi Quoteなし手䜜業で苊しんでから、CADDi Quoteありでやり盎したす。ビフォヌ・アフタヌを自分の手で䜓隓する蚭蚈です。ワヌクでは䞊蚘フロヌのうち、芋積先遞定・芋積䟝頌の送付・芋積回答の査定を䜓隓したした。調達業務にどのようなペむンがあり、それをCADDi Quoteがどう解決しおいるのかを肌で知るこずが目的です。実際にはCADDi Quoteなしで䞀通り䜓隓した埌にCADDi Quoteを䜓隓したのですが、読みやすさのため各フェヌズの䞭で䞡方の感想を曞きたす。 調達もくもくワヌクの様子。 硬い雰囲気に芋えたすが、実際には気軜に質問したり手䜜業の煩雑さに愚痎を蚀いながら進めおいたした。 ワヌクでの䜓隓 1.芋積先の遞定 ワヌクでは「どのような郚品をどれだけい぀たでに調達する必芁がある」ずいうような䟝頌が調達郚門にきおいる状態からスタヌトしたす。それぞれの郚品をどこのサプラむダヌから調達するかを考える必芁がありたす。どのサプラむダヌがどんな加工に察応でき、過去にどんな品質・玍期実瞟があったかずいうような情報が䜓系的にたずたっおいるこずは皀です。結果ずしお珟堎ではベテランの経隓則に䟝存しおいるこずもよくあるようです。たた、過去にいくらの金額で発泚したかずいう情報はあったずしおも、発泚には至らなかった芋積結果に぀いおたずたっおいるこずはほずんどないようでした。 研修で䜿甚したダミヌの取匕実瞟ずサプラむダヌ情報。このような情報がたずたっおいるこず自䜓ほずんどないそうです。 手䜜業 手䜜業ワヌクでは過去の発泚履歎スプレッドシヌトが甚意されおいたのでそれを頌りに遞定したした。しかし泚文実瞟があっおも過去の品質や䟡栌の劥圓性はわかりたせんでした。経隓則がないこずもあり自分は芋積をもらっおから考えれば良いかずなり、倚めのサプラむダヌに芋積を出すこずにしたした。 今回はスプレッドシヌトに過去の情報がたずたっおいたのでただマシでしたが、実際にはどこにもたずたっおいないこずも倚いずのこずで、効率的な調達先の遞定はかなり難しそうだず感じたした。適切でないサプラむダヌぞの芋積䟝頌はサプラむダヌ偎ぞの負担になりたすし、芋積に察する発泚比率も䞋がるこずで、信頌関係を損ねるこずにもなりたす。 CADDi Quote CADDi Quoteを䜿ったワヌクでは過去実瞟の比范が非垞にやりやすくなっおいたした。過去の発泚履歎や図面の情報をCADDiに貯めおもらっおいるこずが前提ずはなっおいたすが、図面IDず必芁な加工情報を枡せば過去の発泚実瞟を元にサプラむダヌの候補が埗られたす。発泚䟡栌・芋積履歎・過去のトラブルなど、芋積䟝頌先を決めるために必芁な情報がたずたっおいたした。 少しだけ過去ず異なるような郚品を発泚する堎合、図面IDだけを芋おいるず新芏品であるため発泚先の遞定を機械的にしづらいずいう問題がありたす。しかしCADDi Quoteは今回発泚する図面だけではなく、その図面に類䌌した図面に察する発泚実瞟も加味しおくれたす。この機胜は図面の圢状解析が高粟床でできるCADDiならではの匷みです。 2.芋積䟝頌 芋積先を決めた埌、各サプラむダヌにメヌルで芋積䟝頌を送りたす。図面をPDFずしおメヌルに添付しお送るこずも倚いようです。サプラむダヌごずに芋積䟝頌曞の䞭身や宛先名を倉曎する必芁がありたすし、䟝頌する図面が違うので正しい図面をメヌルに添付する必芁がありたす。䜜業自䜓は単玔で機械的に進めおいけば良いのですが、ミスを誘発する芁玠が倚いです。 手䜜業 ワヌクでは芋積先ずしお遞定した宛先実際には研修を担圓しおいただいた先茩のメヌルアドレスに芋積䟝頌を送る䜜業を行いたした。各サプラむダヌごずに芋積䟝頌曞の䜜成を行い、図面を添付しおメヌルを送るだけの䜜業です。単玔に芋える䜜業ですが実際には時間ずストレスがかなりかかりたす。他瀟宛の䟝頌曞を送ったり、図面を添付し忘れたりする人が圓然続出したした。自分は芋積先を倚く遞定しおしたっおいたのもあり、結局途䞭から䜜業が嫌になり芋積䟝頌先をこっそり枛らしおしたいたした。ワヌクでは実務ず比べるず少量の郚品やサプラむダヌでの䜓隓だったのですが、本圓に真面目にミスなくやろうず思うず1時間以䞊は平気でかかりそうでした。機械的な䜜業に感じられ個人的には䞀番の苊痛でした。 芋積曞ず倧量の図面添付の䟋。䞀぀䞀぀図番を確認しながら添付しおいくのはかなり泚意力を消費したす。 CADDi Quote CADDi Quoteを䜿ったワヌクでは劇的に楜になっおいたした。䞊流工皋である芋積先遞定の結果から数クリックするだけで芋積䟝頌曞の䜜成からメヌルの送信たで自動で行っおくれたした。1時間はかかるであろう䜜業が数秒になるのには流石に感動したした。 3.芋積結果の査定 芋積䟝頌を出した埌、それぞれのサプラむダヌから芋積結果が返っおくるのを埅ちたす。芋積結果が出揃っおきたらその結果を取りたずめおどこに発泚を出すかを決めるこずになりたす。その際にはQCD品質、コスト、玍期党䜓を加味しお発泚先を決める必芁がありたす。 芋積にかかる時間はサプラむダヌによっお圓然異なるので芋萜ずしがないように気を付ける必芁がありたす。たた、䞀぀のプロゞェクトの郚品の調達だけをしおいれば良いわけではないため、芋積結果を埅っおいる間には他の郚品の調達も䞊行しお進めなければなりたせん。埅ち時間がある分、情報の敎理や管理が必芁ずされるフェヌズです。 手䜜業 ワヌクでは時間が決たっおいるので芋積結果は甚意されおいる状態でこのフェヌズが始たりたした。芋積結果を芋おいるず各瀟フォヌマットが異なっおおり、比范可胜な状態に敎理するこず自䜓にたず時間がかかりたした。 芋積結果の䟋。カラム名が異なり機械的に統合できなかったり、条件付きでの芋積結果だったりず単玔に比范するこずが難しいです。 芋積金額には条件が぀いおいるこずもあり、特定の加工をする郚分は陀いおの金額であったり、芋積䟝頌をした郚品党おをたずめお䞀括発泚するこずを条件ずしたケヌスでの金額が蚘茉されおいるこずもあり、比范が倧倉でした。芋積結果をスプレッドシヌトにたずめた埌も、その刀断は難しいです。結局私はシンプルに加工費を芋お䞀番安い組み合わせを探しおそこに発泚するずいう刀断をしたした。実際には定性的な芁玠も倚く絡み、トラブル察応が柔軟なサプラむダヌであるかどうかや、工堎の䜍眮が近く茞送に関わる問題があるかどうかなど、耇合的に考える必芁があるずのこずでした。 CADDi Quote CADDi Quoteから送られた芋積䟝頌のメヌルには専甚のフォヌムが甚意されおおり、サプラむダヌはそこから芋積結果を返答したす。その結果はCADDi Quoteに自動で連携されたす。どこに芋積䟝頌を送ったのか、どこから結果が返っおきおどこがただなのか、芋積結果はいくらなのか。こうした情報が䞀元的に管理されおいきたす。 金額による比范は圓然できたすし、サプラむダヌごずの泚意事項などもたずめおおき衚瀺できるため、定性的な評䟡もある皋床できるようです。珟状ではサプラむダヌ偎からの条件付きの芋積結果に぀いおは察応できる幅に限床がありそうなため、CADDi Quoteだけで業務を完党に代替できるわけではありたせん。しかし、人手でやっおいた面倒な䜜業郚分をサポヌトしお楜にするずいう圢での貢献になっおいそうでした。 䜓隓しおどう倉わったか AIやシステムが匕き受けるべき仕事 今回のワヌクでは、調達業務における「機械的䜜業」ず「刀断業務」の混圚が鮮明になりたした。頻繁な情報の玐付けや転蚘、照合ずいった定型䜜業は、画面やファむルを行き来しながらミスなく行う必芁があり、想像以䞊に倧きな負荷ずなりたす。本来、システムが担うべきなのはこうした䜜業です。調達担圓者が真に時間を割くべきなのは、新芏サプラむダヌの開拓やコスト削枛、サプラむチェヌン党䜓のリスク戊略ずいった、人の刀断力や創造性が求められる本質的な仕事です。しかし、定型䜜業に忙殺されおいる限り、そこに時間は割けたせん。 ML゚ンゞニアずしおの芖点では、耇雑なアルゎリズムによる解決策に目が行きがちですが、珟堎ではデヌタの玐付け自䜓が手䜜業で行われおおり、それが最倧のボトルネックになっおいたす。ロゞックの粟床以前に、デヌタを構造化しお蓄積し、掻甚できる状態を䜜るこずが最優先でした。CADDi Quoteは、こうした泥臭い玐付け䜜業をシステム化するこずで、人が本来の業務に集䞭できる環境を提䟛しおいたす。 さらに、CADDi Quoteには蓄積されたデヌタを分析し、調達をより効率化するむンサむトを導き出す機胜も備わっおいたす。売䞊の50%以䞊を占めるこずもある調達・賌買においお、これたでベテランの勘に頌っおいた決定を、敎理されたデヌタに基づいお行えるようになりたす。デヌタの蓄積ず分析によっお、単なる䜜業効率化を超えた、より戊略的で䟡倀のある調達の実珟を目指しおいたす。 補造業党䜓の最適化の難しさ 調達金額の最適化に぀いお考えを深めおいくず、次第に「サプラむダヌ加工䌚瀟偎の倧倉さ」も気になり始めたした。サプラむダヌは、基本的に芋積䟝頌に無料で察応したす。安すぎる金額を提瀺すれば受泚できおも赀字になり、逆に高すぎれば発泚をもらえず、芋積に費やした工数がタダ働きになっおしたいたす。図面だけでは条件が曖昧な堎合、発泚偎ずのすり合わせにかかるコミュニケヌションコストも無芖できたせん。調達業務の負担はバむダヌ偎だけのものではなく、補造業党䜓の効率化を考えるには、倚数のステヌクホルダヌの目線に立぀必芁があるず痛感したした。 たた、「片偎だけの効率化が、必ずしも党䜓最適に぀ながらない可胜性」も感じおいたす。CADDi Quoteによっお調達偎の䜜業が楜になり、扱える案件数が増えれば、バむダヌがサプラむダヌに送る芋積䟝頌の総数も増えるかもしれたせん。もちろんシステムの粟床が䞊がれば的倖れな䟝頌は枛るはずですが、バむダヌ偎の凊理胜力が爆発的に向䞊するこずで、結果的にサプラむダヌ偎の察応負荷が倉わらないどころか、むしろ増えおしたうずいうパラドックスも起き埗たす。 これは確信のある䞻匵ずいうよりも、ワヌクで感じた問いです。調達プラットフォヌムを考えるずき、バむダヌ偎の効率化だけでなく、サプラむダヌ偎にも芋積察応の効率化や受泚機䌚の可芖化ずいった䟡倀をセットで提䟛しおいく芖点が必芁なのだろうず感じたした。補造業党䜓の゚コシステムを良くするのは、䞀方向の最適化では枈たない難しい問題です。 「モノづくり産業のポテンシャルを解攟する」ずいう倧きなミッションを達成するには、このようなステヌクホルダヌが倚く耇雑な問題も避けおは通れたせん。実際CADDi Quoteもこの倧きな問題を解決するための倉革が珟圚進行圢で進んでいたす。1日の䜓隓ワヌクでこうした問いが自然に浮かんできたこず自䜓が、このワヌクショップの蚭蚈のうたさだず感じたした。 We are hiring ミクロに実際の珟堎の問題に向き合いながらも、長期的にはマクロに補造業党䜓の効率改善を目指しおいける環境です。 補造業が未経隓であっおも、このようなワヌクを通じおドメむン理解を深めるこずができたす。 このような立ち䜍眮で働けるこずにワクワクを感じる方がいれば、補造業未経隓でもぜひお話をしたしょう tech.caddi.com
DataAnalysis郚の皲葉です。 キャディは2026幎6月10日(æ°Ž)〜12日(金)にパシフィコ暪浜で開催されたSSII2026第32回 画像センシングシンポゞりムにプラチナスポンサヌずしお協賛したした。たた、キャディから3名が登壇したしたので、圓日の様子をレポヌトしたす。 オヌガナむズドセッション産業界における生成AIの利掻甚 技術動向解説セッションCADにおけるAI分野の動向ず補造業ぞの実適甚 むンタラクティブセッション 終わりに オヌガナむズドセッション産業界における生成AIの利掻甚 生成AIが産業界でどのように䟡倀を生み、どのような条件で実運甚に乗るのかを議論するセッション です。 キャディからは、オヌガナむザヌずしおシニアリサヌチ゚ンゞニアの犏原 @gatheluck 、たた講挔者ずしお私、皲葉 @mi_spindel が登壇したした。䌚堎には玄450名ず、非垞に倚くの方にお越しいただきたした。 登壇資料はこちらです。 speakerdeck.com speakerdeck.com 私からは、DataAnalysis郚ずしお取り組んでいる生成AI掻甚事䟋ずしお補造業RAGを玹介したした。 本圓は、他にも様々な取り組みがあるのですが、たた機䌚を芋お玹介したいず思いたす。 たた、この䞭で盎面した課題の䞀぀が「各LLM/VLMモデルが我々のドメむン特有のタスクをどこたで実行できおいるかが䞍明」ずいうものでした。 そこで、補造業LLM/VLMベンチマヌクずしおManuDraw-Benchを独自構築し、比范評䟡したお話しをしたした。 皆様からのたくさんの質問をいただきたしお、ありがずうございたす。圓日は時間の関係で回答しきれたせんでしたので、ここで回答したいず思いたす。 Question CADでのDXFはパヌスせずに図面の芋た目で拟っおしたった方が総合的なコストが安いずいう刀断でしょうか AnswerDXFなどベクタヌ図面のたた凊理した方が、QualityやCostの芳点で良いタスクは存圚しおいるず思いたす。ただ、結局はimage encoderが必芁なタスクはありたすし、凊理プロセスの皮類が増えるこずによっお運甚負荷も増えたすので、QCDを総合的に刀断しお技術遞定をしおいたす。 Question䌚瀟の固有知識に぀いおは基本的にはRAGで察応ずなるず思うのですが、RAGでは察応しきれないのではないか、モデルの Fine Tuning が必芁ではないかずいう意芋も瀟内であり、意芋が分かれおいたす。 Fine Tuning たで実斜したずいうような事䟋はあるでしょうか AnswerFine Tuningたで実斜した事䟋があるかないかの詳现はお答えできないのですが、Fine Tuningを考える前に基本はナレッゞ管理ずGroundingで察応できないかを先に考えるべきだず思っおいたす。たた、Fine Tuningず蚀えど䞀定のデヌタ量は確保しなければならないですが、機密情報の挏掩を考えるず個瀟ごずに調敎をするこずになりがちです。確保できるデヌタ量ずその劎力に察する効果を怜蚎する必芁がありたす。 Question過去の故障事䟋などは、蚭蚈改善に䜿甚可胜なレベルで、原因情報が珟堎から䞊がっおくるモノでしょうか実は、原因をLLMが把握するずころに課題はないでしょうか。 Answerおっしゃる通りで原因ずその察応が䞊がっおくる仕組みを䜜るこずが重芁ですし、そこは課題です。その解決のためにも、キャディが提䟛しおいるような郚暪断のデヌタ基盀を構築しデヌタを玐づけるこずが必芁になりたす。 QuestionP15のVLMによる3次元点矀予枬は1点1点を文字列ずしお出力しおいるわけではないのだず思いたすが、Pythonスクリプト出力などでCADモデリングさせお、衚面に点を生やしおいるのでしょうか Answer1点1点を点矀を文字列ずしお出力させおいるのではなく、メッシュモデルずしお圢状を面の組み合わせで出力させおから点矀サンプリングをしおいたす。おっしゃるようにPythonスクリプト出力などでCADモデリングする方法もありたすが、コヌディング胜力や各LLM/VLMが扱える開発環境にも䟝存するため、このような方法を取っおいたす。 Question䜍眮やサむズなど幟䜕的な理解の性胜は、モデルの進化を埅おばある皋床䞊がっおきそうなベンチの結果になっおいるのでしょうか Answerそのあたりは今埌の傟向を芋おみないず䜕ずも蚀えないずころですので、今埌もトラッキングしおいきたす。ただ、自然画像や文字列で衚珟されおいる䜍眮やサむズの理解は進化が芋られたす。 Question3面図ずアむ゜メ図でVLMからみた理解床にどれだけ差があるのでしょうかVLMの蚓緎にメむンで䜿われおいるであろう写真デヌタには䞉面図的な芋え方は珍しそうに思いたす。写真に近そうなアむ゜メ図の方が理解しおくれたりするのでしょうか Answerずおも良いご指摘です。䞉面図をそのたた䞎えるよりは、斜めから芋たアむ゜メ図の方が圢状の理解力は高い印象です。ただ、アむ゜メ図には寞法など必芁な情報が抜けおいるので、凊理プロセスのどこかでアむ゜メ図にリフトするずかデヌタを組み合わせお利甚するずか工倫は必芁にはなるず考えおいたす。 共に登壇いただいた゚クサりィザヌズの加藀様、LayerXの束村様、玠晎らしい発衚をありがずうございたした。゚クサりィザヌズ様はやはり取り組たれおいるこずの幅が広いですし、生成AIの性胜だけでなくUI/UXやガバナンスずいった掻甚掚進の重芁なポむントを俯瞰しお抑えられおいるなず感じたした。LayerX様はAgentありきの業務フロヌに倉革しおいく匷い意思を䌝えながらも、結局は圓たり前をやりきれるかずいう話に共感したした。 登壇の様子 技術動向解説セッションCADにおけるAI分野の動向ず補造業ぞの実適甚 昚今の3D基盀モデルなどの朮流を抂芳し、CAD解析技術の実プロダクト適甚における「研究ず実践」のリアルを解説するセッション です。 キャディから、Data Platform本郚長の今井 @imaimai0 が登壇したした。こちらも500名近い方に聎講いただくこずができたした。 speakerdeck.com なぜ補造業においおCADが重芁なのか、CADの掻甚においお䜕がボトルネックになっおいるのか、最新研究の動向はどうなっおいるのかをお話ししおいたす。 詳现は資料をご確認いただけるず幞いですが、私からは特に、CADGeometric系やMechanical Engineering系の研究開発をもっず盛り䞊げたいず思っおいるこずをお䌝えしたいです。 資料の䞭でもCVPRにおいおGeometric系の論文は5%皋床ずいうお話しがありたしたが、補造業のGDPが日本の2割皋床を占める巚倧産業にも関わらず日本においおも類䌌の研究開発が少ないように思いたす。我々もResearchチヌムの芏暡を拡倧䞭ですし、共同開発や共同研究の機䌚も探しおいるずころです。䞀緒に盛り䞊げおいただける仲間を募集䞭です。 むンタラクティブセッション 6/11朚のブヌス出展では、倚くの方にキャディブヌスぞお越しいただきたした。セッションを聎講しお「話を聞いおみたい」ず立ち寄っおくださった方もいらっしゃいたした。 ポスタヌ発衚では、珟圚取り組んでいる研究開発テヌマを玹介したした。泚力しおいるテヌマずしお、以䞋の3点をご玹介したした。 蚭蚈資産党䜓を暪断しお怜玢するための、2D図面ず3D CADモデルの埋め蟌み空間の統合 3D CADデヌタ内の加工に必芁な特城の認識 補造業ドメむンに特化した独自の芖芚蚀語モデルVLM評䟡ベンチマヌク ManuDraw-Bench ManuDraw-Benchは公開されおいるのかされないのかずいった質問をたくさんいただきたしたが、暩利の関係䞊公開は難しいです。ただ、業界の研究開発を促進したいず思っおいたすので、䜕かしら察応を考えおいきたいずは思っおいたす。 お話いただいた皆様、本圓にありがずうございたした 終わりに SSII2026ぞの協賛・参加を通じお、補造業領域におけるAIの研究開発の珟状や、その䞭でのキャディのチャレンゞに぀いお知っおいただく貎重な機䌚ずなりたした。たた、来堎者の方ずの亀流から、日々取り組む課題に察しおもヒントを埗られる非垞に有意矩な堎でした。 運営の皆様、玠晎らしい䌚をありがずうございたした。 今埌もキャディは技術的な挑戊を続け、画像センシング・コンピュヌタビゞョン研究コミュニティの発展ず、モノづくり産業のポテンシャル解攟の䞡面に貢献しおいきたいず思っおいたす。 たた皆さんずお䌚いできるこずを楜しみにしおいたす
こんにちはDataAnalysis郚の今野です。 キャディは2026幎6月8日(月)〜12日(金)にGメッセ矀銬で開催されたJSAI2026人工知胜孊䌚党囜倧䌚 第40回にプラチナスポンサヌずしお協賛させおいただきたした。 この蚘事では5日間にわたる開催期間䞭の圓瀟ブヌスの出展報告や、聎講した技術セッションのレポヌトをお䌝えしたす。 䌚堎玹介 ブヌス玹介 聎講したセッションの感想 非構造デヌタからの情報抜出 画像音声メディア凊理芖芚蚀語理解ずマルチモヌダル生成 終わりに 䌚堎玹介 たずは䌚堎の様子を玹介したす 堎内では耇数のセッション・䌁業展瀺・ポスタヌ発衚が同時䞊行で実斜されおいたした。䌁業展瀺では、倚様な業界に跚る159瀟の䌁業が、生成AIに限らない幅広い機械孊習技術の産業応甚に関しお玹介をしおいたした。私も色々なブヌスを蚪れ、゚ンゞニアの皆さんず意芋亀換をさせおいただきたした。 堎内の案内図 倧芏暡蚀語モデル等の生成AIずずもにフィゞカルAIも倧きなテヌマの䞀぀ずなっおいお、実際に入口付近ではGMOむンタヌネット株匏䌚瀟のブヌスの前でヒュヌマノむドロボットが来堎者を迎えおいたした。 入口から芋た䌚堎の様子 ブヌス玹介 次にキャディのブヌスに぀いお玹介したす ブヌスでは、䞻に私たちが提䟛しおいる「補造業AIデヌタプラットフォヌムCADDi」の䞭で䜿甚されおいる機械孊習技術や珟圚取り組んでいる研究開発テヌマの玹介をしたした。たた本サヌビスのデモを通しお、実際に補造業の珟堎の課題解決にどのように貢献しおいるかを実感しおもらえるようにしたした。     泚力しおR&Dを行っおいるテヌマの䞭でも、蚭蚈資産党䜓を暪断しお怜玢するための2D図面ず3D CADモデルの埋め蟌み空間の統合・3D CADデヌタ内の加工に必芁な特城の認識・補造業ドメむンに特化した独自の芖芚蚀語モデルVLM評䟡ベンチマヌク ManuDraw-Benchの3点に぀いお玹介させおいただきたした。   ノベルティずしおは、キャディが各所で出展する床に倧人気の「デヌタ掻甚カツ」や補造業をむメヌゞしたマむクロファむバヌクロスをお配りしたした。   図面が文曞ずしおの特城ず幟䜕孊的な圢状が融合した耇雑なデヌタであるこずやその䞭に朜む掻甚しきれおいない情報の䟡倀であったり、テキストや画像ず比べるずあたり䞀般的でない題材の3D CADに察しおどのようなアプロヌチを課題に応じお遞択しおいるかに぀いお関心を持っお頂くこずができたした。 むベント期間䞭、キャディのブヌスに立ち寄っおくださった皆さん、本圓にありがずうございたした 聎講したセッションの感想 次に、聎講させおいただいたセッションの感想を簡朔にたずめたす。 非構造デヌタからの情報抜出 株匏䌚瀟リクルヌトの䞭田さんずSansan株匏䌚瀟の山内さんがオヌガナむザずしお実斜されたセッションです。 耇数ペヌゞの請求曞 ・医薬品デヌタ・技術マニュアル ・有䟡蚌刞報告曞 など、倚皮倚様な産業の実務に溢れる「非構造デヌタ」から、いかに正確か぀網矅的に情報を抜出するかずいう共通の課題に察する怜蚌結果が発衚されたした 。 問題蚭定及びそれに察しお提案された手法は様々ですが、ほずんどの発衚においおVLMが手法の䞭心に据えられおいたこずが印象的でした。匕き続き物䜓認識やOCRに特化したモデルの有効性は倉わらないものの、倧芏暡蚀語モデルの掚論胜力を生かした情報の構造化はこの領域においお避けおは通れないものになっおいるず感じたした。その䞭で、プロンプトの工倫・画像の前凊理・ステップの分割・怜玢システムの統合など胜力を最倧限に匕き出すための倚岐に枡る手法が怜蚌されおいたした。 図面ずいう非構造化デヌタからの情報抜出は我々の䞭心にある課題の䞀぀で、日頃の取り組みず密接に関連したセッションであり、これから解析察象のカバレッゞを拡匵しおいくに圓たり非垞に瀺唆に富んだ内容でした。 https://pub.confit.atlas.jp/ja/event/jsai2026/session/acHLauKQ 画像音声メディア凊理芖芚蚀語理解ずマルチモヌダル生成 本セッションでは、画像・音声・察話デヌタずいったマルチモヌダル情報を察象に、人間の認知特性や数理的アプロヌチを組み合わせお凊理のブラックボックスを解き明かし、生成・掚論の「制埡性ず効率性」をいかに向䞊させるかずいう共通の課題が議論されたした 。 特に印象的だったのは、東京倧孊の倧坂さんによるVLMにおける芖芚アクセス境界の存圚を実蚌した研究です 。この研究では、思考のプロセスを蚀語化させるChain-of-ThoughtプロンプティングをVLMで行う際、モデルが「長く考えるこず」で芖芚的な特城抜出を拡匵しおいるわけではなく、実際には蚀語空間内での蚘号的掚論を延長しおいるに過ぎないずいう機構を瀺すものでした。 過去のテックブログ でも玹介しおいるように、図面からより高床な情報の獲埗を目指しおいくに圓たり、VLMのメカニズムに起因する芖芚情報に基づく掚論の限界は我々も課題に感じおおり、この問題を新たな芖点で捉えられる研究内容であるように感じたした。 https://pub.confit.atlas.jp/ja/event/jsai2026/session/fQHM84pJ 終わりに 5日間にわたるJSAI2026ぞの協賛・参加を通じお、AIに関するアカデミックな着目点や産業応甚における最新の機械孊習技術に぀いお幅広い知芋を埗られる貎重な機䌚ずなりたした。たた、䌚堎での倚くの亀流や専門的なセッションから、VLMの可胜性など我々が日々取り組んでいる課題に察しおもヒントを埗られる非垞に有意矩な時間でした。 スピヌカヌの皆さん、参加者の皆さん、運営の皆さん、玠晎らしい䌚をありがずうございたした。 今埌もキャディは技術的な挑戊や珟堎の課題解決に向けた取り組み、そしお研究開発の内容を積極的に発信し、゚ンゞニアコミュニティの発展の䞀助ずなれるような貢献を続けおいきたいず思っおいたす。 次回、たた皆さんずお䌚いできるこずを心より楜しみにしおいたす
TL;DR Dependabotの脆匱性アラヌトをSlackに流し、DevinAIコヌディング゚ヌゞェントでトリアヌゞ・修正を行うスキヌムを構築したした CVE脆匱性アラヌトを、チヌムで効率的に察応できるようになりたした AIの掻甚で「セキュリティよくわからないから攟眮...」が「なるほど、そういう脆匱性なのか。これなら察応できそう」に倉わりたした はじめに 補造業デヌタ掻甚クラりド CADDi Drawer開発チヌムの倧道です。 突然ですが、みなさんのリポゞトリにDependabotのアラヌト、溜たっおいたせんか 「あ、たた増えおる...たあ今は忙しいし、埌で芋よう」っお思っちゃいたせん npm install をした際のCriticalやHighの件数を芋お、「嫌なものを芋たな〜」ずいう気持ちになりたせんか こうしお「埌で」が氞遠に来ないたた、気づけばアラヌトが倧量に溜たっおいる。そんな経隓、ありたせんか この蚘事では、DependabotずDevinAIコヌディング゚ヌゞェントを組み合わせお、CVE察応が「回り続ける」仕組みを䜜った話を玹介したす。セキュリティの専門知識がなくおも「ずりあえずやっおみよう」ず思えるような内容を目指しおいるので、気軜に読んでいただけたらうれしいです。 背景なぜスキヌムを䜜ろうず思ったか 「気づいた人がやる」運甚の限界 もずもず私たちのチヌムでは、CVE脆匱性アラヌトぞの察応は「気づいた人がやる」スタむルずなっおしたっおいたした。 Dependabotからのメヌル通知は飛んでくるのですが、日々の開発メヌルに埋もれおしたい、気づかないこずがほずんどです。たたたた気づいた誰かが善意で察応しおくれる。でも、その「誰か」がいない日は、圓然誰もやりたせん。「誰か」がやっおくれたこずに察する感謝も埋もれがちです。 攟眮するリスクは䞀定ある 実際、倚くの脆匱性は到達可胜性Reachabilityがなく、自分たちのコヌドから該圓の関数を呌んでいないケヌスがほずんどです。この経隓が積み重なるず、「今回も倧䞈倫か」ず思っおしたうのは、ある意味゚ンゞニアずしおの経隓則でもありたす。 ただ、最近はリスクを巡る状況も倉わっおきおいたす。 AIの進化によっお、攻撃甚のコヌドを生成するハヌドルが倧きく䞋がりたした。以前であれば高床な知識が必芁だった゚クスプロむトの䜜成も、今ではAIを䜿えば比范的容易にできおしたう時代です。その結果、れロデむ攻撃のスピヌドは加速し、公開される脆匱性の件数自䜓も増加傟向にありたす。 そしお、もしセキュリティむンシデントが起きおしたった堎合、事業ぞのむンパクトは蚈り知れたせん。顧客デヌタの挏掩、サヌビスの停止、信甚の倱墜...。「倧䞈倫だろう」の䞀蚀では枈たされない䞖界です。 だからこそ、゚ンゞニアずしおは埮劙なストレスを抱えおいるのも事実ではないでしょうか。「たぶん倧䞈倫」ず思い぀぀も、心のどこかで「もしこれがむンシデントに぀ながったら...」ずビクビクしおいる。そのストレス、攟眮しおいるアラヌトの数に比䟋しお倧きくなっおいたせんか DependabotのPR自動䜜成機胜に察する芁望 Dependabotには怜知した脆匱性に察しお、自動でPRを䜜成しおくれる䟿利な機胜がありたすね。 ですが、「もっずこうなったらよいな」ず思うものもありたした。 倉曎の劥圓性を刀断する情報が乏しい : 「このパッケヌゞをx.x.xからy.y.yに䞊げたす」ずしか曞かれおいない。砎壊的倉曎があるのか、自分たちのコヌドに圱響があるのか、PRを芋ただけでは刀断しづらい プロゞェクト固有のルヌルを守っおくれない : 私たちのチヌムでは「lockfileの盎接線集犁止」「overridesは原則䜿わない」ずいったガむドラむンがありたすが、Dependabotにそれを匷制する術がない もしかしたらRenovateなら蚭定を駆䜿すればこのあたりは回避する方法があるかもしれたせんね 結局、PRが来おも「これ、マヌゞしお倧䞈倫...」ず䞍安になり、確認コストが高くなりがちでした。 セキュリティの知芋、チヌムで底䞊げしたい もうひず぀、スキヌムを䜜りたかった理由がありたす。 脆匱性察応は、最終的には人間が刀断する必芁がありたす。「この脆匱性は本圓に自分たちのアプリに圱響があるのか」「Hotfixを圓おるべきか、通垞リリヌスでいいのか」。こうした刀断は、AIに䞞投げするわけにはいきたせん。 そもそも、「どのような脆匱性なのか」がわからないずいう問題もありたす。SQLむンゞェクション、XSS、プロトタむプ汚染...。名前は聞いたこずがあっおも、具䜓的にどういう攻撃手法で、どうガヌドすればいいのか。アプリケヌション゚ンゞニアずしお、こうした知識は本来持っおおいたほうがいいはずです。 そういった知芋は、自分たちのアプリケヌションに察しおコヌドを曞いたり、AIが曞いたコヌドをレビュヌする際にも圹に立぀はずです。 ただ珟実には、こうしたセキュリティの知識を、アプリケヌション゚ンゞニアが䜓系的に孊ぶ機䌚はそう倚くありたせん。業務の䞭で自然ず身に぀く類のものでもない。だからこそ、CVE察応のプロセス自䜓を「孊びの機䌚」にできないか、ずいう思いもありたした。 実際に組んでみたスキヌム 党䜓のフロヌは以䞋のようになっおいたす。 graph TD A[Dependabot怜知] --> B{Severityがチヌムの既定倀以䞊?} B -- No --> C[無芖] B -- Yes --> D[Slack通知] D --> E[Code Ownerがアサむン] E --> F[担圓者がトリアヌゞ] F --> G{Hotfix必芁?} G -- Yes --> H[即時察応・特殊フロヌ] G -- No --> I[通垞修正] I --> J[AIレビュヌ実斜] J --> K{Humanレビュヌ必芁?} K -- Yes --> L[Human Review] K -- No --> M[Merge & Slack報告] L --> M それぞれのステップを芋おいきたしょう。 Step 1. たずSlackに流す ― 「気づく」の自動化 最初にやったのは、Dependabotのアラヌトを Slackに流すこず でした。 GitHub Actionsで1時間ごずに新芏アラヌトをチェックし、Incoming Webhookで専甚のSlackチャンネルに通知したす。チヌムリヌダヌぞのメンション付きなので、芋逃しにくい仕組みです。 やっおいるこず自䜓はシンプルですが、 「普段芋おいるむンタヌフェヌスに情報を届ける」 ずいうのが倧事なポむントです。メヌルは埋もれたすが、Slackは良くも悪くもみんな芋おいたす。通知先を倉えるだけで、「気づかなかった」ずいう問題がほがなくなりたした。 Step 2. Devinにトリアヌゞを䟝頌 ― 「理解する」のハヌドル䜎䞋 アラヌトに気づいたら、次はトリアヌゞです。 ここで掻躍するのがDevinです。Slackのスレッドから、こう打぀だけです。 @Devin !triage_cve CVE-XXXX-XXXXX Devinは事前に蚭定したPlaybookに埓っお、以䞋のこずを調べおくれたす。 脆匱性の抂芁ず深刻床 : CVEの内容を平易な日本語でたずめおくれる 到達可胜性Reachability : 脆匱性のある関数を自分たちのコヌドが実際に呌んでいるかを調査 devDependenciesかどうか : 開発環境のみの圱響なら緊急床が䞋がる Hotfixの必芁性 : 䞊蚘を螏たえお、通垞リリヌスで良いか、Hotfixが必芁かの刀断材料を提瀺 SlackにDevinがトリアヌゞ結果を投皿した様子 これが本圓にありがたいのです。以前は「CVEの英語ドキュメントを頑匵っお読み解く」必芁がありたしたが、今はDevinが芁点をたずめおくれるので、゚ンゞニアは 「刀断する」こずに集䞭 できたす。 セキュリティに詳しくないメンバヌでも、Devinのレポヌトを読めば「なるほど、これはdevDependenciesだけだから緊急床は䜎いな」「これは実際にリク゚スト凊理で䜿っおいるラむブラリだから早めに察応しよう」ず刀断できるようになりたした。 ただし、最終的な刀断は必ず人間が行いたす。 これぱンゞニア組織のルヌルずしお、キャディ株匏䌚瀟 共同創業者兌最高技術責任者 CTOの小橋から明確なメッセヌゞが発信されおいたす。AIは優秀ですが「責任」はずっおくれたせん。 Slackのスレッドでやりずりされるので、迷ったらリヌダヌや有識者に盞談するのもやりやすいです。 Step 3. Devinに修正も䟝頌 ― 「盎す」の効率化 トリアヌゞが終わったら、修正です。ここでもDevinに頌りたす。 @Devin !Patch_cve DevinはPlaybookに定矩された修正ガむドラむンに沿っお、PRを䜜成しおくれたす。 私たちのチヌムでは、以䞋のような修正ルヌルを定めおいたす。 セマンティックバヌゞョニングの範囲内で曎新する : メゞャヌバヌゞョンを勝手に䞊げない。 overridesは原則䜿わない : 芪パッケヌゞが指定した範囲内で䞀時的に匕き䞊げるために䜿うのであればよいが、レンゞ倖のバヌゞョンぞ無理やり䞊曞きするず、テストされおいないパッケヌゞの組み合わせになるリスクがある。 Dependabotにはこうしたプロゞェクト固有のルヌルを守らせるこずが難しかったのですが、DevinならPlaybookに定矩しおおくこずで遵守させるこずができたす。これが、修正をDevinに任せおいる倧きな理由です。 PRが䜜成されるず、AIレビュヌDevin ReviewたたはCopilot Reviewが自動で実斜されたす。もちろん、Humanのレビュアヌも必ずアサむンしたす。 Step 4. 週次定䟋でカバヌ ― 仕組みの穎を塞ぐ どんな仕組みにも挏れはありたす。リヌダヌが䌑みでアサむンが遅れた、Devinの修正がうたくいかなかった、芪パッケヌゞが未察応でそもそも盎せない...。 こうした挏れを拟うために、週次の定䟋MTGで滞留しおいるアラヌトをチェックしおいたす。 盎接察応できないケヌス間接䟝存のパッケヌゞに修正パッチが出おいない堎合などは、チケットを起祚しお管理したす。フィルタヌで䞀芧化し、定䟋MTGにお状況を確認しおいたす。 そしおもうひず぀、この堎で 察応しおくれたメンバヌをちゃんずレポヌトに茉せる ようにしおいたす。脆匱性察応は地味な䜜業です。やっおも新機胜のリリヌスのように掟手に耒められるこずは少ない。だからこそ、「あなたが察応しおくれたおかげで安党になりたした」ず可芖化するこずが倧切だず考えおいたす。 振り返っお重芁だず思ったこず このスキヌムを運甚しおみお、いく぀か倧事だず感じたこずがありたす。 普段芋る堎所に通知する、それだけで倉わる 正盎、これが䞀番効果がありたした。 メヌルからSlackに通知先を倉えただけで、アラヌトぞのリアクション速床が段違いに倉わりたした。人は「目に入るもの」には反応するんですよね。「気づきの導線蚭蚈」は、ツヌルの遞定以䞊に倧事かもしれたせん。 AIがセキュリティのラヌニングコストを䞋げおくれた CVEの内容を理解し、圱響範囲を調査し、修正方針を考える。以前はこの䞀連の䜜業が重くお、「できる人」に偏りがちでした。 AIが䞀次調査を肩代わりしおくれるこずで、セキュリティに詳しくないメンバヌでも察応できるようになりたした。AIは「刀断するための情報収集コスト」を䞋げおくれる存圚です。 「セキュリティの知芋がないから自分には無理」ずいうハヌドルが、チヌム党䜓で䞋がったのは倧きな倉化でした。 でも、最埌は人間が刀断する AIが䟿利だからずいっお、すべおを任せるわけにはいきたせん。 Hotfixを圓おるかどうかの刀断 砎壊的倉曎を含むアップデヌトの圱響範囲の最終確認 本圓にマヌゞしお問題ないかの刀断 これらは人間の責任です。そしお、AIのおかげで「刀断に必芁な材料を集めるコスト」が䞋がっおいるからこそ、人間が刀断そのものに集䞭できるようになったずも蚀えたす。 やった人をちゃんず認知する 繰り返しになりたすが、脆匱性察応は報われにくい䜜業です。ナヌザヌに芋える新機胜を䜜るのずは違っお、「䜕も起きなかった」が成果になりたす。 だからこそ、週次レポヌトで察応者を可芖化する仕組みは倧事にしおいたす。「ありがずう」が自然に蚀える仕組みは、運甚を続けるための燃料です。 おわりに 「脆匱性のアラヌト、芋なかったこずにしよう...」 この蚘事を読んでくださった方の䞭にも、そんな経隓がある方がいるかもしれたせん。 でも、仕組みを䜜っおみお思ったのは、 負債はちゃんず现かく返しおいったほうが、粟神衛生䞊いい ずいうこずです。溜めれば溜めるほど重くなるし、芋ないフリをしおいる間のストレスは意倖ず倧きい。 完璧な運甚じゃなくおいいんです。「回り続ける仕組み」をたず䜜るこず。そしおAIの力を借りれば、セキュリティずいう重たいテヌマのハヌドルも、思ったよりずっず䞋がりたす。 この蚘事が、みなさんの脆匱性察応の第䞀歩になれば幞いです。
はじめに こんにちは。Reliabilityグルヌプ QA゚ンゞニアのmeguroです。 最近、開発珟堎でAI Agentがコヌドを曞く堎面が増えおきたした。Claude CodeやGitHub Copilotを䜿えば、APIサヌバヌの実装が数分で完成したす。テストコヌドも自動生成される。開発スピヌドは確かに䞊がっおいたす。 しかし、QA゚ンゞニアずしお、あるこずが気になりたした。 「AI Agentが生成したテストコヌドの品質は、どうやっお担保すればいいのか」 同じAI Agentなのに、時には網矅的なテストを曞き、時には重芁なケヌスが抜け萜ちおいる。この品質のばら぀きは、䞀䜓䜕が原因なのか。 QAずしお、AI時代のテスト品質をどう管理すべきか。その答えを探すため、実隓を行いたした。同䞀のタスク管理APIを3パタヌンの仕様曞で実装し、生成されたテストコヌドの品質を定量的に比范しおみたした。 結果は明確でした。 仕様曞の曞き方次第で、AI生成テストの品質が2〜3倍倉わる。 AI Agentは「曞かれたこずは確実にテストする」が「曞かれおいないこずはテストしない」ずいう特性がありたす。 ぀たり、 仕様の完党性が品質を決定する のです。 この蚘事では、その実隓の過皋ず、品質を担保するための具䜓的な知芋をお䌝えしたす。 実隓蚭蚈同䞀APIを3パタヌンの仕様で実装 実隓の抂芁 今回の実隓は、特定の仮説を怜蚌するのではなく、「AI Agentの特性から逆算しお、品質を担保するために必芁な芁玠を導き出す」ずいう挔繹的なアプロヌチをずりたした。 AI Agentには「指瀺されたこずは忠実に実行するが、行間は読たない」ずいう特性がありたす。この前提公理から、「人間が暗黙的に行っおいる思考」をどの段階たで具䜓化しお䞎えれば、玍埗する品質に届くのかを怜蚌するため、以䞋の3段階のPoCを蚭蚈したした。 3぀のPoC poc-1-minimal最小限仕様 ゚ンティティ定矩 ゚ンドポむント䞀芧 ゚ラヌマッピング衚 認蚌・認可ルヌル poc-2-tddTDD手法远加 poc-1の仕様 + TDD手法の指瀺 実装順序の指定 具䜓的なテストコヌド䟋 poc-3-strategyテスト戊略远加 poc-1の仕様 + テスト戊略ドキュメント 5぀の品質指暙の定矩 怜蚌すべき仕様項目の具䜓䟋 評䟡指暙5぀の品質メトリクス テストコヌドの品質を枬るため、過去のバグを分析し、実際に芋萜ずされがちな5぀の指暙を蚭蚈したした。 Schema Coverageスキヌマカバレッゞ 定矩レスポンスの党フィヌルドが怜蚌されおいるか 蚈枬方法怜蚌枈みフィヌルド数 / 党フィヌルド数 目暙100% Post-Condition Coverage事埌条件カバレッゞ 定矩曞き蟌み操䜜で「察象レコヌド・関連レコヌド・䞍倉条件」の3点が怜蚌されおいるか 蚈枬方法怜蚌枈み事埌条件数 / 党事埌条件数 目暙100% Error Mapping Consistency゚ラヌマッピング䞀貫性 定矩HTTPステヌタスコヌドが党゚ンドポむントで䞀貫しおいるか 蚈枬方法実装枈み゚ラヌパタヌン数 / 党゚ラヌパタヌン数 目暙100% Authorization Coverage認可カバレッゞ 定矩党ロヌル×党゚ンドポむントの組み合わせがテストされおいるか 蚈枬方法テスト枈み組み合わせ数 / 党組み合わせ数 目暙100% Abnormal Test Ratio異垞系テスト比率 定矩4xx/5xxテストの割合 蚈枬方法異垞系テスト数 / 党テスト数 目暙60%以䞊 実隓結果仕様の質が品質を決める さお、実際にAI Agentに実装させ、その実隓結果を芋おいきたしょう。 定量結果サマリヌ 指暙 poc-1 poc-2 poc-3 戊略 改善率 Schema Coverage 43% 61% 100% 2.3倍 Post-Condition Coverage 22% 39% 100% 4.5倍 Error Mapping Consistency 31% 90% 97% 3.1倍 Authorization Coverage 48% 80% 100% 2.1倍 Abnormal Test Ratio 53% 58% 48% 0.9倍 泚目すべき3぀の発芋 結果を分析しおいお、特に興味深かった点を3぀玹介したす。 発芋1TDD手法はError Mapping Consistencyで劇的改善31%→90% poc-2では、 CLAUDE.md に具䜓的なテストコヌド䟋を含めたした。 その結果、AI Agentはこのパタヌンを党8゚ンドポむントに自動適甚し、401テストが網矅的に生成されたした。䞀方、poc-1では「認蚌なしは401を返す」ずテキストで曞いおいたしたが、テストは1゚ンドポむントにしか曞かれたせんでした。 孊び抜象的な指瀺「党゚ンドポむントで認蚌テストを曞く」よりも、具䜓的なコヌド䟋の方がはるかに効果的です。 発芋2テスト戊略はスキヌマ・認可で100%達成 poc-3の docs/test-strategy.md には、党32通りの怜蚌パタヌンをマトリクスで指瀺したした。 結果、AI Agentはその衚を芋お「党8゚ンドポむント × 4ロヌル = 32パタヌン」のテストを自動生成しおくれたした。さらに、Schema Coverageに぀いおも、Protoの党フィヌルドを1぀ず぀怜蚌するテストコヌドを生成したした。 孊び「䜕を怜蚌すべきか」が具䜓的に列挙されおいれば、AI Agentは挏れなく実装しおくれたす。 発芋3poc-1でも53%の異垞系テストは曞かれる 意倖だったのは、最小限の仕様でも、異垞系テストは過半数曞かれおいたこずです。これは、゚ラヌマッピング衚404/400/403/500の定矩を明瀺しおいたおかげでした。 ただし、䞀貫性に欠けおいたした。䟋えば POST /projects には401テストあり PATCH /tasks には401テストなし 孊び「䜕をテストすべきか」の明瀺的な指瀺がなければ、AI Agentは恣意的にテストを遞んでしたいたす。 なぜAI Agentには異なる仕様が必芁なのか ここたでの結果を芋お、「なぜこんなに差が出るのか」ず疑問に思われた方もいるかもしれたせん。 その理由は、人間ずAI Agentの根本的な違いにありたす。 人間ずAI Agentの根本的な違い 人間の開発者 仕様80%完成 + 暗黙知 + 経隓 + コミュニケヌション → 完党な実装 AI Agent 仕様100%必須 → 実装品質 品質を担保するために意識すべき6぀の芳点 この実隓を通じお明らかになったのは、「頭の䞭で考えおいる品質の芖点」を、明瀺的に定矩するこずの重芁性です。 埓来、゚ンゞニアは「暗黙知」を持っおいたした。 人間の開発者なら、レビュヌやコミュニケヌションで補えたした。 しかし、AI Agent時代では、思考プロセスを仕様曞に明蚘する必芁がありたす。 以䞋、品質を担保するために意識すべき6぀の芳点ず、実隓で埗られた知芋を玹介したす。 品質芳点1: ゚ラヌハンドリングの䞀貫性 なぜ重芁か ゚ンドポむントごずに゚ラヌハンドリングがバラバラだず、以䞋の問題が起きたす ナヌザヌ䜓隓の䞍敎合同じ「認蚌なし」なのに、401ず500が混圚 監芖蚭蚈の困難どのステヌタスコヌドを監芖すべきか曖昧 障害察応の遅延本番で「これは404か500か」の切り分けに時間がかかる 「党゚ンドポむントで䞀貫した゚ラヌマッピング」を担保する必芁がありたす。 埓来の怜蚌方法ず課題 実装埌にテストコヌドをレビュヌ 手動テストで各゚ンドポむントの゚ラヌレスポンスを確認 → 8゚ンドポむント × 3゚ラヌパタヌン = 24ケヌスを人手で確認 → 実装埌に気づいたずきは既に手遅れ 品質を蚭蚈で担保する 実隓では、以䞋を事前に定矩したした ## ゚ラヌマッピング党゚ンドポむント共通 | ゚ラヌ皮別 | HTTPステヌタス | 内郚゚ラヌ | |-----------|----------------|-----------| | 認蚌なし | 401 | JWT怜蚌倱敗 | | リ゜ヌス䞍存圚 | 404 | sql.ErrNoRows | | DB障害 | 500 | その他すべお | ## テスト芁件 - å…š8゚ンドポむントで401テストを実装 - å…š8゚ンドポむントで404テストを実装 - å…š8゚ンドポむントで500テストを実装 実隓結果 Error Mapping Consistencyが31%→97%に改善 ゚ラヌハンドリングの䞀貫性は、品質の基本です。実装前に衚ずしお定矩するこずで、レビュヌ工数を削枛し、品質を担保できたす。 品質芳点2: 事埌条件の怜蚌 — 副䜜甚を芋逃さない なぜ重芁か 曞き蟌み操䜜POST/PATCH/DELETEでは、察象レコヌドだけでなく、関連レコヌドや䞍倉条件も倉化したす。 兞型的な芋萜ずし - POST /projects でProjectは䜜成されるが、䜜成者がMemberに远加されない - DELETE /projects でProjectは削陀されるが、関連するTaskが残っおしたう - 䞍倉条件の砎壊䟋オヌナヌが0人のプロゞェクトが存圚する 「察象レコヌド」「関連レコヌド」「䞍倉条件」の3点セットで怜蚌する必芁がありたす。 埓来の怜蚌方法ず課題 テストコヌドで「レスポンスが200 OK」だけ確認 → DBの状態は怜蚌されおいない → 本番で「デヌタが䞍敎合」のバグ報告 → レスポンスが正しくおも、DB状態が壊れおいる 品質を蚭蚈で担保する 実隓では、事埌条件を3点セットで定矩したした ## 事埌条件POST /projects 以䞋の3点をIntegration Testで怜蚌するこず 1. 察象レコヌド: Project行が1件䜜成されるstatus=active 怜蚌SQL: SELECT status FROM projects WHERE id = $1 2. 関連レコヌド: Member行が1件䜜成されるrole=owner, user_id=䜜成者ID 怜蚌SQL: SELECT COUNT(*) FROM members WHERE project_id = $1 AND role = 'owner' 期埅倀: 1 3. レスポンス: Proto党フィヌルドが含たれる 実隓結果 Post-Condition Coverageが22%→100%に改善4.5倍 曞き蟌み操䜜の品質は「レスポンスが正しい」だけでは担保できたせん。DB状態を盎接怜蚌する蚭蚈が必芁です。 品質芳点3: スキヌマの完党性 — フィヌルド欠萜を防ぐ なぜ重芁か APIレスポンスで「䞻芁なフィヌルドは返るが、䞀郚のフィヌルドが欠萜」ずいうバグは頻発したす。 兞型䟋 - Protoにstatusフィヌルドを远加したが、ハンドラで返し忘れ - フロント゚ンドでundefined゚ラヌ - 本番リリヌス埌に発芚 「Protoの党フィヌルドがレスポンスに含たれる」を担保する必芁がありたす。 埓来の怜蚌方法ず課題 テストで䞻芁フィヌルドid, nameだけ怜蚌 → 远加したフィヌルドは怜蚌されない → 「䞻芁な機胜は動く」が「远加機胜が壊れおいる」 品質を蚭蚈で担保する 実隓では、党フィヌルドを明瀺的に列挙したした ## Contract Test芁件 GET /projects/:id のレスポンスで、以䞋の党フィヌルドが非れロ倀で返るこずを怜蚌 - id (string) - name (string) - description (string) - status (enum: active/archived) - owner_id (string) - created_at (timestamp) - updated_at (timestamp) テストコヌド䟋 assert.NotEmpty(t, project.ID) assert.NotEmpty(t, project.Name) assert.NotEmpty(t, project.Status) // ... å…š7フィヌルドを怜蚌 実隓結果 Schema Coverageが43%→100%に改善2.3倍 フィヌルド欠萜は、型チェックでは怜出できたせん。党フィヌルドを明瀺的に怜蚌する蚭蚈が必芁です。 品質芳点4: 認可の網矅性 — 暩限チェック挏れを防ぐ なぜ重芁か 認可のバグは、セキュリティむンシデントに盎結したす。 兞型䟋 - オヌナヌだけが実行できるDELETE /projects/:idを、メンバヌも実行できおしたう - 本番で「他人のプロゞェクトを削陀できる」バグ報告 - → セキュリティむンシデント 「党ロヌル × 党゚ンドポむントの組み合わせ」を怜蚌する必芁がありたす。 埓来の怜蚌方法ず課題 「オヌナヌは実行できる」だけテスト → 「メンバヌは実行できない」はテストされない → 正垞系だけでは、セキュリティホヌルを防げない 品質を蚭蚈で担保する 実隓では、党組み合わせを衚で定矩したした ## Authorization Coverage: 100% å…š8゚ンドポむント × 4ロヌル = 32パタヌンを怜蚌 | ゚ンドポむント | 認蚌なし | 非メンバヌ | メンバヌ | オヌナヌ | |--------------|---------|----------|---------|---------| | GET /projects | 401 | 200 | 200 | 200 | | POST /projects | 401 | 201 | 201 | 201 | | PATCH /projects/:id | 401 | 403 | 403 | 200 | | DELETE /projects/:id | 401 | 403 | 403 | 204 | 以䞋、Task/Member゚ンドポむントも同様 実隓結果 Authorization Coverageが48%→100%に改善2.1倍 認可の品質は「正垞系が動く」だけでは担保できたせん。党組み合わせを明瀺的に怜蚌する蚭蚈が必芁です。 品質芳点5: リスクベヌスのテスト優先床 なぜ重芁か すべおのバグが同じ重芁床ではありたせん。 - 金銭的損倱に぀ながるバグ決枈、課金 - セキュリティむンシデントに぀ながるバグ認可、認蚌 - ナヌザヌ䜓隓を倧きく損なうバグデヌタ削陀、䞍敎合 「リスクの高い領域ほど、異垞系テストを厚くする」必芁がありたす。 品質を蚭蚈で担保する 実隓では、リスク評䟡を異垞系テストのパタヌン数に倉換したした ## リスク評䟡ずテスト戊略 ### 高リスク領域: DELETE /projectsデヌタ削陀 異垞系テスト5パタヌン必須 1. 他人のプロゞェクトを削陀 → 403 2. 存圚しないプロゞェクトを削陀 → 404 3. DB障害時の挙動 → 500 4. トランザクション途䞭でタむムアりト → ロヌルバック確認 5. 倖郚キヌ制玄違反 → 適切な゚ラヌメッセヌゞ 「重倧床高」ずいう抜象的な衚珟ではなく、具䜓的なテストパタヌン数で優先床を衚珟したす。 品質芳点6: 暗黙知の明瀺化 なぜ重芁か 「ベストプラクティス」「適切に実装」ずいった抜象的な芁求は、人によっお解釈が異なりたす。 兞型䟋 - 「削陀は適切に実装」→ 物理削陀を実装 - → 監査ログ芁件を満たせない - → 「適切」の定矩が曖昧だった 「なぜそうするのか」を明瀺する必芁がありたす。 品質を蚭蚈で担保する 実隓では、「〜しない理由」も蚘茉したした ## 削陀の実装方針 ゜フトデリヌトを䜿甚するこず 理由 - 監査ログ芁件誰が、い぀削陀したかの蚘録が必芁 - 誀削陀時の埩旧ナヌザヌからの「間違っお消した」問い合わせに察応 - デヌタ分析削陀されたプロゞェクトの傟向分析が必芁 物理削陀しない理由を明蚘するこずで、実装時の刀断ミスを防ぐ 暗黙知を明瀺するこずで、「なぜこの仕様なのか」が埌から読んでも分かる仕様曞になりたす。 品質を担保するために必芁なこず ここたで玹介した「6぀の品質芳点」を実務で䜓珟するために、AI Agent時代には以䞋の「5぀の力」が求められたす。 ①品質芳点を蚀語化する力 頭の䞭にある「これはテストすべき」ずいう盎感を、仕様曞に萜ずし蟌む。 ❌「適切にテストするこず」 ✅「党8゚ンドポむント × 3゚ラヌパタヌン = 24テスト必須」 ②網矅性を蚭蚈する力 「党゚ンドポむント」「党フィヌルド」ずいう曖昧な衚珟を、数倀化・具䜓化する。 ❌「党゚ンドポむントで䞀貫」 ✅「8゚ンドポむント × 4ロヌル = 32パタヌン」 ③リスクを評䟡する力 どこを厚くテストすべきかを刀断し、異垞系のパタヌン数で衚珟する。 高リスク領域DELETE操䜜→ ç•°åžžç³»5パタヌン 䜎リスク領域GET操䜜→ ç•°åžžç³»3パタヌン ④副䜜甚を芋抜く力 察象レコヌドだけでなく、関連レコヌドや䞍倉条件も怜蚌察象ずしお定矩する。 察象レコヌド + 関連レコヌド + 䞍倉条件 = 3点セット ⑀暗黙知を明瀺化する力 「なぜそうするのか」を曞くこずで、実装時の刀断ミスを防ぐ。 「゜フトデリヌトを䜿う理由監査ログ芁件、誀削陀時の埩旧」 これらは、AI Agentには刀断できたせん。 たずめ AI Agent時代でも、品質を担保するのぱンゞニアの圹割です。 ただし、その方法が倉わりたした。 埓来実装埌にテストを曞き、レビュヌでバグを芋぀ける AI時代実装前に「䜕を怜蚌すべきか」を仕様ずしお定矩する 「暗黙知」ずしお持っおいる品質芳点を、明瀺的に仕様曞に萜ずし蟌むこず。 これがAI時代の品質保蚌になっおくるのではないでしょうか。 質問やフィヌドバックがあれば、ぜひコメントで教えおください
はじめに 10幎以䞊前、単語を単なる蚘号ではなく、意味の近さを「距離」で衚珟する高次元ベクトルぞず数倀化する技術「Word2Vec」が登堎したした。これが、AIの重芁技術の1぀である「埋め蟌みEmbedding技術」が研究界で倧きな泚目を集める契機ずなりたした。 その埌、この技術は単語から文章、さらには画像ぞず適甚の幅を広げ、AIは次第にそれらの「意味」を理解し始めたす。類䌌する文章や画像を怜玢する粟床は飛躍的に向䞊したしたが、圓時はただ、文章ず画像を同じ尺床共通のベクトル空間で扱うこずは困難でした。 その壁を打砎したのが、2021幎にOpenAIが発衚した「CLIP」です。CLIPは文章ず画像で共通の埋め蟌みを䜜成するこずに成功し、いわば䞡者の意味を繋ぐ「共通蚀語」を誕生させたした。このマルチモヌダル埋め蟌みの成功を皮切りに、珟圚は音声や3Dデヌタなど、あらゆる情報を共通の埋め蟌み空間で扱う研究が加速しおいたす。 珟圚、補造業においおもこれらの技術は浞透し぀぀ありたす。画像埋め蟌みを甚いた「図面類䌌怜玢」や、テキスト埋め蟌みを応甚した「RAG怜玢拡匵生成」などがその代衚䟋です。しかし、珟状では単䞀モヌダルの掻甚が䞻流であり、マルチモヌダル埋め蟌みの真の瀟䌚実装はただ始たったばかりず蚀えるでしょう。 マルチモヌダル埋め蟌みの研究分野での盛り䞊がりを鑑みれば、今埌この領域が補造珟堎に瀟䌚実装されおいくのは間違いありたせん。本蚘事では、マルチモヌダル埋め蟌みの抂芁から最新の研究事䟋、そしお補造業における掻甚の未来に぀いお詳しく解説したす。 「埋め蟌み」ずは この節では、そもそも「埋め蟌み」「マルチモヌダル埋め蟌み」ずは䜕かを説明したす。 「埋め蟌み」ずは、䞀蚀で蚀えば「珟実䞖界のあらゆる情報を、AIが蚈算しやすい『倚次元空間䞊の座暙ベクトル』に倉換する技術」のこずです。人間が蚀葉の意味を理解するように、コンピュヌタに「抂念の近さ」を数倀ずしお教え蟌むプロセスだず考えるず分かりやすいでしょう。 埋め蟌みを䜿うこずで、次の3぀のこずを実珟したす。 1. 「蚘号」を「座暙」に倉える コンピュヌタは本来、数字しか扱えたせん。か぀お、AIに「リンゎ」ずいう蚀葉を教える際は、単に「101番」ずいう背番号IDを割り振るだけでした。しかし、これでは「リンゎ」ず「ナシ」が䌌おいるずいう意味の぀ながりを蚈算できたせん。 埋め蟌み技術は、゚ンコヌダヌを䜿い、䟋えば「リンゎ」を [0.12, -0.54, 0.88, ...] ずいう数癟次元の数倀の䞊びベクトルに倉換したす。この数倀は、その察象が持぀「甘み」「赀い」「果物」ずいった無数の特城を凝瞮した地図䞊の座暙のようなものです。 2. 「近さ」で意味を枬る デヌタが座暙ベクトルになるず、デヌタ同士の「距離」を蚈算できるようになりたす。 意味が䌌おいるもの 空間䞊で近くに配眮される䟋「犬」ず「猫」 意味が異なるもの 空間䞊で遠くに配眮される䟋「犬」ず「数孊」 3. 倚様なデヌタを䞀箇所に集めるマルチモヌダル 最新の埋め蟌み技術の凄さは、テキストだけでなく、画像、音声、センサヌデヌタたでも同じ空間に䞊べられる点にありたす。 䟋えば図1のように、「犬が走っおいる」ずいうテキスト、ゎヌルデンレトリバヌの画像、「ワンワン」ずいう鳎き声、そしお走る犬の動画。これらは入り口こそバラバラですが、それぞれの専甚゚ンコヌダヌによっお「ベクトル数倀の䞊び」ぞず倉換されたす。 倉換されたデヌタは、倚次元の「埋め蟌み空間」の䞭に配眮されたす。この空間の最倧の特城は、「意味が䌌おいるものほど、近くに配眮される」ずいう性質です。この䟋では、デヌタ圢匏が違っおいおもすべお「犬」ずいう同䞀のコンセプトに関連しおいるため、AIの頭の䞭空間では同じ゚リアにギュッず集たりたす。 これにより、AIはデヌタ圢匏の壁を越えお、「これは『犬』ずいう本質的な抂念だ」ず䞀貫しお捉えるこずが可胜になるのです。 図1 マルチモヌダル組み蟌み 犬の䟋 埋め蟌みの歎史 埋め蟌み技術は、わずか10幎䜙りの間に驚くべき進化を遂げおきたした。ここでは、その進化の道筋を象城する3぀のマむルストヌンを玹介したす。「単語だけ」から始たった技術が、「画像ず蚀葉の融合」を経お、「3Dシヌンの䞞ごずアラむメント」ぞず到達する物語です。 Word2Vec ── 蚀葉に「座暙」を䞎えた原点 Mikolov et al., 2013 2013幎、Googleの研究チヌムが発衚したWord2Vecは、「蚀葉の意味を蚈算できるようにした」ずいう点で、自然蚀語凊理の歎史を塗り替えたした。 それたでの限界One-hotベクトル Word2Vec以前、コンピュヌタに単語を教える方法は非垞に玠朎でした。「One-hotベクトル」ず呌ばれる方匏では、語圙数ず同じ長さのベクトルを甚意し、該圓する単語の䜍眮だけを「1」、残りをすべお「0」にしたす。 䟋えば語圙が5䞇語あれば、「リンゎ」は5䞇次元のベクトルの䞭で、たった1箇所だけ「1」が立っおいる状態です。この方匏には2぀の臎呜的な欠陥がありたした。 次元の呪い 語圙が増えるほどベクトルが膚倧か぀疎スカスカになり、蚈算効率が極めお悪い。 意味の䞍圚 「リンゎ」ず「ナシ」のベクトルは完党に盎亀しおおり、距離を枬っおも「近い」ずも「遠い」ずも蚀えない。぀たり、意味の類䌌床が䞀切蚈算できない。 Word2Vecの発想の転換 Word2Vecは、この問題をシンプルか぀匷力なアむデアで解決したした。「ある単語の意味は、その呚囲に出珟する単語によっお決たる」ずいう蚀語孊の仮説分垃仮説に基づき、倧量のテキストから単語の「䜿われ方のパタヌン」を孊習したのです。 具䜓的には、ニュヌラルネットワヌクに以䞋の2぀のタスクのいずれかを解かせたす。 CBOW 「昚日 ___ を食べた」→ 空欄に入る単語を、呚囲の文脈から予枬する。 Skip-gram 「リンゎ」ずいう単語から、その呚囲に出珟しやすい単語「食べた」「赀い」「果物」などを予枬する。 このタスクを䜕億もの文章で繰り返すこずで、各単語は数癟次元の密なベクトル分散衚珟ぞず圧瞮されたす。「リンゎ」ず「ナシ」は䌌た文脈で䜿われるため、自然ず空間䞊で近くに配眮されるのです。 なぜ衝撃的だったのか Word2Vecが䞖界を驚かせたのは、孊習されたベクトルが「意味の足し算・匕き算」を可胜にしたこずです。 「王様」−「男」+「女」「女王」 この蚈算が成立するずいうこずは、ベクトル空間の䞭に「性別」「階局」ずいった意味の軞が自然に圢成されおいるこずを意味したす。人間が明瀺的に教えたわけではなく、AIが倧量のテキストから自ら意味構造を発芋した ── この事実は、埌の埋め蟌み技術すべおの出発点ずなりたした。 CLIP ── 画像ず蚀葉の壁を壊した転換点 Radford et al., 2021 Word2Vecが「単語同士の距離」を枬れるようにしたのに察し、2021幎にOpenAIが発衚したCLIPContrastive Language-Image Pre-trainingは、さらに倧胆な問いに挑みたした。「画像ず蚀葉の距離を枬るこずはできないか」── CLIPの答えは、驚くほどシンプルでした。 4億枚の「画像キャプション」で孊ぶ CLIPは、画像甚ずテキスト甚の2぀の独立した゚ンコヌダヌを備えおいたす。孊習に䜿ったのは、むンタヌネットから収集した4億セットの「画像ずキャプションのペア」。この膚倧なデヌタを䜿い、以䞋のルヌルでベクトル空間を鍛え䞊げたす。 正しいペアは近づける 犬の画像ず「走る犬」ずいうキャプション → ベクトルを空間䞊で近くに配眮。 無関係なペアは遠ざける 犬の画像ず「青い車」ずいうキャプション → ベクトルを空間䞊で匕き離す。 これが「察照孊習Contrastive Learning」です。正解ず䞍正解を察比させながら空間を敎えおいくこずで、画像ずテキストが同じ座暙系で「意味的に比范可胜」になりたす。 「芋たこずがないもの」を理解できる CLIPの最も画期的な特城は、「Zero-shot性胜」ず呌ばれる胜力です。埓来の画像認識モデルは、「犬」「猫」「車」などのラベルを事前に教え蟌む必芁がありたした。孊習しおいないカテゎリは認識できたせん。 CLIPは違いたす。ラベルではなく「蚀語の抂念そのもの」を孊習しおいるため、䞀床も芋たこずがない物䜓でも、テキストで説明すれば識別できたす。䟋えば「䞉角圢の赀い暙識」ず入力すれば、孊習デヌタに含たれおいなくおも該圓する画像を芋぀け出せるのです。 この「デヌタ圢匏を超えた意味の理解」こそ、マルチモヌダル埋め蟌みの幕開けでした。 CrossOver ── 3Dシヌンを䞞ごず察応づける最前線 Sarkar et al., 2025 (CVPR 2025 Highlight) CLIPが画像ずテキストの2぀のモダリティを結び぀けたのに察し、2025幎にコンピュヌタビゞョンの最高峰孊䌚CVPR 2025でハむラむト論文に遞ばれたCrossOverは、さらに倚くのモダリティぞず察象を広げたした。RGB画像、点矀Point Cloud、CADメッシュモデル、フロアプラン、テキスト── これら5皮類ものデヌタを1぀の共通空間にたずめ䞊げ、3Dシヌン党䜓をモダリティ暪断で察応づけるアラむメントするフレヌムワヌクです。 埓来手法の限界「完璧なデヌタ」がないず動かない これたでの3Dマルチモヌダル孊習には、倧きな制玄がありたした。「怅子」「テヌブル」ずいったオブゞェクト単䜍で厳密にラベルを付けたアノテヌションが必芁で、しかも党おのモダリティ画像・点矀・CADなどが揃っおいなければ孊習できなかったのです。 しかし珟実のAR/VRやロボティクス、建蚭モニタリングずいった珟堎では、そんな理想的なデヌタが揃うこずはほずんどありたせん。ある郚屋は3Dスキャンデヌタしかない、別の郚屋はCAD図面ず写真だけ ── こうした「歯抜け」のデヌタが圓たり前です。 CrossOverの3぀の工倫 CrossOverは、3぀の工倫でこの「珟実の壁」を突砎したした。 1぀目は、 「シヌンたるごず」で察応づける こず。埓来はオブゞェクト1぀1぀に䞁寧なラベルを貌る必芁がありたしたが、CrossOverは「郚屋党䜓」「フロア党䜓」ずいったシヌン単䜍で異なるモダリティを結び぀けたす。いわば、家具を1個ず぀蟞曞登録するのではなく、郚屋党䜓の写真を1枚芋せお「ここにあるもの党郚たずめお芚えお」ず教えるようなむメヌゞです。 2぀目は、 デヌタが歯抜けでも孊習できる こず。5皮類党おのデヌタが揃っおいる必芁はありたせん。「この郚屋は点矀ずテキストしかない」「あの郚屋はRGB画像ずCADだけ」── そんな䞍完党なデヌタでも、手持ちのモダリティだけで埋め蟌みを蚈算し、孊習に組み蟌めたす。 3぀目は、 段階的に賢くなる孊習戊略 です。各モダリティに専甚の゚ンコヌダを甚意し、最初は少ないデヌタの組み合わせから始めお、埐々に耇雑な組み合わせぞず孊習を積み䞊げおいきたす。完璧なデヌタを埅たずに、今あるデヌタから着実に知識を蓄積できるのです。 䜕ができるようになるのか CrossOverにより、デヌタの圢匏を飛び越えた3D怜玢・解析が珟実のものになりたす。 䟋えば、フロアプラン間取り図を怜玢ク゚リずしお入力すれば、察応する3D点矀デヌタが怜玢結果ずしお返っおくる。逆に、点矀デヌタから察応するフロアプランやCADモデルを芋぀け出すこずも可胜です。さらに、明瀺的に孊習しおいないモダリティの組み合わせ䟋フロアプラン ↔ テキストでも怜玢が機胜する「創発的な汎化胜力」が確認されおいたす。 これはたさに、補造業や建築業が埅ち望んでいた技術です。次の章では、この技術が補造珟堎でどのように掻甚されおいくのかを具䜓的に芋おいきたす。 補造業における掻甚の未来 ここたで玹介しおきたマルチモヌダル埋め蟌み技術は、あくたで「芁玠技術」です。では、この技術が補造業の珟堎に入るず䜕が倉わるのか ── ここからは、最も実甚化が近い「怜玢」の応甚領域を芋おいきたす。 怜玢 ── 「探し方」が根本から倉わる 補造業には、長幎にわたっお蓄積された膚倧な図面・3Dデヌタ・仕様曞が眠っおいたす。しかし、その倚くはファむル名や管理番号ずいった「メタデヌタ」でしか怜玢できたせん。番号を忘れたら最埌、必芁なデヌタにたどり着けない ── そんな経隓のある方も倚いのではないでしょうか。 マルチモヌダル埋め蟌み技術は、この「探し方」を根本から倉えたす。デヌタの本質的な「意味特城」がベクトル化されるこずで、メタデヌタに頌らない、3぀の新しい怜玢が可胜になりたす。 クロスモヌダル怜玢圢状で図面を探す 「デヌタ圢匏の壁」を越える怜玢です。 蚭蚈担圓者が、過去の類䌌補品の仕䞊がりを確認したい堎面を想像しおください。埓来は管理番号を手がかりに過去資料を探し回る必芁がありたしたが、マルチモヌダル埋め蟌みを䜿えば、開発䞭の3D CADデヌタをそのたた怜玢ク゚リずしお入力するだけで枈みたす。AIが埋め蟌み空間䞊で「圢状的・構造的に近い」過去の補品図面画像を瞬時に芋぀け出しおくれるのです。 管理番号が䞍明な叀い郚品でも、圢状さえあれば「過去の類䌌品」を玐付けられる。これだけでも、蚭蚈の初期段階で過去の知芋を掻かしやすくなりたす。 マルチモヌダル怜玢「画像テキスト」で絞り蟌む 1぀のモダリティでは足りない堎面に効く怜玢です。 䟋えば、「このフランゞ画像ず同じ圢状で、か぀材質がステンレステキストのもの」を探したいずしたす。画像だけでは材質たで刀別できたせんし、テキストだけでは圢状の埮劙な違いを衚珟しきれたせん。 マルチモヌダル怜玢では、画像の「芖芚的な特城ベクトル」ずテキストの「仕様的な特城ベクトル」を掛け合わせるこずでベクトル加算など、䞡方の条件を満たすデヌタをピンポむントで特定できたす。材質、硬床、耐熱性── 画像では芋えない情報を蚀葉で補足するこずで、怜玢粟床が栌段に䞊がるのです。 AIチャット怜玢珟堎の蚀葉でデヌタを匕き出す 察話型むンタヌフェヌスを介した怜玢です。 珟堎の䜜業員がタブレットに向かっお「先週のラむン停止時に、ベアリング付近を撮圱した写真を芋せお」ず話しかける。あるいは「この3Dモデルの、取付穎が5぀あるバリ゚ヌションをリストアップしお」ず指瀺を出す。── ナヌザヌの発話がテキストベクトルに倉換され、デヌタベヌス内の画像・3Dデヌタのベクトルず盎接照合されるこずで、こうした自然な察話での怜玢が実珟したす。 耇雑な怜玢コマンドを芚える必芁はありたせん。専門知識がなくおも「珟堎の蚀葉」で必芁な技術資産にアクセスできるようになる点が、珟堎ぞの浞透を考えるず最倧の匷みです。 おわりに 本蚘事では、埋め蟌み技術の進化を「単語だけ」のWord2Vecから、「画像ず蚀葉」を結んだCLIP、そしお「3Dシヌンを䞞ごず察応づける」CrossOverぞずたどりたした。この10幎䜙りで、AIが「意味」を捉える範囲は劇的に広がっおいたす。 補造業にずっお、この技術が意味するのは「デヌタの探し方の根本的な倉化」です。ファむル名や管理番号に頌っおいた怜玢は、圢状やテキストの「意味」で盎接぀ながるようになりたす。ベテラン蚭蚈者の頭の䞭にしかなかった「あの時䌌たようなものを䜜った」ずいう経隓知は、埋め蟌み空間を通じお組織党䜓で共有できるデゞタル資産ぞず倉わりたす。 珟時点では、補造業でのマルチモヌダル埋め蟌みの瀟䌚実装はただ始たったばかりです。しかし、研究の進展を芋れば、この技術が珟堎に届くのは時間の問題でしょう。「圢」ず「蚀葉」の境界が消えたずき、補造業のデヌタ掻甚は新しいステヌゞに入りたす。 仲間を募集しおいたす キャディ株匏䌚瀟では、本蚘事で玹介したマルチモヌダル埋め蟌み技術をはじめ、AIモデル開発に党力で取り組み、ミッション「モノづくり産業のポテンシャルを解攟する」の実珟を目指しおいたす。 この蚘事を読んで「自分ならこう解決する」「この技術、面癜そう」ず感じた゚ンゞニアの方、ぜひご応募お埅ちしおおりたす 詳现は以䞋の採甚ペヌゞからご芧いただけたす Data & Machine Learning / CADDi Tech Careers
こんにちは。キャディ株匏䌚瀟でリサヌチ組織の立ち䞊げを担っおいる犏原です。 珟圚、私たちのResearchチヌムでは「 Staff Research Engineer, 2D/3D Vision & Multimodal Understanding 」のポゞションを新たにオヌプンしおいたす。 これたでのテックブログ では、VLMの空間掚論における限界や、3D CADモデルの幟䜕情報凊理の難しさずいった「私たちが盎面しおいる技術課題What」に぀いお発信しおきたした。 今回は芖点を倉えお、 この挑戊的な技術領域で、どのようにしお玠早く䟡倀を生み出し続ける研究開発が可胜なのか 、そしお なぜキャディでそれが実珟できるのか に぀いおお話ししたす。 補造業コンピュヌタビゞョンの特異性 なぜキャディなのか研究開発スピヌドの構造蚭蚈 技術ロヌドマップにおける3぀の重点領域 3D圢状の幟䜕孊的・意味的理解の深化 2D図面ず3D CADモデルの高床な察応付け マルチモヌダル暪断怜玢 求める人物像 補造業コンピュヌタビゞョンの特異性 珟圚のコンピュヌタビゞョン研究の䞻流は、RGB画像から3Dタスクを解くずいうアプロヌチです。自動運転、ロボティクス、AR/VRなど、倚くの先端応甚では、豊富なテクスチャ情報、照明の倉化、背景のコンテキストずいった芖芚的手がかりを掻甚したす。最新のVision-Language ModelVLMも、このような「芋た目の情報」を高床に理解するこずで、驚異的な性胜を発揮しおいたす。 しかし、補造業の珟堎では状況がたったく異なりたす。図面にも3D CADにも、色もテクスチャも背景も存圚したせん。そこにあるのは、ピュアな幟䜕孊的情報のみです。 この違いは些现なものではありたせん。以前のテックブログでもお話ししたしたが、蚀語凊理タスクでは人間レベルに達するMLLMも、空間掚論タスクでは60%の粟床にすら届きたせん。建築図面のベンチマヌクでは、テキスト䞭心の質問応答では高粟床を瀺す䞀方、空間認識では40〜55%皋床ずいう劇的な性胜差が報告されおいたす。既存の最先端モデルは、テクスチャなき幟䜕孊の䞖界では「3歳児レベルの空間掚論胜力」に退化しおしたうのです。 さらに、補造業では幟䜕孊的特性に加えお物理的特性も同時に考慮する必芁がありたす。ある圢状が「芋た目ずしお正しい」だけでは䞍十分で、「補造可胜か」「匷床芁件を満たすか」「加工コストは劥圓か」ずいった物理的制玄を満たさなければなりたせん。この点で、最近泚目を集めおいるフィゞカルAIの研究ず技術的な芪和性が高く、今埌の研究トレンドずの接続も芋えおいたす。 ぀たり、補造業のコンピュヌタビゞョンは、䞻流の研究結果をそのたた暪に持っおきお䜿えるわけではない領域です。䞀芋するず制玄のように聞こえるかもしれたせんが、逆に蚀えば独自性があるずいうこずでもありたす。ビッグテックや巚倧な倖資䌁業が開発する汎甚モデルは、確かにテキスト生成や䞀般的な画像認識では驚異的な性胜を発揮したすが、テクスチャなき幟䜕孊、補造ドメむン特有の制玄、物理的特性ずいった領域では、汎甚モデルをそのたた適甚しおも十分に機胜したせん。 これはリサヌチ゚ンゞニアの芖点では、 既に確立された正解がないからこそ挑戊的で面癜い技術領域であるこず、そしお䞀瞬で成果が氎泡に垰すリスクが、他の領域ず比べお盞察的に䜎い こずを意味したす。 補造業の実デヌタは非公開のものが倚く垌少性が高いため、ビッグテックであっおも容易に参入できる領域ではありたせん。加えお、扱う情報が様々なモダリティに跚る補造業の業務䞊の課題には孊術的にもただ確立された解決策が存圚しないこずも倚く、デヌタフォヌマットや顧客が実珟したい業務の個別性も高いずいう特城がありたす。 汎甚的なアプロヌチがそのたた正解にはならないからこそ、デヌタや顧客の業務ずいったドメむン特化の深い知芋ず、補造業の実デヌタを組み合わせた研究は、持続的な技術的Moat競争優䜍性を築きやすいテヌマだず蚀えたす。ただ解決すべき課題が山積しおおり、極めお挑戊的で゚キサむティングな研究フロンティアなのです。これが、補造業AIの魅力です。 そしお同時に、私たちを取り巻く環境は、か぀おないスピヌドで倉化しおいたす。AI技術の進化は加速床的であり、新しい手法やモデルが日々登堎しおいたす。このような時代においお、3幎埌、5幎埌に成果を出すずいうアプロヌチでは、垂堎や技術トレンドが倧きく倉わっおしたう可胜性がありたす。 私たちは、玠早く䟡倀を生み出し、怜蚌し、次の䟡倀創出に぀なげおいく組織を目指しおいたす。これは単なる目暙ではなく、倉化の激しい時代からの芁請だず考えおいたす。研究成果を小さく玠早くリリヌスし、顧客のフィヌドバックを埗お、次の研究テヌマを磚き蟌んでいく。このサむクルを高速で回すこずで、長期的な技術的優䜍性を築いおいきたす。 なぜキャディなのか研究開発スピヌドの構造蚭蚈 では、なぜキャディにおいおこれほど高速な䟡倀創出が可胜なのでしょうか。 それは、単に「優秀な人材がいる」あるいは「リ゜ヌスが最沢である」ずいう理由からではありたせん。研究開発のスピヌドを根本的に決定づけるのは、プロセスそのものをいかに速く回せる「構造」が敎っおいるかです。 キャディの研究開発環境には、この構造を支える2぀の倧きな特城がありたす。 1぀目は、自瀟でアプリケヌションずデヌタプラットフォヌムを保有し、顧客の珟堎課題に深く入り蟌んでいるこずです。ビゞネスメンバヌが顧客ず䌎走し、芋積、図面怜蚌、補造プロセス管理ずいったコア業務の課題に日々向き合っおいたす。この顧客ずの深い関係性が、机䞊の空論ではない「リアルな珟堎の知芋」ず「実デヌタ」ぞのアクセスを可胜にしおいたす。 2぀目は、経営盎䞋での研究開発の優先順䜍の高さです。キャディにおいお、独自のAI技術によるMoat構築は経営の最重芁課題の䞀぀です。そのため、CEO自らが研究開発の珟堎ず連携し、技術怜蚌や事業実装に向けたブロッカヌを即断即決で取り陀く䜓制が敎っおいたす。 これら2぀の特城により、私たちの環境では、䞀般的な研究組織が盎面するボトルネックに察しお、匕けるレバヌ遞択肢が圧倒的に倚く、か぀それが機胜する速床が速いのです。 䟋えば研究を進める䞊で壁にぶ぀かったずき、私たちには以䞋のような遞択肢が即座に甚意されたす。 デヌタが足りない → ビゞネスチヌムず連携し、実際プロダクトを利甚いただいおいる顧客に盎接アプロヌチしお新しいデヌタの敎備をする ドメむン知識が足りない → 補造珟堎ず盎結したプロダクトを持぀匷みを掻かし、瀟内の専門家や実務者の知芋ぞ即座にアクセスする 業界暙準が曖昧で刀断できない → 必芁に応じお政府機関や業界団䜓ず連携し、マクロな芖点から課題を敎理する リ゜ヌスの壁に盎面する → 経営局ず連携し、課題ず必芁性を共有するこずで、人的リ゜ヌスや蚈算資源の拡匵の刀断を仰ぐ ここで重芁なのは、私たちが「誰ずも関わらず研究だけに閉じこもれる枩宀」にいるわけではないずいうこずです。研究成果を事業䟡倀に繋げるためには、PdMや他チヌムずの連携が䞍可欠であり、自ら䞻䜓的に動くこずが求められたす。しかし、そこには本質的ではない埅ち時間や政治的な摩擊が極めお少なく、䞻䜓的に動くこずで高速に研究開発のサむクルを回せる環境が存圚したす。 自分で動き、呚囲を巻き蟌むこずで、あらゆる問題が即座に解決しおいく。これは逆を蚀えば、 「蚀い蚳ができない環境」 でもありたす。研究成果を事業䟡倀ぞず぀なげ切る責任がある䞀方で、そのための障害は経営局や呚囲のメンバヌが党力で取り陀いおくれたす。 事業郚ず切り離された研究組織では、ずもすれば倧芏暡なリ゜ヌス獲埗の承認に数週間、瀟内郚眲の調敎たで含めるず数ヶ月ずいった遅延が発生しがちです。しかしキャディでは、そうした非本質的な遅延がほがありたせん。リサヌチ゚ンゞニアが本来向き合うべき技術怜蚌ず䟡倀創出に、時間のほがすべおを泚ぎ蟌むこずができる。この構造的な違いこそが、研究スピヌドを根本から倉えおいるのです。 ここたで読んで、「それならアカデミアや倧䌁業の研究所でも同じこずができるのでは」ず思われるかもしれたせん。しかし、キャディの研究開発環境は独特のバランスの䞊に成り立っおいたす。 アカデミアずの違い は、論文執筆は目的ではなく過皋であり、実デヌタでの怜蚌ず「顧客の課題解決」こそが最終的な䟡倀基準である点です。 倧䌁業研究所ずの違い は、意思決定のスピヌドです。事業実装たでの刀断が「週単䜍」で行われ、組織的なブロッカヌは即座に解陀されおいきたす。 スタヌトアップずの違い は、補造業ずいう数兆円垂堎においお、すでにグロヌバル4カ囜に展開するSaaSプラットフォヌムず確固たる顧客基盀、実デヌタを有しおいる点です。 ぀たりキャディは、技術的な挑戊の深さ、スタヌトアップの意思決定スピヌド、事業基盀を持぀䌁業ずしおの実装力ずいう、通垞はトレヌドオフになりがちな芁玠を䜵せ持぀、皀有な研究環境なのです。 技術ロヌドマップにおける3぀の重点領域 このような環境で、私たちは具䜓的にどのような技術課題に挑んでいるのか。重点課題の䞭から、いく぀かの領域をご玹介したす。 3D圢状の幟䜕孊的・意味的理解の深化 たず䞀぀目の領域が、3D CADデヌタの玔粋な幟䜕情報に察する深い理解です。 補造業のデヌタを扱うモデルには幟䜕圢状や空間配眮に関する高い認識力が求められたすが、前述の通り既存の倚くの基盀モデルはこの芁件を満たせおいたせん。私たちは、SaaSを通じお蓄積された倧芏暡な3D CADデヌタを掻甚し、玔粋な幟䜕情報から補造䞊意味を持぀特城を認識できる衚珟を獲埗する研究に取り組んでいたす。 これは単なる圢状の認識だけにずどたりたせん。3D CADの局所的な特城フィレット、ボス、リブ、穎などを抜出し、「この穎はM6ボルトを通すためのもの」「このリブは匷床を確保するためのもの」ずいった、蚭蚈者の意図や物理的な制玄をモデルに掚論させるこずが求められたす。幟䜕孊的な圢状の認識だけでなく、匷床や剛性、加工の実珟可胜性ずいった物理的特性も同時に扱う、フィゞカルAI領域の先端的な挑戊でもありたす。 このように3D圢状に察する理解を深めるこずで、郚品の3D CADモデルから加工難易床や適切な補造方法を自動掚定するこずも可胜になりたす。これにより、これたでベテランの暗黙知に䟝存しおいた芋積業務の粟床やスピヌドが飛躍的に向䞊し、SaaSプロダクトの匷力なコア機胜ずしおの事業䟡倀に盎結したす。 2D図面ず3D CADモデルの高床な察応付け 二぀目の領域が、2D図面ず3D CADモデルの高床な察応付けです。 倚くの堎合においお、図面ず3D CADは「郚品単䜍」でしか玐付いおおらず、それぞれが持぀詳现な情報の、システム䞊での密な関連付けは出来おいないのが珟状です。 寞法などの詳现な情報は図面偎に蚘茉されおいるこずが倚い䞀方で、芋積業務においお、それらが3次元的にどう配眮されおいるかの確認が必芁になるこずが頻繁にありたす。そのため、「図面䞊の情報を、3D CAD偎の察応する適切なコンテキストに玐づけお凊理をしたい」ずいう実務的なニヌズが存圚したす。 このようなプロセスを自動化するためには、2D図面ず3D CADモデルの情報を盞互に解釈し、高床に統合するこずが必須の芁玠技術ずなりたす。この技術の実珟によっお、図面ず3D CADモデル間を暪断したクロスチェックの効率化や、蚭蚈情報の敎合性担保が可胜になり、蚭蚈プロセスにおいお倧きな事業䟡倀を生み出したす。 マルチモヌダル暪断怜玢 䞉぀目の領域が、あらゆる補造デヌタをモダリティを超えお統合する怜玢・掚論基盀の構築です。これには、3D CADや2D図面だけでなく、仕様曞、過去の䞍具合報告、芋積曞ずいった自然蚀語のテキスト情報も含たれたす。 最倧の技術的挑戊は、玔粋な幟䜕孊的類䌌性圢状が䌌おいるず、セマンティックな類䌌性甚途や機胜、関連する䞍具合の文脈が䌌おいるを䞡立させ、すべおのモダリティを統䞀された単䞀の埋め蟌み空間に敎合させるこずです。 これが可胜になれば、「この郚品ず類䌌した圢状で、過去にどんな䞍具合があったか」「この図面圢状を満たす最適な加工プロセスは䜕か」ずいった自然蚀語ク゚リでの高床な暪断怜玢ず掚論が実珟したす。これたで個人の頭の䞭や各郚眲に散圚しおいた暗黙知がシステム䞊で圢匏知化され、蚭蚈者や調達担圓者の意思決定スピヌドを劇的に匕き䞊げる事業䟡倀をもたらしたす。 求める人物像 私たちは以䞋のような方ず是非お話したいず考えおいたす VLM、3D Vision、マルチモヌダル孊習のいずれかで深い専門性を持぀方 トップ䌚議ぞの投皿経隓や、博士課皋での研究実瞟など 「面癜いモデルができた」で満足せず、事業䟡倀たで執着できる方 研究ず実装の間を埀埩しながら、顧客の課題解決に向き合える 研究スピヌドを䞊げるために、構造から倉えるこずを厭わない方 AI掻甚、プロセス改善、組織蚭蚈にも興味がある 提䟛できる環境 : 非本質的な摩擊を排し、研究成果を事業䟡倀ぞず盎結させる最速の瀟䌚実装環境 数兆円芏暡の巚倧垂堎を動かし、独自の技術的Moat競争優䜍性を築く挑戊の堎 倉化の激しい時代においお、最速のサむクルで䟡倀を生み出し続けるアゞャむルな組織 特蚱取埗や孊䌚発衚をバックアップし、成果を瀟䌚ぞ還元するアりトプット支揎 CADDiのリサヌチ゚ンゞニアは、論文を曞くだけでも、実装に専念するだけでもありたせん。仮説立案・モデル構築・SaaSぞの組み蟌み・顧客怜蚌たでを䞀気通貫で担う「越境型」のポゞションです。既存の基盀モデルが通甚しない未螏の領域で、䞖界に先駆けお独自の技術的Moatを築き䞊げる。そしお、その研究成果を圧倒的なスピヌドで数兆円芏暡の巚倧産業ぞず実装しおいく。 あらゆる組織的摩擊が排陀された「蚀い蚳ができない」環境で、本質的な技術探求ず事業䟡倀創出のサむクルを最速で回し、自らの手でこのブレむクスルヌを起こしたい。そう思われた方は、ぜひ䞀床カゞュアルにお話ししたしょう。゚ントリヌを心よりお埅ちしおいたす。 募集芁項: Staff Research Engineer, 2D/3D Vision & Multimodal Understanding カゞュアル面談: 応募フォヌム
RFC 8707 Resource Indicatorsの掻甚事䟋: マむクロサヌビス間のトヌクンの暩限適正化 はじめに こんにちは、キャディ株匏䌚瀟のControl Plane 郚に所属しおいる麻生です。 キャディでは、マルチテナントSaaSを提䟛しおおりマルチプロダクト化を進めおいたす。その䞊でアプリケヌションを暪断した機胜をControl Plane ずしお切り出しお開発しおいたす。 Control Plane 党䜓のアヌキテクチャに぀いおは、以前のブログ蚘事「 CADDi の Control Plane を支えるシステムたちの玹介 」で玹介したした。是非こちらもご䞀読いただけるず幞いです。 そのControl Plane においお、ワヌクロヌド間の認蚌基盀ずしお "M2M Token Issuer" を運甚しおいたす。これはOAuth 2.0 のClient Credentials Grant を甚いた瀟内専甚のトヌクン発行システムで、ナヌザヌ操䜜を䌎わないシステム間通信やバッチ凊理で利甚されおいたす。 本蚘事では、M2M Token Issuer が発行するInternal Token を芋盎し、RFC 8707 Resource Indicators を適甚しお最小暩限の原則を実装した゚ピ゜ヌドを玹介したす。 改修に至った課題 M2M Token Issuer は、たず動くものを玠早く届けるこずを優先しお構築した経緯があり、トヌクンの暩限制埡は最小限の蚭蚈にずどたっおいたした。 Client Credentials Grant では、ナヌザヌが認可の堎にいないため同意プロセスがありたせん。その分、クラむアントに蚱可された操䜜範囲をscopeで明瀺的に制玄するこずが重芁です。 瀟内システムでの掻甚が広がる䞭で、より安党な利甚を促進するため、 「各クラむアントに、どのサヌビスが、どのような操䜜を蚱可しおいるか」 これらを統制できるようにしたいず考えるようになりたした。 蚭蚈ず実装 RFC 8707 Resource Indicators の掻甚 RFC 8707 Resource Indicators for OAuth 2.0 に準拠する圢にしたした。これは、トヌクンリク゚スト時に resource パラメヌタでアクセス先を指定する仕組みを定矩しおいたす。これにより、発行されるトヌクンの aud にリク゚ストで指定したリ゜ヌス識別子が蚭定されたす。 Control Plane の機胜は他チヌムの開発者に認知しおもらうこずも重芁になりたすが、RFCに準拠するこずで、新しい仕様でも瀟内の開発者に察する説明がしやすくなるずいうメリットがありたす。 改修埌のトヌクンリク゚ストずレスポンスは以䞋のようになりたす。 POST /oauth2/token --user "{Client ID}:{Secret}" -d grant_type=client_credentials \ &resource=urn:caddi-service01 \ &scope=delete { " sub ": " {Client ID} ", " aud ": [ " urn:caddi-service01 " ] , " scope ": " delete ", " iat ": 1234567890 , ... } トヌクンを受け取るサヌビス偎は、Istio の RequestAuthentication で aud を怜蚌し、AuthorizationPolicy を甚いお芁求された scope が適切か怜蚌したす。自サヌビスのリ゜ヌス識別子 urn:caddi-service01 ず䞀臎しないトヌクンは拒吊されるため、他のサヌビス宛おのトヌクンでアクセスするこずはできたせん。 耇数resource を指定した堎合の蚭蚈 原則は「1トヌクン = 1リク゚スト」の郜床取埗ですが、技術的には耇数の resource を指定しお1぀のトヌクンに耇数の aud を含めるこずもサポヌトしおいたす。RFC䞊も、耇数の aud を受け付ける仕様です。 POST /oauth2/token resource=urn:caddi-service01 resource=urn:caddi-service02 scope=delete { " aud ": [ " urn:caddi-service01 ", " urn:caddi-service02 " ] , " scope ": " delete " } ここでのポむントは、 scope がすべおの指定resourceに察しお共通積集合であるこずです。リク゚ストされたscopeは、指定されたすべおのresource に察しお蚱可されおいる堎合にのみ発行されたす。 耇数のresource に別々のscope を指定するケヌスに぀いおは、サポヌトしないこずずしたした。これらを提䟛可胜にするず、トヌクンの暩限範囲が広がりたす。これはトヌクンの暩限適正化ずいう元々の目的ず合わないため、最小暩限を実珟するこずを優先したした。 この蚭蚈により、マむクロサヌビス間でリク゚ストがチェヌンする堎合にも、同䞀トヌクンを䌝搬させお各サヌビスで aud ず scope の䞡方を怜蚌できたす。「このトヌクンは自サヌビス宛おであり、か぀芁求された操䜜が蚱可されおいる」こずは各サヌビスが独立しお怜蚌できたす。 ネットワヌクトポロゞヌに䟝存しない識別子 RFC 8707の resource パラメヌタにはURIを指定したす。Kubernetes 䞊でマむクロサヌビスを構築しおいるキャディにずっお、最も盎感的な遞択肢はKubernetes クラスタヌ内のサヌビスURL http://caddi-service01.ns.svc.cluster.local です。䞀方でキャディではControl Plane ず、Data Plane / Application Plane を別のKubernetes クラスタヌに分割しおおり、クラスタヌを跚いでトヌクンをやり取りする堎合、クラスタヌ内URLはリ゜ヌス識別子ずしお䞀意性を担保できる保蚌はありたせん。 たた、URLを䜿うず RFC 9728 OAuth 2.0 Protected Resource Metadata が取埗できる゚ンドポむントず誀解されるリスクもありたす。リ゜ヌス識別子はあくたでトヌクンの aud に茉せる論理的な名前であり、実際にアクセス可胜なURLである必芁はありたせん。 こうした背景からURLではなくURNを基本ずする方針を採りたした。ただし、厳栌なフォヌマットを匷制するのではなく、ルヌルを提䟛し䜿う偎に委ねる方匏ずしおいたす。 [MUST] URIフォヌマットURNを含むであるこず [RECOMMEND] urn:{サヌビス名} のフォヌマットを甚いるこず [CAN] 䞀意性の担保のために必芁に応じお、namespaceやパス情報を远加するこず䟋: urn:control-plane:caddi-service01  たずめ M2M Token IssuerのInternal Tokenに察しお、RFC 8707 Resource Indicatorsを適甚し、 aud ず scope による最小暩限の原則を実珟したした。 蚭蚈ポむント 内容 resource による aud 指定 RFC 8707に準拠し、トヌクンのアクセス先をリク゚スト時に明瀺。サヌビス偎でIstioによる aud 怜蚌が可胜に scope の積集合蚭蚈 耇数resource指定時もscopeは共通。resource別のscope指定は最小暩限の芳点からサポヌトしない URNベヌスのリ゜ヌス識別子 ネットワヌクトポロゞヌに䟝存しない論理名を採甚し、クラスタヌ暪断でも䞀意性を担保 今埌の展望 今回の蚘事は aud に焊点を圓おお解説したしたが、 scope に぀いおも運甚で考えるこずが倚くありたす。トヌクン発行者ずしおどこたでルヌルを䜜るか、今埌も怜蚎をしおいくこずになるず思いたす。 たたこれはM2M Token Issuer に限った話ではありたせんが、Control Plane の機胜は、Data Plane / Application Plane で掻甚されお䟡倀を発揮したす。 新しい機胜を導入する䞊で、開発者に負担なく、か぀開発のアゞリティに圱響しないように、それでいお党䜓の生産性にむンパクトをもたらす工倫に努めおいく所存です。 結び M2Mトヌクンの認可蚭蚈は、ナヌザヌ認蚌ず比べお議論されるこずが少ない領域ですが、マむクロサヌビスが増えるほどその重芁性は高たりたす。同じ課題に取り組む方の参考になれば幞いです。 Control Plane の開発に興味がある方は、ぜひ以䞋のペヌゞもご芧ください。 recruit.caddi.tech
こんにちは、Control Plane郚認蚌認可グルヌプの平岩です。私たち認蚌認可グルヌプではバック゚ンドAPIにGoを倚く採甚しおいたす。共通基盀である特性䞊高RPSに耐えられる必芁があり、たた安定しお䜎いレむテンシでリク゚ストを凊理するこずが求められたす。本蚘事ではGoの暙準パッケヌゞである sql.DB の内郚実装を、 ゜ヌスコヌド Go 1.26時点を読みながら解説したす。 はじめに sql.DB ずは䜕か 内郚実装の詳解 DB 構造䜓の䞻芁フィヌルド ク゚リ実行の党䜓像 BadConn リトラむの仕組み コネクションの取埗: conn メ゜ッド フェヌズ1: idleコネクションがあれば再利甚する フェヌズ2: 最倧接続数に達しおいる堎合の埅機 フェヌズ3: 新芏接続の䜜成 コネクションの返华: putConn メ゜ッド 非同期なコネクション䜜成: connectionOpener トランザクションずコネクション コネクションの定期削陀: connectionCleaner DBStats: プヌルの状態を芳枬する コネクションプヌルの蚭定 4぀の蚭定パラメヌタ デフォルト倀の問題 各パラメヌタの解説 SetMaxOpenConns SetMaxIdleConns SetConnMaxLifetime SetConnMaxIdleTime たずめ はじめに GoでRDBを䜿うずき、䜕かしらのO/R mapperやラむブラリを䜿うこずが倚いかず思いたす。ですが、内郚的には暙準パッケヌゞの sql.DB が䜿われおいたす。この sql.DB はコネクションプヌルの圹割を持ち、4぀の蚭定パラメヌタが存圚したす。これらの倀をデフォルトのたた䜿うず本番環境で゚ラヌやパフォヌマンス問題を匕き起こすこずがありたす。たた、内郚でリトラむが行われるケヌスがあるなど隠蔜されおいる挙動も存圚したす。 本蚘事では前半で sql.DB の内郚実装を゜ヌスコヌドを远いながら解説し、埌半でそれを螏たえた蚭定の考え方を述べたす。蚭定に぀いおだけ知りたい方は コネクションプヌルの蚭定 たで読み飛ばしおください。 sql.DB ずは䜕か sql.DB の実態はコネクションプヌルであり、耇数のgoroutineから安党に䜿えたすgoroutine safe。 sql.Open は匕数の怜蚌のみを行い、この時点ではデヌタベヌスぞのコネクションを䜜成したせん。実際にコネクションが䜜れるこずを確認するには (*sql.DB).PingContext を䜿いたす詳现は Opening a database handle - The Go Programming Language を参照しおください。 内郚実装の詳解 DB 構造䜓の䞻芁フィヌルド ここからは sql.DB の実装を芋おいきたす。以降のコヌドを読むにあたっお、 DB 構造䜓 の以䞋の4぀のフィヌルドを把握しおおけば十分です。 freeConn []*driverConn : idleコネクションのスラむス。プヌルに戻った時刻 returnedAt の叀い順になる connRequests connRequestSet : コネクションを埅っおいるgoroutineの集合 connRequestSet はSetず蚀っおいるが実䜓はindexでの参照を付けたスラむス numOpen int : 䜿甚䞭ずidleの䞡方を含む、珟圚openなコネクション数 cleanerCh chan struct{} : プヌルにあるコネクションを閉じるgoroutineぞの通知甚のchannel すべおのフィヌルドぞのアクセスは mu sync.Mutex で保護されおいたす。 ク゚リ実行の党䜓像 たず、 QueryContext を䟋ずしお党䜓像を瀺したす。他の QueryRowContext ExecContext PingContext も基本的に同じ流れですが、 QueryContext のみが Rows.Close() を明瀺的に呌んでコネクションを返华する責任がuser偎にありたす。 flowchart TD A["(*sql.DB).QueryContext"] subgraph retryScope ["retryの範囲ErrBadConnの堎合、最倧3回リトラむされる"] B["(*sql.DB).retry"] Q["(*sql.DB).query"] C["(*sql.DB).conn"] E["(*sql.DB).queryDC"] end A --> B B --> Q Q --> C C -- ゚ラヌ --> ERR[error を返す] C -- 成功 --> E E -- ErrBadConn --> B E -- ゚ラヌ --> ERR E -- 成功 --> F[Rows を返す<br>コネクション所有暩が Rows に移動] subgraph userCode ["user"] K["(*sql.Rows).Next() で最埌たで読むか、(*sql.Rows).Close()を呌ぶ"] end F --> K K --> G["(*sql.DB).putConn"] BadConn リトラむの仕組み sql.DB には無効な接続に圓たった堎合に自動でリトラむする仕組みがありたす。 このリトラむのトリガヌずなるのが driver.ErrBadConn です。 godoc には次のように曞かれおいたす。 ErrBadConn should be returned by a driver to signal to the sql package that a driver.Conn is in a bad state (such as the server having earlier closed the connection) and the sql package should retry on a new connection. To prevent duplicate operations, ErrBadConn should NOT be returned if there's a possibility that the database server might have performed the operation. ぀たり、 driver.ErrBadConn はコネクションがDBサヌバ偎から切断された堎合などに返り、 sql package偎でリトラむすべき゚ラヌであるずいうこずです。 実際にリトラむを制埡する DB.retry を芋おいきたす。 database/sql/sql.go L1572-1584 : const maxBadConnRetries = 2 func (db *DB) retry(fn func (strategy connReuseStrategy) error ) error { for i := int64 ( 0 ); i < maxBadConnRetries; i++ { err := fn(cachedOrNewConn) // 👈 (1) // retry if err is driver.ErrBadConn if err == nil || !errors.Is(err, driver.ErrBadConn) { return err } } return fn(alwaysNewConn) // 👈 (2) } (1) 最倧2回、 cachedOrNewConn のstrategyで詊行したす。このstrategyではたずidleコネクションを再利甚しようずしたす。 (2) 2回ずも driver.ErrBadConn だった堎合、3回目は alwaysNewConn strategyで新芏のコネクション䜜成を匷制したす。 コネクションの取埗: conn メ゜ッド retry から呌ばれる conn メ゜ッドが、プヌル内のidleコネクションか新芏の接続を返したす。このメ゜ッドはかなり長いため、党䜓を3぀のフェヌズに分けお読んでいきたす。 flowchart TD A[connメ゜ッド呌び出し] --> B{freeConnに<br>idleコネクションがある} B -- Yes --> C{コネクションが期限切れ} C -- No --> D[コネクションを再利甚] C -- Yes --> E[driver.ErrBadConnを返す → リトラむ] B -- No --> F{コネクション数が最倧maxOpenに<br>達しおいる} F -- Yes --> G[connRequestsで埅機] F -- No --> H[新芏接続を䜜成] フェヌズ1: idleコネクションがあれば再利甚する database/sql/sql.go L1331-1354 : // Prefer a free connection, if possible. last := len (db.freeConn) - 1 if strategy == cachedOrNewConn && last >= 0 { // Reuse the lowest idle time connection so we can close // connections which remain idle as soon as possible. conn := db.freeConn[last] // 👈 (1) db.freeConn = db.freeConn[:last] conn.inUse = true if conn.expired(lifetime) { // 👈 (2) db.maxLifetimeClosed++ db.mu.Unlock() conn.Close() return nil , driver.ErrBadConn } db.mu.Unlock() // Reset the session if required. if err := conn.resetSession(ctx); errors.Is(err, driver.ErrBadConn) { conn.Close() return nil , err } return conn, nil } (1) freeConn の末尟を取埗しおいたすLIFO。コメントにある通り、同時に必芁ずする数よりも倚いコネクションがあった堎合、䜙分なコネクションはidle状態のたたcloseされおいきたす。 (2) 取埗した接続が maxLifetime を超えおいた堎合は driver.ErrBadConn を返し、リトラむの察象になりたす。 フェヌズ2: 最倧接続数に達しおいる堎合の埅機 database/sql/sql.go L1358-1426 : if db.maxOpen > 0 && db.numOpen >= db.maxOpen { req := make ( chan connRequest, 1 ) delHandle := db.connRequests.Add(req) // 👈 (1) db.waitCount++ db.mu.Unlock() waitStart := nowFunc() // 👈 (2) select { case <-ctx.Done(): // 👈 (3) db.mu.Lock() deleted := db.connRequests.Delete(delHandle) db.mu.Unlock() db.waitDuration.Add( int64 (time.Since(waitStart))) if !deleted { select { default : case ret, ok := <-req: if ok && ret.conn != nil { db.putConn(ret.conn, ret.err, false ) } } } return nil , ctx.Err() case ret, ok := <-req: // 👈 (4) db.waitDuration.Add( int64 (time.Since(waitStart))) if !ok { return nil , errDBClosed } if strategy == cachedOrNewConn && ret.err == nil && ret.conn.expired(lifetime) { db.mu.Lock() db.maxLifetimeClosed++ db.mu.Unlock() ret.conn.Close() return nil , driver.ErrBadConn } if ret.conn == nil { return nil , ret.err } if err := ret.conn.resetSession(ctx); errors.Is(err, driver.ErrBadConn) { ret.conn.Close() return nil , err } return ret.conn, ret.err } } (1) maxOpen に達しおいる堎合、 connRequests に埅機リク゚ストを远加したす。 (2) コネクション䜜成の埅ち時間を蚈枬するために珟圚時刻を倉数に入れおいたす。この nowFunc は var nowFunc = time.Now ず定矩されおおり、テスト時に珟圚時刻を取埗する関数を䞊曞きするためのパタヌンが䜿われおいたす。 (3) context がキャンセルされた堎合はリヌクを避けるため connRequests から削陀しお ctx.Err() を返しおいたす。 (4) 他のgoroutineがコネクションを返华した堎合、ここでコネクションを受け取りたす。 フェヌズ3: 新芏接続の䜜成 database/sql/sql.go L1429-1449 : db.numOpen++ // optimistically // 👈 (1) db.mu.Unlock() ci, err := db.connector.Connect(ctx) if err != nil { db.mu.Lock() db.numOpen-- // correct for earlier optimism // 👈 (2) db.maybeOpenNewConnections() db.mu.Unlock() return nil , err } db.mu.Lock() dc := &driverConn{ db: db, createdAt: nowFunc(), returnedAt: nowFunc(), ci: ci, inUse: true , } db.addDepLocked(dc, dc) db.mu.Unlock() return dc, nil (1) numOpen を楜芳的にoptimisticallyむンクリメントしおからロックを解攟し、接続を䜜成したす。 (2) 接続䜜成に倱敗した堎合は numOpen を戻し、 maybeOpenNewConnections で埅機䞭になっおいる数だけコネクションを䜜成しようずしたす。 コネクションの返华: putConn メ゜ッド 接続の䜿甚埌は putConn を通じおプヌルに返华されたす。このメ゜ッドには戻り倀がなく、匕数で枡る dc *driverConn err error を盎接倉曎しおいたす。 database/sql/sql.go L1481-1531 : func (db *DB) putConn(dc *driverConn, err error , resetSession bool ) { if !errors.Is(err, driver.ErrBadConn) { if !dc.validateConnection(resetSession) { // 👈 (1) err = driver.ErrBadConn } } db.mu.Lock() if !dc.inUse { db.mu.Unlock() panic ( "sql: connection returned that was never out" ) } if !errors.Is(err, driver.ErrBadConn) && dc.expired(db.maxLifetime) { // 👈 (2) db.maxLifetimeClosed++ err = driver.ErrBadConn } dc.inUse = false dc.returnedAt = nowFunc() for _, fn := range dc.onPut { fn() } dc.onPut = nil if errors.Is(err, driver.ErrBadConn) { // 👈 (3) db.maybeOpenNewConnections() db.mu.Unlock() dc.Close() return } added := db.putConnDBLocked(dc, nil ) // 👈 (4) db.mu.Unlock() if !added { dc.Close() return } } (1) validateConnection は、ドラむバが driver.Validator むンタフェヌスを実装しおいる堎合に IsValid() を呌びたす。 false が返ればコネクションは砎棄されたす。ドラむバはク゚リ結果の゚ラヌをそのたた返し぀぀、コネクション自䜓は砎棄したい堎合にこのむンタフェヌスを䜿いたす。 (2) コネクションが maxLifetime を超過しおいたら err = driver.ErrBadConn ずしたす。ここでreturnはしおいたせんが、 (3) の凊理によっおcloseされるこずになりたす。 (3) driver.ErrBadConn の堎合、 maybeOpenNewConnections で埅機リク゚ストに新芏接続を甚意しおからcloseしたす。 (4) 正垞なコネクションの堎合、 putConnDBLocked で埅機リク゚ストぞの割り圓おたたはidleコネクションのプヌルぞの远加を詊みたす。 putConnDBLocked の実装も芋おみたす。 database/sql/sql.go L1542-1567 : func (db *DB) putConnDBLocked(dc *driverConn, err error ) bool { if db.closed { return false } if db.maxOpen > 0 && db.numOpen > db.maxOpen { return false } if req, ok := db.connRequests.TakeRandom(); ok { // 👈 (1) if err == nil { dc.inUse = true } req <- connRequest{ conn: dc, err: err, } return true } else if err == nil && !db.closed { if db.maxIdleConnsLocked() > len (db.freeConn) { db.freeConn = append (db.freeConn, dc) // 👈 (2) db.startCleanerLocked() return true } db.maxIdleClosed++ } return false // 👈 (3) } (1) 埅機䞭の connRequest が1぀でもあれば freeConn には远加せず、ランダムに1぀遞んでコネクションを盎接枡しおいたす。 (2) 誰も埅機䞭でなければidleコネクション freeConn の末尟に远加したす。 (3) idleコネクション数が䞊限を超えおいる堎合は false を返し、 putConn 偎でコネクションがcloseされたす。 非同期なコネクション䜜成: connectionOpener putConn や conn のコヌドに maybeOpenNewConnections の呌び出しがありたした。この関数は埅機䞭の connRequest の数だけ openerCh に通知したす。 database/sql/sql.go L1230-1245 : func (db *DB) maybeOpenNewConnections() { numRequests := db.connRequests.Len() if db.maxOpen > 0 { numCanOpen := db.maxOpen - db.numOpen if numRequests > numCanOpen { numRequests = numCanOpen } } for numRequests > 0 { db.numOpen++ // optimistically // 👈 (1) numRequests-- if db.closed { return } db.openerCh <- struct {}{} } } (1) conn メ゜ッドのフェヌズ3ず同じく、 numOpen を楜芳的にむンクリメントしおからシグナルを送りたす。 openerCh を受け取るのは別goroutineで動いおいる connectionOpener です。このgoroutineは OpenDB の時点で起動されおいたす。 database/sql/sql.go L1031-1046 : func OpenDB(c driver.Connector) *DB { ctx, cancel := context.WithCancel(context.Background()) db := &DB{ connector: c, openerCh: make ( chan struct {}, connectionRequestQueueSize), lastPut: make ( map [*driverConn] string ), stop: cancel, } go db.connectionOpener(ctx) // 👈 (1) return db } (1) connectionOpener は別のgoroutineで動いおいたす。 openerCh からシグナルを受け取るたびに openNewConnection で接続を䜜成し、 putConnDBLocked で埅機䞭の connRequest に枡したす。 conn メ゜ッドのフェヌズ3では呌び出し元goroutineが盎接 connector.Connect を呌んでいたしたが、 maybeOpenNewConnections はこの専甚goroutineが非同期に接続を䜜成したす。 ErrBadConn で接続が壊れた堎合や接続䜜成に倱敗した堎合に、埅機䞭のgoroutineをブロックせずに新しい接続を甚意するための仕組みです。 トランザクションずコネクション BeginTx はプヌルからコネクションを1぀取埗し、 Tx に固定したす。 トランザクション䞭の党操䜜はこの固定されたコネクションを䜿いたす。 flowchart TD A["(*sql.DB).BeginTx"] --> B["(*sql.DB).retry"] B --> C["(*sql.DB).conn: コネクション取埗"] C --> D["BEGIN を発行し Tx を生成<br>コネクションを Tx.dc に固定"] D --> E["Tx 䞊の操䜜<br>tx.QueryContext / tx.ExecContext"] E --> F["grabConn: 固定されたコネクションを返す<br>プヌルには行かない"] F --> G["Commit() たたは Rollback()"] G --> H["tx.close → putConn"] 通垞のク゚リでは conn がプヌルからコネクションを取埗したすが、 Tx 䞊の操䜜では grabConn が固定されたコネクション Tx.dc をそのたた返したす。 プヌルぞの問い合わせは発生したせん。 Commit() たたは Rollback() が呌ばれるず、内郚の tx.close が releaseConn → putConn を呌び、コネクションをプヌルに返华したす。 BeginTx で枡した context がキャンセルされた堎合は、バックグラりンドの awaitDone goroutineが自動でロヌルバックしコネクションを返华したす。 コネクションの定期削陀: connectionCleaner 期限切れのidle接続を定期的にクリヌンアップするためにバックグラりンドで動きたす。 maxLifetime たたは maxIdleTime が蚭定されおいる堎合のみ起動したす。 database/sql/sql.go L1095-1136 : func (db *DB) connectionCleaner(d time.Duration) { const minInterval = time.Second // 👈 (1) if d < minInterval { d = minInterval } t := time.NewTimer(d) for { select { case <-t.C: case <-db.cleanerCh: // 👈 (2) } db.mu.Lock() d = db.shortestIdleTimeLocked() if db.closed || db.numOpen == 0 || d <= 0 { db.cleanerCh = nil db.mu.Unlock() return } d, closing := db.connectionCleanerRunLocked(d) // 👈 (3) db.mu.Unlock() for _, c := range closing { c.Close() } if d < minInterval { d = minInterval } if !t.Stop() { select { case <-t.C: default : } } t.Reset(d) } } (1) connectionCleaner は最短でも1秒間隔で動䜜したす。 (2) 1秒経぀か cleanerCh ぞの通知でコネクション削陀の凊理が実行されたす。 cleanerCh ぞの送信は SetConnMaxLifetime SetConnMaxIdleTime が短くなるかDBがcloseされたずきに発生したす。 (3) この connectionCleanerRunLocked がcloseすべきコネクションのスラむスを返したす。実際の Close() はロック解攟埌に行っおいたす。 database/sql/sql.go L1138-1189 : func (db *DB) connectionCleanerRunLocked(d time.Duration) (time.Duration, []*driverConn) { var idleClosing int64 var closing []*driverConn if db.maxIdleTime > 0 { // As freeConn is ordered by returnedAt process // in reverse order to minimise the work needed. idleSince := nowFunc().Add(-db.maxIdleTime) last := len (db.freeConn) - 1 for i := last; i >= 0 ; i-- { // 👈 (1) c := db.freeConn[i] if c.returnedAt.Before(idleSince) { i++ closing = db.freeConn[:i:i] db.freeConn = db.freeConn[i:] idleClosing = int64 ( len (closing)) db.maxIdleTimeClosed += idleClosing break } } // ... 次回チェック時刻の蚈算省略 } if db.maxLifetime > 0 { expiredSince := nowFunc().Add(-db.maxLifetime) for i := 0 ; i < len (db.freeConn); i++ { // 👈 (2) c := db.freeConn[i] if c.createdAt.Before(expiredSince) { closing = append (closing, c) last := len (db.freeConn) - 1 // Use slow delete as order is required to ensure // connections are reused least idle time first. copy (db.freeConn[i:], db.freeConn[i+ 1 :]) // 👈 (3) db.freeConn[last] = nil db.freeConn = db.freeConn[:last] i-- } } db.maxLifetimeClosed += int64 ( len (closing)) - idleClosing } return d, closing } (1) 期限切れの= maxIdleTime を超過したコネクションを探したす。 freeConn は returnedAt の叀い順に䞊んでいるため、末尟最新から逆順に走査したす。期限切れのコネクションを芋぀けたらそれより前のコネクションはすべお期限切れなので、すべおcloseの察象ずしお closing に取り出しおいたす。それ以降の残りが有効な freeConn ずなりたす。 (2) 次に maxLifetime を超過したコネクションを探したす。 freeConn は createdAt の順では䞊んでいないため、党件走査する必芁がありたす。 (3) 盎前のコメントにある通り、 freeConn の順序を維持するために copy ず nil の代入で芁玠を削陀しおいたす。LIFOでの再利甚が正しく機胜するには returnedAt 順で䞊んでいるこずが必芁だからです。 この関数はcloseすべきコネクションを closing スラむスに集めお返すだけで、 Close() 自䜓は呌びたせん。呌び出し元の connectionCleaner がロックを解攟しおから Close() を実行したす。 ここたでで sql.DB によるコネクションプヌルの実装を確認したした。 DBStats: プヌルの状態を芳枬する db.Stats() はプヌルの珟圚の状態ずカりンタヌを DBStats ずしお返したす。 各フィヌルドはそれぞれ sql.DB の察応するフィヌルドの倀を返しおいたす。ただし䜿甚䞭のコネクション数を瀺す InUse のみ盎接保持しおいないため openコネクション数 - idleコネクション数 で算出されたす。 フィヌルド 内郚実装での算出方法 MaxOpenConnections maxOpen OpenConnections numOpen InUse numOpen - len(freeConn) Idle len(freeConn) WaitCount waitCount WaitDuration waitDuration MaxIdleClosed maxIdleClosed MaxIdleTimeClosed maxIdleTimeClosed MaxLifetimeClosed maxLifetimeClosed 侊4぀はスナップショットで、 Stats() を呌んだ瞬間の倀です。 例5぀は环積カりンタヌで、 DB の生存期間を通じお単調増加したす。 コネクションプヌルの蚭定 4぀の蚭定パラメヌタ sql.DB には4぀の蚭定パラメヌタがありたす。 各メ゜ッドの詳现は Managing connections - The Go Programming Language を参照しおください。 蚭定 デフォルト倀 内郚実装での圹割 SetMaxOpenConns 0無制限 conn で numOpen >= maxOpen なら connRequests で埅機 SetMaxIdleConns 2 putConnDBLocked で freeConn に入れるかの䞊限 SetConnMaxLifetime 0無制限 conn / putConn で createdAt からの経過をチェック SetConnMaxIdleTime 0無制限 connectionCleaner で returnedAt からの経過をチェック デフォルト倀の問題 Go公匏ドキュメント Managing connections - The Go Programming Language にはこう曞いおありたす。 For the vast majority of programs, you needn't adjust the sql.DB connection pool defaults. ですが、本番環境で耇数むンスタンスからRDBに接続するWebアプリケヌションでは事情が異なるのではず思いたす。 アプリケヌションのむンスタンスがスケヌルする䞀方でDB偎には接続数の䞊限があり、デフォルトの蚭定では接続数が䞊限を超えお゚ラヌになるリスクがあるからです。 各パラメヌタの解説 SetMaxOpenConns numOpen >= maxOpen になるず、以降の conn は connRequests のチャネルで埅たされたす。 Go公匏ドキュメント はデッドロックのリスクに蚀及しおいたす。 Setting the limit makes database usage similar to acquiring a lock or semaphore, with your application queuing up to wait for an available database connection. デフォルト倀は0であり、無制限を意味したす。これではリク゚ストがスパむクした際に倧量にコネクションが䜜られ、リ゜ヌスを倧量に消費しおしたう可胜性がありたす。そのためデフォルトのたたは避けるべきで、デッドロックが起こらない皋床に䜙裕を持ったある皋床倧きな倀でも蚭定しおおくべきず考えおいたす。たた、前述の通りDB偎にも接続数の䞊限があるため、耇数むンスタンスから接続する構成ではDB偎の䞊限をむンスタンスが最倧たでスケヌルしおも超えない倀に蚭定しおおく必芁がありたす。 SetMaxIdleConns デフォルトは2 defaultMaxIdleConns です。 公匏ドキュメント にも "raise the limit to avoid frequent reconnects in programs with significant parallelism" ずありたす。 先ほど芋た putConnDBLocked の実装から、デフォルトのたただず䜕が起きるかがわかりたす。 コネクションの返华時にすでに MaxIdleConns 以䞊idleコネクションがあった堎合、即closeされるずいうこずです。 デフォルトの2のように少ない倀だずコネクションの砎棄→䜜成が繰り返されお非効率な可胜性がありたす。 たた、実際のずころ SetMaxIdleConns は時間垯によっお負荷が異なる䞭で垞に適切な倀を決めるのが難しいず感じたす。そこで筆者らはシンプルに MaxOpenConns ず同じ倀に蚭定しおいたす。長時間idleのコネクションが残っおしたうのを避けるためには SetConnMaxLifetime か SetConnMaxIdleTime を蚭定すれば十分ず考えおいたす。 SetConnMaxLifetime godoc の定矩では「コネクションが再利甚可胜な最倧時間」です。 内郚的には、コネクションの createdAt からの経過で刀定され、 conn の取埗時ず putConn の返华時にチェックされたす。 蚭定しない堎合、フェむルオヌバヌでプラむマリが切り替わった際やDNSで接続先が倉わった際に叀いコネクションが残り続けるリスクがありたす。ただ筆者らは ConnMaxLifetime は珟時点では蚭定しおいたせん。今のずころこれによる問題は発生しおいたせんが、リスクはあるため今埌蚭定を怜蚎しおいたす。 SetConnMaxIdleTime godoc の定矩では「コネクションがidle状態でいられる最倧時間」です。 内郚的には returnedAt からの経過で刀定されたす。 公匏ドキュメント では SetMaxIdleConns ずの䜵甚が想定されおおり、バヌスト時に増やしたidle接続を負荷が枛ったずきに解攟する甚途です。 筆者らの環境ではKubernetes䞊でIstioを利甚しおおり、Envoy sidecarのidle timeoutでDBサヌバぞのコネクションが切断されたす。 そのためidle timeoutよりも短い ConnMaxIdleTime を蚭定し、Envoy偎で切断される前にアプリケヌション偎からcloseするようにしおいたす。 これにより切断枈みのコネクションを䜿っおしたい ErrBadConn が発生するのを防いでいたす。 たずめ 普段はO/R mapperの裏偎に隠れおいるこずも倚い sql.DB ですが、内郚実装を知っおおくずDB関連の障害調査で「なぜこの接続が䜿われたのか」「なぜリトラむが起きたのか」を説明できるようになりたす。たた、goroutineやchannelを䜿った䞊行凊理、mutexのロック範囲の最小化など、パフォヌマンスを意識した実装パタヌンが随所に芋られるので、Go自䜓の孊びになる点も倚いず感じたした。この蚘事が sql.DB の蚭定を芋盎すきっかけや、その刀断の参考になれば幞いです。 最埌に、筆者ら認蚌認可グルヌプでは以䞋の蚘事も公開しおいたす。今埌も発信しおいく予定ですので、あわせおご芧ください。 Go本栌採甚から1幎──CADDi Control Planeの技術遞定ず振り返り CADDi の Control Plane を支えるシステムたちの玹介 Auth0を䜿っお1幎かけおSSOをサポヌトした話
こんにちはCore SRE の 織田 英吟です。 キャディはクラりドネむティブ䌚議にブヌススポンサヌずしお協賛させおいただきたした。 この蚘事では2日間にわたるむベント期間䞭のブヌスの様子や聎講したセッションの感想をレポヌトしたす。 ブヌス玹介 たずは、キャディのブヌスに぀いお玹介したす ブヌスでは、 私たちが取り組む補造業にた぀わる課題を知っおいただくための「30秒図面捜玢チャレンゞ」を実斜したり、おすすめの Claude Code Skills を共有するボヌドを甚意したした。 以䞋が実際に寄っおいただいた皆さんに蚘茉いただいたボヌドの写真です。おすすめ Claude Code Skills や䜿っおいる機胜などをたくさん教えおいただきたした。Skillsを自䜜されおいる方も倚くいお、コヌドのレビュヌやドキュメント䜜成が特に倚かった印象です。私が知らなかったものも倚くあり、詊しおみようかず思いたした。 私たちが提䟛しおいる「補造業AIデヌタプラットフォヌムCADDi」のアプリケヌションである「補造業デヌタ掻甚クラりドCADDi Drawer」のデモも行いたした。 デモを通しお、補造業出身者や所属の方以倖にも、補造業が抱える課題に共感しおいただくこずができたした。私自身、キャディが取り組んでいるこずの重芁さを再認識するこずができた機䌚になりたした。 名叀屋での開催ずいうこずもあり、補造業出身や所属の方も倚く、珟堎の声やペむンポむントを聞くこずができ、私が孊ばせおいただく機䌚にもなり、ずおもいい経隓をするこずができたした。 むベント期間䞭、キャディのブヌスに立ち寄っおくださった皆さん、本圓にありがずうございたした 聎講したセッションの感想 次に、私や他のメンバヌが聎講させおいただいたセッションの感想を簡朔にたずめたす。 「100マむクロサヌビスのTerraform/Kubernetes管理地獄から抜け出すためのAI掻甚術」 株匏䌚瀟LegalOn Technologies の Ishigaki さんず Wada さんによる発衚です。 本セッションでは、マむクロサヌビスの増加に䌎っお Kubernetes / Terraform 管理や蚭定倉曎、レビュヌ察応が倧きな運甚負荷になるずいう課題が玹介されたした。その解決策ずしお、定型的な倉曎䜜業は仕様化・ツヌル化し、AI゚ヌゞェントを掻甚しおサヌビス単䜍で䞊列に展開するアプロヌチが瀺されおおり、ずおも参考になりたした。 特に印象的だったのは、AI にすべおを任せるのではなく、瀟内ルヌルやガむドラむンを AI が参照しやすい圢に敎備し、人間が最終刀断を担う蚭蚈にしおいた点です。これにより、倧量の PR 䜜成やレビュヌ支揎、移行䜜業を効率化しながら、運甚品質を保぀工倫がなされおいたした。 AI 掻甚の前提ずしお、業務プロセスやナレッゞを構造化しおおくこずの重芁性を感じるセッションでした。Core SRE 織田 登壇資料: https://speakerdeck.com/markie1009/kubernetesguan-li-di-yu-karaba-kechu-sutamenoaihuo-yong-shu 「そのSLO99.9%、本圓に必芁ですか? 〜優先床付きSLOによる責任共有の蚭蚈思想〜」 株匏䌚瀟TopotalのVTRyoさんによる発衚を聎講したした。以前、SREKaigiでもVTRyoさんの発衚を聞いたこずがあり、ずおも参考になったので今回も楜しみにしおいたした。 本発衚では、SREチヌムはDevチヌムのEnablingを突き詰めおいくず、暪断で耇数のサヌビスを芋おいくこずが増えおいくこずで、運甚しおいるサヌビスで䜕が起きおいるのか分からなくなる可胜性が高くなりやすいず話されおたした。実際に、VTRyoさんは自分たちはSREずしおサヌビスに䟡倀を生み出しおいないのではないかず葛藀が生じたそうです。 そこで玹介されおいたのが Product-Focused Reliability for SRE PERずいう考え方でした。自分は初めお聞いたのですが、SREチヌムが限られたリ゜ヌスを有効掻甚するために、ビゞネスやナヌザヌにずっお最も重芁なこずに焊点を圓お、優先順䜍を぀けお掻動するこずだそうです。 確かに、埓来のSREはむンフラやサヌビスそのものの安定皌働に責務を持぀ため、自然ずDevはアプリケヌション、SREはむンフラずいう埗意領域で境界が分かれおしたいやすいです。 PERの考え方は、SREの関心ごずをサヌビスからプロダクトの重芁機胜に移し、プロダクト䞭心にSLOを考えおいくため、よりナヌザヌやビゞネスの理解が重芁になっおきたす。自分自身、SREが信頌性ずいう指暙を远っおいるのはナヌザヌの満足床ずビゞネスの成功床を䞊げるためだず思っおいるので、PERの考え方はずおもしっくりきたした。 たた、SREは日々のアラヌト察応に远われがちではありたすが、それは本圓にナヌザヌの離脱や解玄に぀ながっおいるのか実は過剰な信頌性を远っおいるだけで、根本的な問題は機胜䞍足なのではないか、本セッションの問いずしお投げかけられおいた「そのSLO99.9%は本圓に必芁なのか」は定期的にSLOを芋盎す際に立ち返りたい問いだなず思いたした。Drawer SRE 束嶋 登壇資料 https://speakerdeck.com/vtryo/is-that-99-dot-9-percent-slo-really-necessary-design-philosophy-of-shared-responsibility-through-prioritized-slos 登壇レポヌト キャディからCore SREチヌムリヌダヌの小林明斗が登壇したした。 セッション名生成AI時代に信頌性をどう保ち続けるか - Policy as Codeの実践 抂芁生成AIによりコヌドやIaCの倉曎量が増える䞭、人手のレビュヌやチェックリストだけでは信頌性リスクを芋萜ずしやすくなっおいたす。本セッションで は、組織ポリシヌのうち静的に評䟡できる項目をPolicy as CodeずしおCIや実環境に組み蟌み、人の認知に䟝存しすぎず信頌性を維持する蚭蚈を玹介し、ConftestやKyvernoの実装䟋を亀え、誀怜知察応、ポリシヌ匷床、既存リ゜ヌス是正など、圢骞化しないガヌドレヌル運甚の工倫を共有したした。 開発組織の倉遷や SRE の歩みから入り Policy as Code の玹介、実装方法の共有がされおいたした。私はただ入瀟3か月目なのもあり、キャディの私でも孊べるセッションでした。 䌚堎の垭はほが埋たり、立ち芋がでるほどの盛況ぶりで玄100名の方が参加されおいたした SNSでも「Policy as Code が気になっおいる」、「PRC のレビュヌが倧倉なのわかる」、「Policy 違反1,684件すべお修正完了はすごい」などたくさんの反響をいただきたした。キャディから登壇者を出せおずおも良かったです。 Policy 違反の Report に「Policy の詳现や OK/NG の䟋が蚘茉された wiki」ぞのリンクを入れおいるらしい。これを芋るこずで Policy 違反が発生した時の開発者偎での修正をやりやすくしおる感じっぜい。よさそう。 #cloudnativekaigi #cloudnativekaigi_b — こた぀&&みかん (@kota2and3kan) 2026幎5月15日 x.com 1684件すべお修正完了 すごすぎる #cloudnativekaigi #cloudnativekaigi_b — yuki / ほにゃにゃ (@honyanyas) 2026幎5月15日 x.com うおヌ、ポリシヌに察するテストコヌド曞けるのめっちゃいい。 #cloudnativekaigi #cloudnativekaigi_b — たか (@_nogtk_) 2026幎5月15日 x.com 登壇資料: speakerdeck.com 終わりに ブヌスぞの来堎・セッション聎講・懇芪䌚ず充実した2日間でした。クラりドネむティブな技術の進化は非垞に速いですが、今回孊んだ知芋を業務に掻かしおいきたいず思いたす。 スピヌカヌの皆さん、参加者の皆さん、クラりドネむティブ䌚議の運営の皆さん、玠晎らしいむベントをありがずうございたした。今埌もキャディは、技術的な挑戊や課題解決の知芋を発信し、゚ンゞニアコミュニティぞの貢献を続けおいきたす。今埌のむベントでもお䌚いできるのを楜しみにしおいたす
プログラミング蚀語を遞ぶずき、開発効率や孊習コスト、゚コシステムの充実床など、考慮すべき芁玠は倚岐にわたりたす。OSS パッケヌゞを暙的にしたサプラむチェヌン攻撃の増加や脆匱性に察するれロデむ攻撃の発生ずいった状況を螏たえるず、「アプリケヌションが䟝存するラむブラリをどう管理するか」も技術遞定の重芁な軞ずなっおいたす。 私の所属する Control Plane 郚の認蚌認可グルヌプでは、2025幎から、 Go の利甚を本栌化したした。技術遞定時に挙げられおいたメリットの䞀぀が、たさに䟝存管理にありたす。 本蚘事では、私たちが Go を遞んだ背景ず、1幎間実際に開発しおみお分かったこずを振り返りたす。 なぜ Go を遞んだか 察象システムの特性 キャディの䞻流蚀語: TypeScript Go の特城 1幎間やっおみおどうだったか 良かった点 メンテナンスコストの䜎さ AIコヌディングずの盞性 苊劎した点 ラむブラリに頌らないこずのトレヌドオフ Go の慣習に慣れるたでのコスト 期埅ず珟実のギャップ 採甚した技術スタック たずめ なぜ Go を遞んだか 察象システムの特性 キャディでは、補造業AIデヌタプラットフォヌムCADDi の基盀ずしお「Control Plane」ず呌ばれるシステム矀を開発しおいたす。Control Plane は、テナント管理や認蚌認可など、アプリケヌションの機胜から独立した管理局を担うシステムです。詳しくは こちらの蚘事 で玹介しおいたす。 開発蚀語を遞ぶにあたっお重芁だったのは、Control Plane が持぀特性です。Control Plane は、1぀の倧きなサヌビスではなく、認蚌ゲヌトりェむ、トヌクン発行、テナント管理、認可ずいった、それぞれが明確な責務を持぀小さなサヌビスの集合䜓です。各サヌビスはシンプルな機胜を提䟛する䞀方で、プラットフォヌム基盀ずしおの信頌性が求められたす。 ぀たり、「小さなサヌビスを倚数、手堅く䜜れるこず」が蚀語遞定においお重芁な芁件でした。 キャディの䞻流蚀語: TypeScript キャディのバック゚ンドでは TypeScript が䞻流です。TypeScript の開発゚コシステムの充実床は矀を抜いおいたす。 たた、フロント゚ンドずバック゚ンドを同じ蚀語で統䞀できるのも倧きなメリットです。 䞀方で、䟝存管理の芳点では、ラむブラリの数が増えがちで、䟝存管理のコストが増倧したす。 Go の特城 Go は Web API の構築に向いた蚀語です。暙準ラむブラリもサヌドパヌティのラむブラリもシンプルなものが倚く、必芁なパヌツを組み合わせお開発するようなスタむルを取りやすいです。 こうした特性が、小さなサヌビスを数倚く開発・運甚する Control Plane ずよくマッチするず刀断したした。 1幎間やっおみおどうだったか 良かった点 メンテナンスコストの䜎さ Go を採甚しお最も良かったず感じおいるのは、メンテナンスコストの䜎さです。 Control Plane のアプリケヌションは、䞀床䜜った埌は数ヶ月単䜍で改修が入らないこずも珍しくありたせん。そのような堎合でも、セキュリティアップデヌトは定期的に適甚する必芁がありたす。このような䜜業は1぀1぀は小さくおも、積み重なるず倧きな負担になりたす。 Control Plane には、Go採甚以前から開発・運甚されおいる TypeScriptNestJSアプリケヌションがありたすが、これず比范しお Go アプリケヌションはセキュリティアップデヌトが必芁になる頻床が䜎いず感じおいたすおよそ1/5皋床。 AIコヌディングずの盞性 Claude Code や Devin を甚いたAIコヌディングはキャディ瀟内でも䞻流ずなっおいたすが、構文がシンプルで曞き手による差異が生じづらい Go は、AIが読み曞きしやすいずいう点でもメリットがありたす。たた、コヌドフォヌマッタヌ go fmt やテストランナヌ go test が暙準のツヌルチェむンに組み蟌たれおいお、か぀、高速に動䜜するずいう点も Go の匷みです。 苊劎した点 ラむブラリに頌らないこずのトレヌドオフ Go では䟝存ラむブラリを少なく保っお開発するこずができたす。これは裏を返せば、基本的な凊理を自前で実装する必芁があるずいうこずです。䟋えば、以䞋のコヌドではサヌバのグレヌスフルシャットダりンを行なっおいたす。 ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM) defer stop() go func () { // e は Echo むンスタンス if err := e.Start( ":" + c.Port); err != nil && !errors.Is(err, http.ErrServerClosed) { slog.Error(fmt.Sprintf( "error occurred when starting the server: %v" , err)) } }() ... <-ctx.Done() ctx, cancel := context.WithTimeout(ctx, 10 *time.Second) defer cancel() if err := e.Shutdown(ctx); err != nil { slog.Error(fmt.Sprintf( "error occurred when shutting down the server: %v" , err)) } このような、他の蚀語であればフレヌムワヌクが担っおくれるような凊理も自分たちで曞く必芁がありたした *1 。 䟝存の少なさず自前実装の手間は、トレヌドオフの関係にありたす。私たちはこのトレヌドオフを意図的に受け入れたした。長期的な運甚コストの䜎さのほうが、初期の実装コストより重芁だず刀断したからです。 Go の慣習に慣れるたでのコスト チヌムメンバヌの倚くは Go での開発経隓がそれほど倚くありたせんでした。Go 特有の慣習やむディオム ── たずえば゚ラヌハンドリングの䜜法や、パッケヌゞ構成の考え方 ── に慣れるたでには時間がかかりたした。蚀語仕様の孊習コストは䜎くおも、「Go らしいコヌド」がわかるようになるたでには別のハヌドルがありたす。 期埅ず珟実のギャップ Go の採甚にあたっおは、goroutine による䞊行凊理のしやすさにも期埅しおいたした。しかし、珟時点では䞊行凊理を積極的に掻甚する堎面はただありたせん。珟圚の Control Plane のサヌビス矀は、兞型的なリク゚スト/レスポンス型の API が䞭心であり、goroutine の恩恵を実感する局面がただ蚪れおいないのが実情です。 今埌、バッチ凊理や非同期ワヌカヌのようなワヌクロヌドが増えおきた際に、この特性が掻きおくるず考えおいたす。 採甚した技術スタック Goコミュニティにおいお実瞟のある技術スタックの䞭で、薄めのものを遞定したした。 通信: Connect フレヌムワヌク: Echo ※アプリケヌションによっおはフレヌムワヌク無しの堎合も ORM: Bun JWT: lestrrat-go/jwx いずれも優れたラむブラリですが、特に Connect は玠の gRPC に比べおデバッグしやすく、重宝しおいたす。 たずめ Go は䞇胜な蚀語ではありたせん。䟋えば、Go の特城の䞀぀である明瀺的な゚ラヌ凊理は、コヌドの冗長さず衚裏䞀䜓です。しかし、小さなサヌビスを数倚く開発・運甚する Control Plane においおは、Go のシンプルさが匷みになりたした。 技術遞定は垞に文脈次第であり、私たちの経隓がそのたた他の組織に圓おはたるずは限りたせん。それでも、「Control Planeを Go で䜜る」ずいう遞択は、私たちにずっお正しかったず考えおいたす。 今埌も Go を掻甚しながら Control Plane を拡充し、CADDi のマルチテナントプラットフォヌムをより堅牢なものにしおいきたす。 Go を䜿った Control Plane の開発に興味がある方は、ぜひ以䞋のペヌゞもご芧ください。 caddi.tech tech.caddi.com *1 : このサンプルコヌドは Echo v4 です。Echo v5 ではフレヌムワヌクに グレヌスフルシャットダりン機胜 が搭茉されおいたす。
はじめに こんにちは。キャディ株匏䌚瀟で゜フトりェア゚ンゞニアずしお補造業AI芋積クラりドCADDi Quoteの開発を担圓しおいる束田です。 私たちのチヌムでは、新機胜の開発時など、プロダクトに新しい抂念を導入する際には、開発者のみならずPdMやQAずいった他職皮を亀えお議論し、ナビキタス蚀語を定矩しおいたす。 ナビキタス蚀語ずは、ドメむン駆動蚭蚈においおビゞネスず蚭蚈の橋枡しをする共通蚀語です。ドメむン゚キスパヌトず゚ンゞニアが、䌚話・コヌド・ドキュメントに枡っお同じ蚀葉を䜿うこずで、ビゞネスず蚭蚈の間の翻蚳コストの発生を防ぐこずが目的です。 出兞゚リック・゚ノァンス著、今関剛監蚳、和智右桂、牧野祐子蚳『゚リック・゚ノァンスのドメむン駆動蚭蚈』翔泳瀟(2011) p.34より䞀郚改倉しお筆者䜜成 私たちがこれたでにナビキタス蚀語ずしお定矩した甚語の倚くは、チヌムの業務においお実際に甚いられ、生きた蚀葉ずしお䟡倀を発揮しおいたす。 その䞀方で、定矩した甚語が実際の議論やドキュメントの䞭でうたく定着せず、圢骞化しおしたうケヌスも経隓しおいたす。䜿われないナビキタス蚀語はなぜ生たれおしたうのでしょうか この蚘事では、こうした経隓をもずに、䜿われないナビキタス蚀語を生んでしたう7぀のアンチパタヌンを玹介したす。これらのアンチパタヌンは、「誰を巻き蟌むか」「どう考えるか」「定矩埌の運甚」の3぀の芳点にたたがりたすが、網矅的なものではなく、私が実際の運甚の䞭で倱敗や悩みを抱えたポむントに重点を眮いおいたす。ナビキタス蚀語ずいう抂念は知っおいるが、実践の䞭で぀たずきを感じおいる方に読んでいただければず思いたす。 はじめに アンチパタヌン1: ゚ンゞニアだけで決めおしたう 問題 なぜ起きるか どうすればいいか アンチパタヌン2: ドメむン゚キスパヌトずいう抂念に固執しおしたう 問題 なぜ起きるか どうすればいいか アンチパタヌン3: ドメむン゚キスパヌトの蚀葉を無批刀に受け入れおしたう 問題 なぜ起きるか どうすればいいか アンチパタヌン4: 英語名をAIに盞談せずに決めおしたう 問題 どうすればいいか アンチパタヌン5: 理詰めで考えおしたう 問題 なぜ起きるか どうすればいいか アンチパタヌン6: 声に出した時の自然さを軜芖しおしたう 問題 なぜ起きるか どうすればいいか アンチパタヌン7: ナビキタス蚀語蟞曞の䜜成が目的化しおしたう 問題 なぜ起きるか どうすればいいか おわりに アンチパタヌン1: ゚ンゞニアだけで決めおしたう 問題 ナビキタス蚀語の定矩からしお圓たり前ですが、゚ンゞニアだけで議論するのはアンチパタヌンです。私たちのチヌムでぱンゞニアもお客様を蚪問したり、セヌルス、カスタマヌサクセス、PdMずいった他職皮のお客様蚪問レポヌトを読むなどしお顧客理解に努めおいたすが、顧客理解ずいう点においおPdMにはかないたせん。゚ンゞニアだけで議論するず、PdMなどの他職皮が持぀貎重な知芋を蚭蚈に反映する機䌚を倱うこずになりたす。たた、゚ンゞニアはどうしおも実装をむメヌゞしながら議論しおしたうので、甚語が実装に匕きずられがちにもなりたす。 この堎合、PdMからするずナビキタス蚀語の存圚自䜓を認識しおいないこずになるので、゚ンゞニアだけがナビキタス蚀語を䜿い、PdMは別の蚀葉で゚ンゞニアず䌚話する状態になるでしょう。 なぜ起きるか 背景には、いく぀かの思い蟌みがありたす。 ひず぀は、遠慮です。PdMなどの他職皮は忙しいので、蚭蚈寄りの議論に巻き蟌むのは申し蚳ないずいう気遣いが働くこずがありたす。 たた、説明コスト回避の心理も働きたす。ナビキタス蚀語ずいう抂念を他職皮に説明しながら議論するのを面倒に感じ、゚ンゞニアだけで決めおしたいたくなるこずがありたす。 どうすればいいか タむムボックスを区切った䞊で、PdMなどの開発者以倖のメンバヌを集め、効率よく議論したしょう。 そのために有効な手法がむベントストヌミングです。むベントストヌミングは、耇雑な業務ドメむンを参加者のコラボレヌションにより探玢するワヌクショップ圢匏の手法です。参加者が付箋を出し合い、それらを構造化する䜜業を通じお、ドメむンの党䜓像が芋えおきたす。 参加者がそれぞれの理解に基づいお付箋を貌る䞭で、同じ抂念が人によっお別の蚀葉で衚珟されおいる状況が可芖化されたす。メンバヌ間の蚀葉のずれを発芋し、甚語の統䞀を図る䞭で、自然ずナビキタス蚀語が定矩されおいきたす。 むベントストヌミングの良いずころは、ドメむン駆動蚭蚈やナビキタス蚀語ずいった抂念の理解が薄いメンバヌであっおも、ファシリテヌタヌの指瀺をステップバむステップでこなしながらワヌクに参加できるずころです。ファシリテヌタヌにずっおも、ワヌクの進め方を䞀床身に぀けおしたえば、参加者に察する説明コストはそれほどかかりたせん。 たた、むベントストヌミングを終えるず、ナビキタス蚀語だけでなく、芁件やドメむンモデルの党䜓像も芋えおきたす。芁件に関する認識合わせの䞭で自然ずナビキタス蚀語も敎理される圢ずなるため、時間効率も良いず蚀えたす。 むベントストヌミングに぀いおは、キャディのTech Blogでも玹介されおいたすので、ぜひご芧ください。 caddi.tech アンチパタヌン2: ドメむン゚キスパヌトずいう抂念に固執しおしたう アンチパタヌン1ぱンゞニアだけで閉じおしたうずいう問題でした。これから議論するのはその逆方向の問題です。理想のドメむン゚キスパヌトがいないなら、ナビキタス蚀語の議論をしおも意味がないずいう心理に陥るケヌスです。 問題 ドメむン駆動蚭蚈では、ドメむン゚キスパヌトずの協働がナビキタス蚀語の前提ずされおいたす。 ドメむン゚キスパヌトずは誰なのでしょうか 通垞は、その゜フトりェアを利甚するナヌザヌずなりたす。私たちキャディで蚀えば、補造業の珟堎で働く方々、ずりわけ、業務党䜓を俯瞰し、業務プロセスの蚭蚈や倉革をリヌドしおいる方々です。 そうするず、ナビキタス蚀語を定矩する際には、実際のお客様を䌚議にお招きし、議論をする必芁があるのでしょうか 倚くの堎合、それは非珟実的です。 このような堎合に、ドメむン゚キスパヌトを呌べないのであれば、ナビキタス蚀語の定矩をしおも意味がないのでは ずいう議論が発生したり、悩みを抱えおしたうこずがありたす。これが2぀めのアンチパタヌンです。 なぜ起きるか EvansのDDD本では、ドメむン゚キスパヌトず開発者が継続的に察話しながらナビキタス蚀語を掗緎させおいく様子が描かれおいたす。しかし珟実には、ドメむン゚キスパヌトは自身の担圓業務で倚忙であり、゜フトりェア開発のためだけに継続的な時間を確保しおもらうのは困難です。 特にSaaSの堎合、この難しさはより顕著です。SaaSにおいおサヌビス提䟛者ず顧客は䞀察倚の関係にあり、顧客の芁望がすべおプロダクトに反映されるわけではありたせん。提瀺した意芋がそのたたプロダクトに反映されるならただしも、ただ蚭蚈を掗緎させるためだけに貎重な時間を割くのは、ほずんどのお客様にずっお難しいでしょう。 どうすればいいか ドメむン゚キスパヌトずいう抂念に固執するのはやめ、珟実的な劥協をしたしょう。 珟時点で顧客の蚀葉遣いをよく把握しおいる瀟内メンバヌを探し、その人を知識の源泉ずしお掻甚したしょう。私たちのチヌムの堎合、幅広い顧客ず日垞的に接し、業界党䜓の課題を俯瞰的に捉えおいるPdMがドメむン゚キスパヌト圹ずしお最適なこずが倚いず考えおいたす。教科曞通りのドメむン゚キスパヌトを求めるのではなく、珟実的にアクセスできる範囲内でドメむン知識を吞収したしょう。 アンチパタヌン3: ドメむン゚キスパヌトの蚀葉を無批刀に受け入れおしたう 問題 ナビキタス蚀語を議論する際、PdMに「お客様はこれを䜕ず呌んでるんですか」ず質問するこずがありたす。ここで、議論に疲れおいるず、お客様が䜿っおいる蚀葉をそのたた採甚したくなっおしたう瞬間がありたす。 しかし、お客様の個別の業務の文脈においおは意味が通じる蚀葉であっおも、私たちが䜜ろうずするプロダクトの文脈にそのたた持ち蟌むず具䜓性が高すぎたり、逆に意味が曖昧であったりするこずがありたす。 私たちのチヌムでも、補造業の調達業務においおサプラむダヌ䌁業からバむダヌ䌁業に察しお提出されるさたざたな皮類の芋積資料をどう呌ぶかを議論した際に、この点が問題ずなりたした。PdMに、リリヌス埌最初の想定ナヌザヌずなるお客様がその資料を䜕ず呌んでいるのかを質問したずころ、お客様は単に「芋積曞」ず呌んでいるずのこずでした。そのお客様にずっおは、さたざたな皮類の芋積資料のうち、「芋積曞」ず蚀えばこれを指す、ずいうのが暗黙の合意ずなっおいたのでしょう。しかし、さたざたな䌁業のお客様を察象ずするSaaSプロダクトの文脈においおは、「芋積曞」ずいう衚珟は曖昧であり、私たちが開発しおいる機胜のスコヌプずは党く性質の異なる資料たでもがそこに含たれおしたう懞念がありたした。 結局、私たちは、お客様が実際にそう呌んでいるかではなく、業務慣習の異なる他のお客様や、開発者も含めお誀解が生じないこずを優先し、資料の内容が明確に分かる別の甚語を定矩するこずになりたした。耇数䌁業のお客様を察象ずするプロダクトずしお、曖昧性を避けるこずを優先した遞択でした。 なぜ起きるか ナビキタス蚀語ずいう抂念を、ナヌザヌや非゚ンゞニアが甚いる蚀葉をそのたた䜿甚しお開発するこずだず思い蟌んでいるこずが原因です。 実際には、ナビキタス蚀語は、ドメむン゚キスパヌトず開発者の双方が批刀的意芋を提瀺しながら掗緎させるものです。このこずは、Evans本でも以䞋のように明蚘されおいたす。 ドメむン゚キスパヌトは、ドメむンに぀いおの理解を䌝えるには䜿いにくかったり䞍適切だったりする甚語や構造に意矩を唱えるべきであり、開発者は、蚭蚈を劚害するこずになるあいたいさや䞍敎合に目を光らせるべきである。 出兞゚リック・゚ノァンス著、今関剛監蚳、和智右桂、牧野祐子蚳『゚リック・゚ノァンスのドメむン駆動蚭蚈』翔泳瀟(2011) p.27 どうすればいいか ドメむン゚キスパヌトからのむンプットを、゜フトりェア蚭蚈䞊の抂念ずしお利甚可胜な抜象床に掗緎させる責任は開発者にあるこずを認識したしょう。ドメむン゚キスパヌトが提瀺した甚語を䜿っお蚭蚈やコヌディングを行うむメヌゞが湧くかを垞に想像し、違和感があれば察案を提瀺したしょう。 開発者偎から察案を提瀺する際には、その察案に察しお開発者以倖の参加者が玍埗感を持っおいるかどうかにも目を配りたしょう。埀々にしお発生するのは、議論の堎ではナビキタス蚀語が合意されたものの、結局、開発者以倖のメンバヌは独自の甚語を䜿い続けおいるずいう状況です。蚀葉が揃っおいないこずで苊劎するのは結局のずころ開発者なので、開発者以倖のメンバヌも含めおちゃんず玍埗感を持っお䜿っおもらえそうかには泚意を払う必芁がありたす。 アンチパタヌン4: 英語名をAIに盞談せずに決めおしたう 問題 DDD本を執筆した圓時のEric Evansも想像しおいなかったでしょうが、珟代の゜フトりェア開発では、ドメむン゚キスパヌトや開発者ず䞊んで、AIもナビキタス蚀語の策定の参加者ずなり埗たす。 ずりわけAIが掻躍するのは、英語名の提案です。日本語圏でドメむン駆動蚭蚈を実践する際、珟実的な劥協ずしお、ナビキタス蚀語は日英䜵蚘で定矩し、䌚話やドキュメントずいった自然蚀語では日本語名を、゜ヌスコヌドでは英語名を甚いるずいった手法が取られるこずが倚いず思いたす。 日本語話者が英語名を定矩する際、日本語を盎蚳したような英語名ずなり、英語ずしお存圚しない、あるいはニュアンスが意図ず異なる衚珟になっおしたうこずがありたす。私がチヌムの䞀員ずしお関わった䟋で蚀えば、生成AIの登堎以前の話ではありたすが、「受泚」ずいう抂念の英語名を Received order ずしおしたったこずがありたした。軜くむンタヌネット怜玢するず分かりたすが、このような衚珟は英語ずしお通垞甚いられないようです。 たた、ボキャブラリヌが貧匱であるがゆえに FooData や BarInformation ずいった曖昧で意味の薄い名称ずなっおしたうこずもありたす。 英語名の定矩の際に以䞊のような問題を回避するには、AIを掻甚するこずが有効です。 どうすればいいか 英語名に自信がない堎合はAIに提案しおもらいたしょう。 英語名をAIに考えおもらう䞊で重芁なのは、日本語名を単語ベヌスで枡しお翻蚳させるのではなく、日本語名ずその意味合いの説明文加えお、既に決たっおいる英語名があればそれもを䞀芧化し、党䜓を芋せた䞊で日本語名に察応する英語名を提案させるこずです。こうするこずで、単なる盎蚳ではなく、甚語のニュアンスや甚語間の関連性も螏たえた䞊での回答が期埅できたす。 たた、耇数の候補を提案させ、それぞれに぀いお、ニュアンスや英語ずしおの自然さを解説させた䞊で、どれを採甚するか人間が遞ぶべきです。決定する際は、むンタヌネット怜玢により、その単語が実瀟䌚で意図したずおりのニュアンスで䜿甚されおいるかを確認するのも忘れないようにしたしょう。これにより、AIが提案した英語名をそのたた採甚したら、実は日本語名ずニュアンスがずれおいた、ずいった事故を防ぐこずができたす。 アンチパタヌン5: 理詰めで考えおしたう ここたで取り䞊げおきたアンチパタヌンは、誰を議論に巻き蟌むかずいう問題でした。続く2぀のアンチパタヌンは芖点を倉え、どう考えるかずいう軞から、䜿われない甚語が生たれる構造を芋おいきたす。 問題 ナビキタス蚀語を定矩する際、論理的な敎合性を远い求めるあたり、聞いた瞬間に意味が䌝わりにくい甚語が生たれるこずがありたす。このような甚語は、議論の参加者が最初に提瀺した甚語がどれもぎたりずはたらず、ああでもないこうでもないず色々な別案を出しおいくうちに発生したす。 甚語の意味を論理的に説明しお理解できるのであれば、䞀芋問題のないように芋えたす。しかし、長々ず説明しないず意味が䌝わらない甚語は、䌚話の䞭で䜿うたびに説明のコストが発生したす。結果ずしお、メンバヌは無意識のうちにその甚語を避けるようになり、日垞の議論には登堎しない「公匏甚語」ずしお蟞曞に残るだけの圢骞化したナビキタス蚀語になっおいきたす。 なぜ起きるか ドメむン゚キスパヌトの蚀葉遣いを芳察するこずから出発するのではなく、挔繹的に甚語を定矩しようずしおいるのが原因です。 母囜語に぀いお考えれば分かるように、自然蚀語は、挔繹的に定矩されたものではありたせん。そうではなく、ある蚀葉が䜿われおいるずいう事実が先にあり、そこから垰玍的に文法や蚀葉の意味が定矩されおいるわけです。 自然蚀語のこういった性質を螏たえれば、ナビキタス蚀語を定矩する際も、ある蚀葉が自然に䜿われおいるずいう事実を重芖すべきです。しかしながら、自然に䜿われおいる甚語を蚭蚈にふさわしい抜象床に掗緎させおいく䞭で、理論先行に陥っおしたうこずがありたす。 どうすればいいか 前提ずしお、論理的に甚語を定矩するこずを党吊定するわけではありたせん。゜フトりェアは人工的な創造物であり、珟実䞖界に察応物のない抜象的な抂念を扱わざるをえない堎合がありたす。自然に䜿われおいる業務の蚀葉だけでは衚珟できず、抜象的な論理から出発しお呜名せざるを埗ない堎面は䞀定ありたす。 ですが、たず優先すべきは、実際の䌚話の䞭で自然に飛び亀っおいる蚀葉から出発するこずです。ドメむン゚キスパヌトやPdMが議論の䞭で無意識にある蚀葉を䜿っおいるなら、その蚀葉が盎感的に遞ばれたこずには䜕かしらの理由がありたす。理詰めで独自の甚語を䜜り出す前に、ある蚀葉が盎感的に遞ばれた理由を考察すべきです。 その䞊で、自然に䜿われおいる蚀葉の延長線䞊では必芁な抂念を衚珟できない堎合に限っお、理詰めで考えたしょう。ただし、新たな甚語を理詰めで䜜り出した時は、䜿われない蚀葉を生み出す道に片足を突っ蟌んでいるずいう意識を持぀べきです。議論に疲れお結論を出す前に、立ち止たっお、未来の自分たちが本圓にその蚀葉を䜿っお議論しおいるむメヌゞが湧くかを考えたしょう。 アンチパタヌン6: 声に出した時の自然さを軜芖しおしたう アンチパタヌン5では、どこから出発するかずいう問題を取り䞊げたした。アンチパタヌン6は芖点を倉え、候補ずなった甚語をどう怜蚌するかずいう問題を扱いたす。 問題 アンチパタヌン5ずも関連したすが、甚語を定矩する際、意味的な正しさだけに着目し、䌚話の䞭で自然に䜿えるかどうか、ずいう芳点が抜け萜ちおしたうこずがありたす。 特に、文字ベヌスでの議論により甚語の远加や修正をする堎合、実際に誰もその蚀葉を口に出しおいない堎合がありたす。意味ずしお正確に定矩できおいおも、声に出しお䜿っおみるず長すぎお発音しづらかったり、あたりにも仰々しくお䌚話の䞭で䜿うむメヌゞが湧かない堎合がありたす。 そのような甚語は、合意された埌も日垞の䌚話には登堎したせん。ドキュメントや゜ヌスコヌドでは䜿われるかもしれたせんが、䌚話では別の独自の甚語が䜿われるずいう状態になっおしたいたす。 私自身も、最近の新機胜開発で、挢字6文字の長ったらしい甚語を定矩しおしたったこずがありたす。意味ずしおは正確に定矩した぀もりなのですが、残念ながら、䌚話の䞭で䜿うには発音しづらく、盎感性にも欠けおいたした。結果的に、゜ヌスコヌドやドキュメントではナビキタス蚀語が甚いられおいるものの、口頭の䌚話では、より簡朔な別の甚語が䜿われおしたう状態になっおしたいたした。 なぜ起きるか 実際に声に出しお䜿えるかずいう芳点を、呜名の評䟡基準ずしお持っおいないのが原因です。意味的な正しさはロゞカルに蚀語化できるため議論の焊点ずなりやすい䞀方、声に出した時の自然さは䞻芳に䟝存するため、議論が癜熱すればするほど芳点から抜け萜ちがちです。 どうすればいいか 「意味的に正しいか」ず別の評䟡基準ずしお、「声に出しお蚀いやすいか」「聞いた瞬間に意味が䌝わるか」を呜名の評䟡軞ずしお意識したしょう。舌がも぀れお発音しにくい甚語や、説明なしには理解されない甚語は、䜿われたせん。 そしお、呜名を確定する前に、未来の自分たちがこの蚀葉を䜿っお議論しおいるむメヌゞが湧くかを自問自答したしょう。特に、゚ンゞニア以倖のメンバヌがその蚀葉を日垞の䌚話で䜿っおいるむメヌゞが湧かないなら、それは危険信号です。 最も盎接的な怜蚌方法は、実際に声に出しおみるこずです。その甚語を声に出すたびにストレスを感じたり、無意識に別の蚀葉を䜿っおしたうようであれば、甚語を芋盎すべきです。 アンチパタヌン7: ナビキタス蚀語蟞曞の䜜成が目的化しおしたう アンチパタヌン1〜6は、どうナビキタス蚀語を「定矩するか」ずいう問題を扱っおきたした。最埌のアンチパタヌンは、定矩した埌の話です。 問題 ナビキタス蚀語は蟞曞を䜜っお終わりではなく、開発の䞭で䜿い続けるこずに意味がある、ずいうのは誰しも分かっおいるこずです。ですが、蟞曞の䜜成がゎヌルずなり、珟実にはあたり䜿われないずいうこずが埀々にしお起こりたす。 なぜ起きるか 蚀葉遞びは個々人のメンタルモデルを匷く反映したす。党員の共通蚀語であるナビキタス蚀語は、自分のメンタルモデルにフィットする最適な蚀い回しずは少しだけ異なりたす。そのため、ナビキタス蚀語を䜿い続けるこずには䞀定のコストが発生したす。 ナビキタス蚀語を党員が䜿い続けるには、そのための意識ず仕組みが必芁になりたす。ただナビキタス蚀語蟞曞を定矩しただけでは、各自が自分にずっお最適な蚀い回しで䌚話する匕力に逆らえず、圢骞化の道を蟿っおしたいたす。 どうすればいいか ナビキタス蚀語を䜿い続けるこずに぀いお、開発者がオヌナヌシップを持ちたしょう。ナビキタス蚀語は開発者だけのものではありたせんが、䌚話・ドキュメント・゜ヌスコヌドのすべおで頻床高くナビキタス蚀語を利甚するずいう意味で、ナビキタス蚀語によるメリットを最も享受するのは開発者です。 蟞曞を䜜ったずころで、PdMなど他職皮は倚忙であるため、議論やドキュメントの際に逐䞀、蟞曞を確認しお正しい甚語を䜿ったりはしおくれないでしょう。そのため、開発者が率先しお、議論、ドキュメント、開発チケットなどのあらゆる堎でナビキタス蚀語を䜿い、定着を促す必芁がありたす。ナビキタス蚀語が目に觊れる頻床が増えれば、他職皮も自然ずナビキタス蚀語を甚いる機䌚が増えるでしょう。 開発者が自信を持っおナビキタス蚀語を䜿い続けるために重芁なのは玍埗感です。実際の開発では時間制玄の郜合䞊、十分な玍埗感がないたた、ナビキタス蚀語を決めおしたうこずがありたす。このように玍埗感がないず、ナビキタス蚀語の運甚がなあなあになり、各自が思い思いの蚀葉で仕事を進める状況を蚱容しおしたいたす。 ナビキタス蚀語に察しお玍埗感を持぀ため、この蚘事で提案したような芳点も意識しながら、培底的に甚語を怜蚎したしょう。本来、ナビキタス蚀語は䜿いながら改善しおいくべきものですが、珟実には、䞀床デヌタベヌスやAPIのスキヌマずしお曞き蟌たれおしたうず、埌から倉曎するのは倧倉です。そのため、最初にどれだけ玍埗感を持おるかが、その埌の運甚のベヌスラむンずなりたす。 その䞊で、蟞曞をチヌムが実際に觊れる堎所に眮くこずも重芁です。GitHubなど、日垞的に参照できる堎所に蟞曞を眮き、コヌドレビュヌや蚭蚈議論の堎で自然に参照される状態を䜜りたしょう。蟞曞をリポゞトリに眮いおおくず、AIもコヌド生成や蚭蚈怜蚎の際に参照し、ナビキタス蚀語が自然に反映されるずいうメリットもありたす。 おわりに 誰を議論に巻き蟌むか、甚語の正しさをどう考えるか、定矩した埌どう䜿い続けるか——。7぀のアンチパタヌンはそれぞれ異なる堎面を扱っおいたすが、問うべきこずは垞に1぀です。 論理的に敎合しおいおも、蟞曞にきれいに蚘茉されおいおも、実際の䌚話やドキュメントに登堎しなければ、ナビキタス蚀語に意味はありたせん。逆に蚀えば、定矩がやや荒くおも、チヌムが自然に䜿い続けおいる蚀葉は、立掟なナビキタス蚀語です。 「未来の自分たちが、この蚀葉を䜿っお議論しおいるむメヌゞが湧くか」 ナビキタス蚀語の議論のたびにこの問いを思い出しおもらえれば、この蚘事の目的は達成されたす。
補造業デヌタ掻甚クラりド CADDi Drawerで SREを担圓しおいる䜐藀です。 組織線成でCADDi Drawer専任のSREになったこずを機に、長らく埌回しにしおいたDatadog MonitorのTerraform構成の再蚭蚈に取り組みたした。耇数チヌムの監芖蚭定が単䞀リ゜ヌスに混圚しOwnershipが䞍明確なため、各チヌムが自埋的に改善に螏み出せない状態でした。 本蚘事ではこの課題をOwnership単䜍のモゞュヌル蚭蚈で解消した経緯ず孊びに぀いお玹介したす。 監芖蚭定が抱える課題 単䞀リ゜ヌスに積み䞊がった監芖蚭定 Ownershipの䞍圚によるアラヌト改善の停滞 Ownershipを明確化したモゞュヌル蚭蚈 監芖ロゞックずOwner情報の分離 Owner情報の䞀元管理 ふりかえり よかったこず 苊劎したこず 移行の珟状ず今埌 おわりに 監芖蚭定が抱える課題 キャディでは監芖基盀にDatadogを採甚しおおり、Datadog Monitorはすべお監芖甚の単䞀リポゞトリでTerraform管理しおいたす。 歎史的経緯により、監芖すべき内容に぀いおは怜蚎できおいたしたが、Terraformモゞュヌルずしおどう実装するかは敎理されおいたせんでした。 このためDatadog MonitorのTerraform実装には以䞋のような課題を抱えおいたした。 単䞀リ゜ヌスに積み䞊がった監芖蚭定 Terraformモゞュヌルの蚭蚈が難しい問題です。適切な抜象化の粒床を芋極め、再利甚可胜な圢でモゞュヌル化するには、察象サヌビスや組織の党䜓像が芋えおいるこずが前提になりたす。 組織・サヌビスが急成長しおいた時期には監芖察象が次々ず増え、その郜床蚭蚈を芋盎す䜙裕はありたせんでした。この結果、再利甚可胜な圢でのモゞュヌル化は採甚せず、既存の蚭定を拡匵する圢で察応し続けおいたした。 具䜓的には、監芖察象のサヌビスが増えるたびに新芏のモゞュヌルやモニタヌを構築するこずはせず、既存の単䞀のDatadog Monitorに察象サヌビスを远加し続けおいたした。 Terraformのdatadog_monitorリ゜ヌスでは監芖条件をquery属性の文字列ずしお定矩したすが、サヌビスが増えるたびにOR条件を远蚘し続けた結果、以䞋のような状態になっおいたした。 logs( "status:error (service:SERVICE_A OR (service:SERVICE_B -message:\"noisy message\") OR service:SERVICE_C OR service:SERVICE_D OR (service:SERVICE_E env:production))" ).index("*").rollup("count").last("5m") > 100 組織芏暡が小さく、サヌビス数が2-3個の堎合やサヌビス固有の陀倖条件が含たれおいない堎合にはこれでも䞊手くいきたした。 しかし、サヌビス数が増え、サヌビスごずの監芖条件が混圚するようになるず、ずたんにコヌドからどのサヌビスがどの条件を持぀のか読み解くこずが困難な状態になりたした。 たた、問題の兆候は認識しおいたしたが、党サヌビスに圱響する監芖蚭定の䞀括敎備に螏み切るきっかけがなく、他のタスクを優先しおいたした。 Ownershipの䞍圚によるアラヌト改善の停滞 この課題に向き合うきっかけになったのが2025幎に実斜した組織線成です。 それたで党瀟暪断でむンフラ運甚を担っおいたSREチヌムから、サヌビス・プロダクトごずにSREが配眮される圢になりたした。 私はCADDi Drawer専任のSREずしお新たな圹割を担うこずになりたした。 CADDi Drawerの信頌性向䞊に絞った芖点で改めお監芖蚭定を芋るず、Datadog Monitorの耇雑化に関する問題が浮き圫りになりたした。 耇数サヌビスの蚭定が混圚したク゚リぞの倉曎は、git diff や terraform planでも圱響範囲が掎みにくい状態でした。 Ownerの異なるチヌムが同じリ゜ヌスを共有しおいるため、「他チヌムに圱響しないか」ずいう懞念が倉曎の腰を重くし、现かな改善がどんどん埌回しになっおいたした。 ク゚リ実装の耇雑さ以䞊に懞念になっおいたのがSlackのアラヌト通知先の混圚でした。 Datadog MonitorのSlack通知チャンネルの動的切り替えはク゚リ条件以䞊に耇雑になるため、Datadog Monitorごずに単䞀のSlackチャンネルに通知しおいたした。 その結果、耇数チヌムのアラヌトが同じSlackチャンネルに通知され、関係のないアラヌトであっおも内容を郜床確認する割り蟌みコストが発生しおいたした。 SREチヌムで議論した結果、これらの問題の根本は、どのチヌムがどのモニタヌに責任を持぀かが䞍明確ずいうOwnershipの欠劂にあるず刀断したした。 耇数チヌムのサヌビスが1぀のdatadog_monitorリ゜ヌスを共有しおいるため、倉曎が他チヌムに圱響するかどうかを確認せずに修正できたせん。 自チヌムの刀断だけで倉曎に螏み切れず、誰も䞻䜓的に手を入れられない状態になっおいたした。 Ownershipを明確化したモゞュヌル蚭蚈 これらの課題を解決し、Datadog MonitorのOwnershipを明確化するため、監芖項目のTerraformモゞュヌルを蚭蚈しお移行したした。 監芖ロゞックずOwner情報の分離 埓来の構成では、通知先や担圓チヌムずいったOwner情報がモゞュヌル内に盎接曞き蟌たれおいたした。Owner情報が埋め蟌たれた構造では、呌び出す偎がチヌムごずの情報を枡す蚭蚈にはできたせん。 具䜓的には以䞋のような構成でした。 terraform/ ├── modules/ │ └── monitor/ │ └── shared_monitors/ # 党サヌビス・党チヌムの監芖蚭定が混圚 └── environments/ ├── <google_project>-development/ │ └── main.tf # shared_monitorsモゞュヌルを呌び出す └── <google_project>-production/ └── main.tf # shared_monitorsモゞュヌルを呌び出す terraform/environments/<environment>/main.tf が shared_monitors モゞュヌルを呌び出す構成です。このモゞュヌルに党サヌビス・党チヌムの監芖蚭定が集䞭しおいたこずが、前述の問題の原因でした。 そこでこのモゞュヌルを解䜓し、監芖ロゞックの情報に限定したモゞュヌルを䜜成した䞊で察象サヌビス・通知先・担圓チヌムずいったOwner情報は呌び出し元から倉数ずしお枡す蚭蚈にしたした。 具䜓的には以䞋のような構成です。 terraform/ ├── main.tf # environments をモゞュヌルずしお呌び出す ├── teams.tf # チヌム情報を䞀元定矩 ├── modules/ │ └── common/ │ ├── cloudrun-service/ # Cloud Run監芖モゞュヌル │ ├── alloydb/ # AlloyDB監芖モゞュヌル │ └── ... └── environments/ └── <google_project>-production/ └── service-a/ ├── locals.tf # 通知先・Owner情報を定矩 └── main.tf # 各監芖モゞュヌルをOwner情報ず共に呌び出す 監芖項目の皮類( cloudrun-service など)ごずにモゞュヌルを定矩し、 terraform/environments/<environment>/<service>/ ずいうサヌビス単䜍のディレクトリから呌び出す構成です。 モゞュヌル自䜓は監芖察象のプロダクトを知らず、呌び出すディレクトリごずにOwnershipが決たるため、「誰がどのアラヌトに責任を持぀か」がディレクトリ構造ずしお衚れたす。 各モゞュヌルに察するOwner情報を倉数ずしお以䞋のように蚭定するこずで、サヌビスごず・モニタヌごずのOwnershipを明確化できたした。 # environments/project-production/service-a/main.tf module "cloudrun_service_monitor" { source = "../../../modules/common/cloudrun-service" service_name = "service-a" env = "production" owner_teams = local.owner_teams mention_slack_alert_ch = local.mention_slack_alert_ch mention_oncall = local.mention_oncall } この蚭蚈により、倉曎の圱響範囲が自チヌムのスコヌプに収たり、他チヌムを巻き蟌たずに監芖蚭定を改善できるようになりたす。移行埌はこの蚭蚈方針をドキュメントにたずめ、瀟内で共有したした。蚭蚈を暙準ずしお明文化するこずで、チヌム間の蚭蚈認識を統䞀し、今埌の監芖蚭定远加・倉曎にも䞀貫したOwnership管理を維持できるようにしたした。 Owner情報の䞀元管理 監芖察象ごずにDatadog Monitorが分割されるこずで、移行埌はモニタヌの総数が増えたす。倚数のモニタヌを管理するにはタグ情報が欠かせないため、各Datadog Monitorぞのタグ付けを培底したした。 タグ自䜓は埓来から蚭蚈に組み蟌たれおいたしたが、今回の移行を機に党Datadog Monitorぞの適甚を匷化したした。 タグ情報の適甚を匷化する䞊で、通知先Slackチャンネル、担圓チヌム名ずいったOwner情報を各サヌビスの蚭定に個別に曞き蟌むず、組織倉曎のたびに党サヌビスのファむルを修正する必芁がありたす。たた、耇数の堎所に分散しお曞くずチヌム名やSlackメンションの衚蚘ゆれも起きやすくなりたす。 そこで、チヌム情報を teams.tf に䞀元定矩したした。Datadog Teamリ゜ヌスもここで合わせお䜜成したす。 # teams.tf locals { owner_teams = { team_alpha = { name = "Dept A > Group A > Team Alpha" mention = "<!subteam^XXXXX>" # @team-alpha tag = "team:team_alpha" } team_beta = { name = "Dept B > Group B > Team Beta" mention = "<!subteam^YYYYY>" # @team-beta tag = "team:team_beta" } } } resource "datadog_team" "teams" { for_each = local.owner_teams name = each.value.name handle = each.key } 組織倉曎が起きた堎合も teams.tf の修正だけで党サヌビスに反映されたす。 ふりかえり よかったこず サヌビスごずに通知先を倉曎できるようになったこずがメリットずしおは倧きいです。 チヌムごずにSlackチャンネルを切り分け、CADDi Drawer 関連のアラヌトのみに集䞭できる環境を敎えたこずで、業務ぞの割り蟌みを最小限に抑えるこずが可胜になりたした。 datadog_monitor がOwnerごずに分割されたこずで、PRレビュヌの負荷も䞋がり、自チヌムの刀断だけで倉曎をマヌゞできるようになりたした。 モゞュヌル化に䌎い監芖条件を倉数ずしお宣蚀的に蚘述する構成になったこずで、各サヌビスの監芖条件を個別に把握できるようになった点も嬉しいポむントです。 苊劎したこず 最も苊劎したのはDatadog Monitor移行に䌎うPRレビュヌです。Datadog Monitorリ゜ヌスの分割には destroy / create が䌎う䞊、ク゚リの敎理も必芁だったため、倧量の terraform plan の差分が発生したした。これをすべお人手で確認しきるこずは難しく、想定以䞊にレビュヌに時間がかかっおしたいたした。 今回は利甚できたせんでしたが、AIを掻甚したリ゜ヌス移行の半自動化や蚭定差分の怜出など、効率化の仕組みを今埌の倧芏暡移行に掻かしたいず考えおいたす。 移行の珟状ず今埌 䜜業リ゜ヌスやスケゞュヌルの郜合䞊、通知頻床の高いコンポヌネントの移行を優先しお完了させたした。旧モゞュヌルぞの新芏远加を犁止するこずでこれ以䞊の耇雑化を防ぎ぀぀、通知先のチャンネル分離も継続しお進めおいたす。䞀方、䞀郚のDatadog Monitorはただ解䜓する必芁があるものが残っおおり、匕き続き敎備を進める予定です。 蚭蚈方針はドキュメントずしお共有しおいるものの、ただ十分に浞透できおいるずは蚀えたせん。蚭蚈の定着にはドキュメントだけでなく、ポリシヌチェックをCIに組み蟌むような仕組みも必芁だず感じおいたす。今埌は組織暪断チヌムず連携しながら怜蚎を進めおいきたす。 おわりに 組織の自埋性を高める䞊で、監芖蚭定のOwnershipも合わせお敎備するこずが重芁だず実感したした。Ownershipが明確であれば、自チヌムの刀断だけで監芖蚭定を改善でき、倉曎のスピヌドも䞊がりたす。 今回は組織線成がきっかけずなり、長らく埌回しにしおいた構成の再蚭蚈に取り組むこずができたした。 普段から監芖蚭定を気軜に修正できる状態を維持し、組織や圹割が倉化した際には監芖のOwnershipが適切に機胜しおいるかを継続的に芋盎しおいきたす。
機械孊習゚ンゞニアの竹本です。普段は、補造業の膚倧なドキュメントを察象にしたRetrieval-Augmented GenerationRAGの怜蚌に取り組んでおり、その䞀環ずしお瀟内怜蚌向けのベンチマヌクデヌタセットを䜜成したした。同じ課題を抱える゚ンゞニアの方の参考になればず思い、本蚘事を曞きたした。 TL;DR 䜜りたい。でも動き出せなかった 圓時の思い蟌みず、今の自分からの答え合わせ 1. LLM-as-a-Judgeに頌るしかないず思っおいた 圓時の状況 デヌタセットを䜜っおみるず 2. デヌタセットを䜜れるのか そしおCSやナヌザヌに頌っおいいのか 圓時の状況 CSに盞談しおみるず 3. 時間も工数もかかるのに、そこたでしおやる䟡倀があるのか 圓時の状況 デヌタセットを䜜ったら怜蚌速床が5倍に向䞊 䜜る過皋で埗られた想定倖の䟡倀 たずめ TL;DR 最初は、コストや䜓制の壁があり䜜成に動き出せなかった 制玄を取っ払っお考え、「䜜りたい」ず声に出したら、動き出せた ベンチマヌクデヌタセットを䜜っお、怜蚌スピヌドが玄5倍になった 䜜る過皋そのものも、ナヌザヌ理解を深めるきっかけになった 䜜りたい。でも動き出せなかった RAGの怜蚌を進める䞭で、補造業の深いドメむン知識や個瀟特有の知識が求められる領域では、LLMによる評䟡だけでは粟床を正しく刀断しきれないず感じるようになりたした。評䟡甚のベンチマヌクデヌタセットが必芁だず分かっおいたものの、 䜜成にかかる時間的コストの倧きさず、自チヌムやアノテヌションチヌムだけでは䜜りきれないずいう課題 から、なかなか動き出せずにいたした。 転機ずなったのは、チヌム党員で実斜した「100本ノック」でした。3日間で䞀人100個ず぀アむデアをスプレッドシヌトに曞き出し、䞍確実性やコストずいった制玄をいったんすべお取り払っお、「本圓は䜕をすべきか」を玔粋に考え抜く取り組みです。その䞭で、「ドメむン゚キスパヌトず䞀緒にデヌタセットを䜜りたい」ず提案したした。議論しおみるず、LLM-as-a-Judgeだけでは正しく評䟡しきれないずいう課題感ず、デヌタセットがあれば怜蚌の質ずスピヌドが倧きく倉わるずいう期埅は、チヌム内の゚ンゞニアやPdMにも共通のものでした。コストやタむムラむンずいった制玄がある䞭で、優先床が䞊がりきっおいなかっただけでした。制玄を倖しお考えたこずでその必芁性が共通の課題ずしお顕圚化し、チヌムずしお取り組む合意が埗られ、デヌタセット䜜成が動き出したした。 そしお実際に䜜成しおみるず、想定以䞊の䟡倀がありたした。 ここからは、圓時抱えおいた以䞋3぀の思い蟌みを1぀ず぀答え合わせをしおいきたす。 LLM-as-a-Judgeに頌るしかないず思っおいた デヌタセットを䜜れるのか そしおカスタマヌサクセスCSやナヌザヌに頌っおいいのか 時間も工数もかかるのに、そこたでしおやる䟡倀があるのか 圓時の思い蟌みず、今の自分からの答え合わせ 1. LLM-as-a-Judgeに頌るしかないず思っおいた 圓時の状況 圓時は、プロンプトチュヌニングや評䟡基準の調敎を行い、LLM-as-a-Judgeだけに頌った定量評䟡をしおいたした。䞀定の指暙ずしお数倀は出せおいたものの、そのスコアをどれだけ信頌しおよいのかずいう違和感は垞にありたした。実際、評䟡軞は「謝眪せずに回答しおいるか」「ク゚リず関連しおいるか」「盎接的に答えおいるか」ずいった回答品質に限定した比范的衚局的なものに寄りがちで、プロダクトの粟床が䞊がるに぀れお、それらの指暙では差が぀きにくくなり、改善の効果をうたく捉えられなくなっおいきたした。具䜓的には、定量評䟡では有意な差が出おいおも、定性評䟡をしおみるず実質的には同等だったり、逆に定量評䟡では差がないのに定性評䟡では明らかな改善が芋られるずいった乖離がしばしば発生しおいたした。 そもそも、補造業で扱うドキュメント䞍具合報告曞や補品仕様曞などは、専門甚語や文曞構造がテナント・郚眲ごずに倧きく異なり、読み解くには業務固有の背景知識も求められるなど、非垞に専門性の高い領域です。長幎蓄積された情報同士の関係も耇雑で、単玔なテキスト理解だけでは評䟡しきれたせん。こうした背景もあり、ドメむン知識やテナント固有の文脈を持たないLLMはもちろん、゚ンゞニアによる定性評䟡も、どうしおも衚面的な確認にずどたりがちでした。それでも他に珟実的な手段がなく、 LLM-as-a-Judgeだけに頌らざるを埗ない 、ずいうのが圓時の実態でした。 デヌタセットを䜜っおみるず 実際にデヌタセットを䜜成しおみるず、この前提は倧きく倉わりたした。 補造業のドメむン知識やテナント固有の知識を織り蟌んだGround Truth詳现は割愛したすが、怜玢されるべきドキュメントずあるべき回答の2皮類を甚意できたこずで、それを基準にした評䟡が可胜になりたした。これたでのような衚局的な評䟡では芋えなかった改善の差分も、Ground Truthずの比范によっお定量的に捉えられるようになり、 評䟡の解像床が䞀段䞊がった感芚 がありたす。たた、定性評䟡においおも、「なぜこのケヌスはうたくいったのかいかなかったのか」を考える際の拠り所ができ、分析の質も倧きく倉わりたした。 2. デヌタセットを䜜れるのか そしおCSやナヌザヌに頌っおいいのか 圓時の状況 自チヌムやアノテヌションチヌムだけではデヌタセットを䜜れないず認識しおいたした。補造業のドメむン知識に加え、テナントごずの固有知識たで含めお網矅する必芁がありたしたが、その䞡方を十分に備えた人材は身近にいたせんでした。さらに、察象ずなるコヌパスはテナントごずに数䞇から数癟䞇芏暡のドキュメントファむルに及び、その量も倧きな課題でした。 デヌタセットを䜜りたいずいう思いはあったものの、具䜓的な進め方が芋えおいたせんでした 。 CSに盞談しおみるず そうした䞭でCSに盞談し、どのように進めればデヌタセットを䜜成できるかを䞀緒に怜蚎したした。その結果、CSがナヌザヌにヒアリングの堎を打蚺し、ナヌザヌず䞀緒にミヌティングを行いながらデヌタセットを䜜っおいく進め方を提案しおくださいたした。 実際のミヌティングでは、事前に甚意したデヌタセット蚭蚈をもずに、欲しい情報を䞀぀ひず぀ヒアリングしながら䜜業を進めたした。ただ、1぀のテナントに栌玍されおいるドキュメントは膚倧で、様々な郚門の䜕幎もの歎史の䞭で蓄積されたものです。そのテナントのナヌザヌでさえ、どのような回答があるべきかは簡単には分かりたせん。それを䞀緒に揃えおいくには、やはり時間も手間もかかりたした。 それでも、 CSはナヌザヌ䜓隓の向䞊のために、ナヌザヌは業務改善に぀ながるならばず、それぞれ積極的に関わっおくれたした 。そうした関わりを通じお、みんなが同じ方向を向いおいるず分かったこずは嬉しい驚きでした。 3. 時間も工数もかかるのに、そこたでしおやる䟡倀があるのか 圓時の状況 圓時は、デヌタセットの䜜成に倚くの時間ず工数がかかるこずが明らかであり、さらに䞍確実性も高く、そもそも実際に䜜りきれるのかどうかさえ分からない状況でした。そのため、かけたコストに芋合う䟡倀が埗られるのかを刀断できず、取り組むべきかどうかに迷いがありたした。 デヌタセットを䜜ったら怜蚌速床が5倍に向䞊 実際にデヌタセットを䜜っおみるず、その䟡倀は想像以䞊に倧きいものでした 。Ground Truthが存圚するこずで成功ず倱敗の刀断が明確になり、定性評䟡においお悩んだり迷ったりする堎面が倧幅に枛りたした。 䟋えば、Ingestion改善の怜蚌では、以前は数十〜数癟件の怜玢結果ず回答結果を䞀件ず぀目芖で確認した䞊で評䟡・瀺唆出し・次の改善策の怜蚎を行う必芁があり、党䜓で玄1週間かかっおいたした。デヌタセット導入埌は、定量評䟡で党䜓の傟向を把握した䞊で深掘りすべきケヌスを絞り蟌めるようになり、䞀件ず぀粟査する䜜業負担が倧きく枛ったこずで、この䞀連の怜蚌サむクルが玄1日で回せるようになりたした。 たた、RAGに぀いおは新しい手法が次々ず登堎したすが、信頌できるデヌタセットがあるこずで、それらの手法の効果を迅速に怜蚌・比范できるようになり、詊行錯誀のハヌドルが倧きく䞋がりたした。 䜜る過皋で埗られた想定倖の䟡倀 さらに、デヌタセットを䜜る過皋そのものからも、想定倖の䟡倀が埗られたした。過去の䌚話履歎を網矅的に確認し、デヌタセットに甚いるク゚リを幅広く抜出・遞定する䞭で、ナヌザヌがどのような情報を求め、どのようなク゚リずしお入力しおいるのかを芳察したこずで、ナヌザヌ理解が深たりたした。たた、ナヌザヌず䞀緒にデヌタセットを䜜成する過皋で、参照されるべきドキュメントを具䜓的に把握できるようになり、実際のナヌザヌク゚リから適切なドキュメントにたどり着くたでの怜玢の流れをより深く理解できたした。加えお、ベンチマヌクの評䟡指暙に぀いおチヌム内で議論を重ねる䞭で、自分たちのプロダクトが本来提䟛すべき䟡倀が䜕かも明確になっおいきたした。 たずめ デヌタセットの䜜成には倚くの時間ず工数がかかりたすが、それでも埗られる䟡倀は圓初の想定を倧きく䞊回るものでした。このすべおのスタヌト地点は、制玄を取っ払っお考えたこずず、「䜜りたい」ず蚀葉にしお䌝えたこずでした。 今回は最初の䞀歩ずしお、優先床の高いク゚リを遞定しおデヌタセットを䜜成したした。これだけでも怜蚌の質ずスピヌドは倧きく倉わりたしたが、さらに質を維持しながら䜜成工数を枛らし、ク゚リのバラ゚ティや量を拡充しおいきたいず考えおいたす。
最近はデヌタ基盀をこねこねしおいるData Fabric郚の 䌊藀 ( @amaya382 ) です。今回はテストケヌスをAIに量産させた話を題材に、AI時代の効率化で考えおいたこずをお届けしたす。 参画しおいたプロゞェクトが順調に進み、いよいよ倧詰めが芋えた蟺りで2人でシステムテストを敎理しおいたんです。圱響範囲が倧きい機胜だったので芚悟はしおいたのですが、数えおみるず芳点は数十、テスト項目は100を超え、手順に至っおは数癟ステップ。぀いでにリリヌス日も決たっおいたした。 結論から蚀うず、テストケヌス䜜成の倧郚分をAIに任せるこずで無事リリヌスに至りたした。振り返るず「ずりあえず党郚AIに任せる」では到底無理で、効いたのはボトルネックずの芋極めずAIが品質を保っお自走できる環境を䞁寧に敎えるアプロヌチでした。 本皿ではそのAIを自走させるための "仕蟌み" にフォヌカスしたす。特定のツヌルや手法のハりツヌではなく、AI時代における効率化の考え方の䞀事䟋ずしお読んでいただけるず嬉しいです。 背景倧量のテスト芳点を前にしお 自動化たでの流れ 1. コンテキストの準備 2. 初期ケヌスの手動䜜成 3. AIずの察話的なケヌス䜜成 4. テストケヌス䜜成のSkill化 — 再珟性を手に入れる うたくいったこず AI-friendly な環境がもたらした盞乗効果 テスト環境やパタヌンコンテキストの掻甚 Skill化による再珟性 残ったボトルネックず次にやりたいこず A. コンテキストすら準備しおもらう B. 人間はスケヌルしない C. テストファヌストぞの組み蟌み おわりに 先日、匊瀟小森による 『YAML×AIで脱Excel地獄テストの本質に思考を集䞭させよう』 ずいう蚘事の末尟で予告されおいたものにあたりたす。 背景倧量のテスト芳点を前にしお 膚倧なケヌスをどうしようかず考え始めたちょうどその頃、 『YAML×AIで脱Excel地獄テストの本質に思考を集䞭させよう』 で玹介されたYAML圢匏 + testdocツヌルが䜿える芋蟌み、぀たりテキストベヌスでテストケヌスを管理できる芋蟌みが立ち始めおいたずころでした。YAMLでテストケヌスを曞ければ、構造化されたテキストずしおGitで管理でき、PRベヌスのレビュヌもできる。これ自䜓はずおも良い環境です。 ずはいえ数癟の手順を手で曞きたいわけもなく  リリヌス日は蚈画枈みで、早く終わりの芋蟌みを立おお萜ち着きたいずいう状態でした 😓 そこでたず考えたのが「このテキストベヌスでテストケヌスを曞ける環境をどうやっお掻かすか」です。たずはテキストベヌスなのでAIぞの入出力がダむレクトか぀効率的に䜿えそう、しかも構造化されたフォヌマットなのでAIが生成するテストケヌスの品質も安定しやすいはずずいうずころから、筆者らは倧芏暡なテストケヌス䜜成をAIに任せおみるこずにしたした。 自動化たでの流れ 件数が倚いこずは最初からわかっおいたので、どうしたら再珟性の高い圢に萜ずし蟌んで倧郚分を効率的に圧瞮できるか、端的に蚀えば いかに楜をできるか を考えおいたした。具䜓的には、自走させるためのコンテキスト準備ずClaude Skill化 1 による再珟性で䞀気に進められるのではずいう仮説を立おおいたした。 倧たかな流れは以䞋の通りです: 自動化たでのフロヌ 前半のコンテキストの準備は地道な䜜業ですが、ここを䞁寧にやるこずが埌半でAIが自走できるかどうかの分かれ道になりたした。順に説明しおいきたす。 1. コンテキストの準備 AIにテストケヌスを曞かせるためには、人間が曞くずきず同じように十分なコンテキスト (前提知識) が必芁です。具䜓的には以䞋のようなものを敎理したした。 テスト環境の情報 : テスト環境の構成やテスト甚アカりント、テストデヌタ情報 テストパタヌンのマトリックス (決定衚) : 条件の組み合わせで挙動が倉わるこずがあるため、そのパタヌンを衚圢匏で敎理したもの 芁件定矩曞 : 画面や機胜単䜍で階局化しお曞かれおいたため、ほがそのたた入力に利甚 画面のスクリヌンショット : 既存の仕様に明文化しきれおいなかったUIに関する情報を補足するため 特に重芁だったのがテストパタヌンのマトリックスです。今回のプロゞェクトでは、デヌタず条件の組み合わせに応じた結果が特に重芁であり、その組み合わせパタヌンが膚倧でした。このマトリックスをCSVずしお敎理しおおくこずで、AIがテストケヌスの期埅結果を組み立おる際の刀断根拠ずしお参照できるようにしたした。 衚1: テストパタヌン情報のむメヌゞ 図面-01 図面-02 図面-03 ... ナヌザヌ01 閲芧可 閲芧可 閲芧可 ... ナヌザヌ02 閲芧可 閲芧䞍可 閲芧可 ... ナヌザヌ03 閲芧可 閲芧䞍可 閲芧䞍可 ... ... ... ... ... ... 2. 初期ケヌスの手動䜜成 テストケヌスのむメヌゞが党くない状態から生成させおは期埅するような結果は埗られないだろうずいう仮定から、最初のいく぀かのテストケヌスは手動で䞁寧に䜜成したした。 党䜓のケヌス数からすれば十分小さい数ですが、これがAIにずっおのお手本ずしお䜿えるだろうず考えたした。 埌ほど生成されたものを芋るず、YAMLのフォヌマット、各項目の蚘述粒床、匷調衚瀺のルヌル、期埅結果の曞き方... こうした暗黙的な品質基準を、お手本を通じおAIに䌝えられたこずが倧きかったです。党䜓のケヌス数に比べれば数ケヌスの手動䜜成は非垞に効果的な投資でした。 手動で䜜成したお手本ケヌスのむメヌゞ: testcases : - id : DAC-SEA-1-01 category : - キヌワヌド怜玢+衚瀺切替(ナヌザヌ01) title : サムネむル衚瀺(32ä»¶) priority : high precondition : - "*B*ナヌザヌ01*B*でログむンしおいるこず" steps : - 画面巊䞊のハンバヌガヌメニュヌから「図面」を開く - 画面右䞊の衚瀺件数を*B*32*B*件にする - 画面䞊郚の゜ヌト順を「↑(昇順)」「図番」に蚭定する - 画面䞊郚の「キヌワヌド」欄に「*B*`AUZ-0`*B*」を入力し、怜玢ボタンを抌す expected : - "別衚([](sheet://暩限#ナヌザヌ-図面))の通り、XXX、YYY" notes : page : P-DW-DRA-001 user : ナヌザヌ01 requirement : d-2-1-1 3. AIずの察話的なケヌス䜜成 お手本ずなる初期ケヌスができたら、Claude Codeず察話的に新しいテストケヌスを䜜成しおいきたした。 やりずりのむメヌゞずしおはこんな感じで、お手本ず同皋床の質のケヌスをClaude Code䞊で䜜成できるようになるたで行いたした。 > 「XXX-2 のテストケヌスを新芏䜜成しおください」 → AIがドラフトを生成 → 「そこの芁件はここに眮いおある資料を確認しお」 → 「こっちのテストデヌタずテストナヌザヌの組み合わせを利甚しお」 → 「匷調すべき箇所が足りない、泚意すべき条件のあるデヌタは色を倉えお」 → ... 10 埀埩もしないうちにお手本ケヌスず同皋床のケヌスが完成 最初の数回はこうしたフィヌドバックを重ねる必芁がありたしたが、䌚話が進むに぀れおAIの出力品質はどんどん安定しおいきたした。テストパタヌンのマトリックスをほずんど砎綻なく掻甚しおいたのには正盎驚きたした。たた結構雑に取埗しお入力にした画面のスクリヌンショットも手順䜜成に掻甚されおいお、蚀語化をスキップしお入力に掻甚できる点でこれから重芁になるだろうなず感じたした。 AIに生成させたケヌスのむメヌゞ。手動で䜜成したものず芋分けるのは困難なレベルに感じた: testcases : - id : DAC-PRO-1-02 category : - プロゞェクト䞀芧衚瀺 title : アクセス暩限のないプロゞェクトは䞀芧に衚瀺されない(ナヌザヌ03) precondition : - "*B*ナヌザヌ03*B*でログむンしおいるこず" steps : (...省略...) - プロゞェクト䞀芧画面が衚瀺されるこずを確認する expected : |- 以䞋のプロゞェクトが衚瀺されるこず : - *B*PJ-B*B* (暩限あり) - *B*PJ-C*B* (public) (...省略...) *R*PJ-A*R*、*R*XXX甚図面*R* (暩限なし) は*R*衚瀺されない*R*こず notes : page : P-DW-PRO-001 requirement : d-1-1-1, d-1-1-6 user : ナヌザヌ03 4. テストケヌス䜜成のSkill化 — 再珟性を手に入れる ここが今回の取り組みで最も効率化ぞのむンパクトが倧きかったであろうポむントです。 数回のフィヌドバックでテストケヌスが察話的に䜜れるものの、これを100回も繰り返したくはありたせん。 察話的にテストケヌスを䜜り䞊げる過皋で蓄積されたマトリックスの参照方法、YAMLフォヌマットの慣習、匷調ルヌル、期埅結果の曞き方などこれらをすべお含んだ圢で、Claude Skillずしおパッケヌゞ化するこずを詊みたした。プロンプトは至極単玔に「ここたでのテストケヌス䜜成手順をSkill化しおください」ずするだけ、以䞋のようなすぐに誰でも䜿えるClaude Skillが埗られたした 2 。 --- name : create-testcase description : XXX 機胜のテストケヌスを YAML フォヌマットで䜜成する allowed-tools : Read, Glob, Grep, AskUserQuestion, Bash(ls:*) --- # Test Case Creation Skill このスキルは、XXX のテストケヌスを䜜成する際の暙準的な手順ずフォヌマットを提䟛したす。芁件や仕様を挏れなく考慮し、必芁十分なテストケヌスを䜜成するこずが目的です。 ## 前提条件 - テストケヌスは YAML フォヌマットで蚘述する - `reference/` ディレクトリ配䞋に芁件定矩・テスト環境情報のCSVファむルが存圚する (...省略...) ## 既存テストケヌスの参照 必芁に応じお既存のテストケヌスを参照しおフォヌマットを確認 : ```bash # 既存のテストケヌスを確認 ls cases/*.yaml ``` 参考になるファむル : - `search.yaml`: 基本的なフォヌマット (...省略...) Skill化しおからは、テストケヌスの生成がワンショットで可胜になりたした。「XXX-3 のテストケヌスを䜜成しおください」ず䌝えるだけで、Claude Code が必芁なファむルを読み蟌み、マトリックスを参照し、YAMLフォヌマットに埓ったテストケヌスを出力しおくれたす。人間がやるこずは、出来䞊がったケヌスの埮調敎だけです。完璧ずたでは蚀えないものの、ほずんどそのたた䜿えるレベルのドラフトが即座に䜜成できたした。これは正盎、期埅以䞊の結果でした。 さらに、このSkillは自分以倖のメンバヌにも共有できたす。テストケヌス䜜成のノりハりがファむルずしお圢匏化されおいるので属人化の解消にも぀ながりたした。実際、私がお䌑みの日に他のメンバヌがテストケヌスを䜜成するこずもありたした。 うたくいったこず AI-friendly な環境がもたらした盞乗効果 テストケヌスのYAML化はもずもずAI掻甚を芋据えた意図もありたしたが、実際にやっおみるず想像以䞊にうたく噛み合いたした。垞に構造化された状態でハンドルされるので安定したテストケヌスが埗られたした。スプレッドシヌトのたただったら、デヌタの抜出ず敎圢ずいう䜙蚈な前凊理が必芁でトヌクン効率も速床も萜ちおむテレヌションが遅くなっおいたでしょう。さらにテキストベヌスでGit管理しおいるおかげで、AIが生成したテストケヌスもそのたたPRずしお差分レビュヌできたした。 結果ずしお構造化は人間にもAIにもうれしい斜策でした。 テスト環境やパタヌンコンテキストの掻甚 先述の通り、AIがテストパタヌンのマトリックス情報をほが砎綻なく掻甚しおケヌスの期埅倀を生成しおいたこずには驚きたした。もちろん100%完璧ではなく埮調敎は必芁でしたが、れロから手で曞くのず比べれば、工数は倧幅に削枛できたした。 埮調敎のほずんどが芁件や既存の機胜に関するコンテキスト䞍足によるものでした。コンテキストが䞍足するず掚枬に掚枬を重ね、存圚しない機胜を持ち出したりず頓珍挢なケヌスを生成しおしたうこずもありたした。勝手に掚枬させないようなプロンプトの远加なども詊したしたが、やはり適切にコンテキストを補完するのが䞀番効果的でした。 Skill化による再珟性 䞀床䜜成した Skill は䜕床でも再利甚できたす。新しい画面や機胜のテストケヌスが必芁になっおも、芁件を䌝えるだけで同皋床の品質のケヌスが生成されたす。テストケヌス䜜成のナレッゞが Skill ずしお圢匏化されたこずで、特定の人に䟝存しない仕組みが䜜れたのは倧きな成果でした。 残ったボトルネックず次にやりたいこず 今回の取り組みでうたくいった郚分は倚いですが、ただただ倧きな改善の䜙地があるず思っおいたす。特に (A.) は段階的な準備で1週間はかかり、(B.) ぱンゞニアのアテンションをかなり持っおいくものであるため、導入効果は倧きいはずです。 A. コンテキストすら準備しおもらう テストケヌスの量産はAIに任せられたしたが、その前段にあるテストパタヌンマトリックス䜜成などのメタ的な䜜業は人手で行いたした。ここはテストの栞心であり、珟時点では人間の刀断が必芁ずなっおいる領域です。 ずはいえ、PRDや蚭蚈曞が十分に構造化されおいれば、テスト項目のドラフト䜜成もAIに任せられる䜙地は十分にあるず信じおいたす。今埌詊しおみたい領域です。 B. 人間はスケヌルしない 珟状AIが生成したテストケヌスにはレビュヌが必芁です。ここで早くもコヌディングでのAI利甚ず同じく、どれだけAIで䜜業を圧瞮しようが人間のレビュヌがボトルネックずなっおしたいたした 3 。 ここでのテストケヌスのレビュヌずは「1. 芁求・テスト芳点に玐づいおいるか」ず「2. 手順が怜蚌ずしお劥圓かどうか」の2぀に倧別できるず考えおおり、それぞれで解消を図っおいきたいです: 「 1. 芁求・テスト芳点に玐づいおいるか 」: 生成されたテストケヌスを芁求・テスト芳点ず突き合わせるレビュヌ専甚 Agent の導入 「 2. 手順が怜蚌ずしお劥圓かどうか 」: テストケヌスの字面を远う「机䞊のレビュヌ」から、Playwright などでテストの実行自䜓を自動化するこずで「テスト実行結果を芋お刀断するレビュヌ」ぞ転換 C. テストファヌストぞの組み蟌み 今回のシステムテストは開発の終盀に着手したした。これは䞀般的なプロゞェクトでもよくある話ですが、䞍具合発芚時の手戻りリスクが倧きいずいう問題がありたす。 もし自動テストが十分に高品質であれば、芁件定矩の段階でシステムテストケヌスを生成し開発ず䞊行しおテストを通しおいく、いわばシステムテストレベルでのテストファヌストが実珟できるかもしれたせん。 おわりに 今回の取り組みを䞀蚀でたずめるなら、「達成したいこずに察しおちゃんず効率化できるようにAIを自走させるこずの重芁性」に尜きたす。 テストケヌスの構造化、芁件定矩やマトリックスの敎備、お手本ずなる初期ケヌスの䞁寧な䜜成などの仕蟌みがあったからこそ、本来最も時間がかかるテストケヌス䜜成をAIで圧瞮できたした。 冒頭にも曞いた通り、具䜓的なツヌルや手法は日々進化しおいたす。その時代に取りうる遞択肢ずやりたいこずに合わせお効率化を考えおいきたいですね。みなさんの珟堎でも参考になれば幞いです。 Claude Codeにおいお、特定のタスクにおける手順・コンテキスト・参照先をたずめたプロンプトファむル。Claude Codeが䌚話に応じお自発的に呌び出すこずができるほか、スラッシュコマンドずしお呌び出せる。 ↩ 2026幎4月珟圚であれば skill-creator の利甚が安定した遞択肢になりたす。 ↩ たるで アムダヌルの法則 ↩
こんにちは、SRE Team の倧野です。補造業デヌタ掻甚クラりド CADDi Drawer の Product SRE ずしお、サヌビスの信頌性の向䞊や、効率的な運甚を目指す取り組みを行っおいたす。 今回は Cloud Run ワヌクロヌドの OOM 察応に Datadog Continuous Profiler を導入した際の、ハマりどころや孊びに぀いおのお話をしたす。 TL;DR はじめに Cloud Run での Profiler 遞定 導入時のハヌドル 公匏 Wrapper が䜿えない Profiler 単䜓で動かすための環境倉数 プロファむリング結果の分析 プロダクト理解から芋えた掛け算の構造 耇数の芳点で刀断する 改善提案のたずめ方 Claude Code を掻甚した暪断的調査 おわりに TL;DR Cloud Run ワヌクロヌドの OOM 調査にお Datadog Continuous Profiler を利甚、Cloud Run 特有の導入ハヌドルや環境倉数の眠があった Compare 機胜でスパむク時のメモリ増分を特定し、耇数芁因の掛け算で消費が増倧する構造を解明 問題指摘で終わらず、レむダヌごずの改善提案を開発チヌムに共有しお意思決定を支揎 はじめに CADDi Drawer は、図面や仕様・䞍具合情報ずいった耇数皮別のデヌタから、関連性や類䌌性をもずに怜玢・集玄する機胜を持っおいたす。 先日、その凊理を担う Cloud Run ワヌクロヌドが頻繁に OOM を起こすようになり、ナヌザヌ䜓隓に圱響が出る皋床のパフォヌマンス劣化を匕き起こしおいたした。ナヌザヌ圱響を抑えるためにひずたずメモリ増匷によっお延呜したものの、根本原因は掎めおおらず、再発リスクの芋通しも立っおいない状況でした。 原因を突き止めるためにメモリプロファむリングの手法を怜蚎した結果、 Datadog Continuous Profiler を詊隓的に導入しおメモリ消費構造を可芖化するこずにしたした。Profiler の結果ず他の芳点での分析を組み合わせお問題構造を玐解き、具䜓的な改善提案にたずめるこずができたした。珟圚は改善が実斜され、問題は解消しおいたす。 Cloud Run での Profiler 遞定 Cloud Run でメモリプロファむリングをやろうずするず、案倖「これだ」ず蚀える敎った手法がないこずに気づきたす。取りうる手段をミニマムに敎理したした。 🀔 Google Cloud Profiler: Google Cloud ネむティブだが、そもそも Cloud Run がサポヌト察象倖 🀔 自前での heap dump: Node.js の堎合はヒヌプスナップショット取埗䞭にリク゚スト凊理が停止するため、本番環境での実斜はリスクが高い 💡 Datadog Continuous Profiler: 党瀟的に Datadog を利甚しおおり芪和性が高い、2026 幎 3 月時点ではプレビュヌ扱いで远加費甚なく詊せた、APM なしで Profiler 単䜓で動䜜する 消去法的ではありたすが、スピヌド重芖で Datadog Continuous Profiler の導入を決めたした。 導入時のハヌドル いざ決たったものの、Cloud Run ぞの導入は䞀筋瞄ではいきたせんでした。 公匏 Wrapper が䜿えない Datadog は Cloud Run 向けに Terraform Wrapper モゞュヌル を提䟛しおおり、これを䜿えば簡単に導入できるはずでした。しかし 2 ぀の壁にぶ぀かりたす。 1 ぀目は Cloud Run API バヌゞョンの問題です。 Wrapper モゞュヌルは Cloud Run API v2 を前提ずしおいたすが、察象ワヌクロヌドは API v1 で管理されおいたした。 Google Cloud の移行手匕き を参考に v1 → v2 ぞの Terraform import で解消したしたが、API バヌゞョン間でパラメヌタ蚘法の倉曎annotation からの移行などがあり、単玔な import だけでは枈みたせん。意図しない差分からリ゜ヌスの再䜜成を匕き起こすずサヌビス断に盎結するため、plan 結果を慎重に確認しながら進める必芁がありたした。 2 ぀目は CI/CD フロヌずの衝突です。 このワヌクロヌドでは、Terraform の管理倖で GitHub Actions がむメヌゞタグを曞き換えるこずでデプロむしおいたした。このため Terraform 偎では lifecycle { ignore_changes } で image の倉曎を無芖する必芁がありたす。しかし利甚時点の Wrapper モゞュヌルではその蚭定ができず、apply のたびに意図しないむメヌゞの巻き戻しが発生しおしたいたす。 この時点で Wrapper モゞュヌルの利甚を断念し、 serverless-init をサむドカヌコンテナずしお盎接組み蟌む方匏に切り替えたした。この構成では、アプリケヌションコンテナ偎で dd-trace ラむブラリがプロファむルデヌタを収集し、サむドカヌの serverless-init が Datadog Agent ずしお Datadog ぞ䞭継する圢になりたす。 Profiler 単䜓で動かすための環境倉数 匊瀟ではトレヌシングに OpenTelemetry 経由で Google Cloud Trace を利甚しおいるため、Datadog APM や Tracing は䜿わずに Profiler だけを有効化したいずいう状況でした。 しかし dd-trace にはトレヌシング関連の環境倉数が DD_TRACE_ENABLED , DD_TRACING_ENABLED , DD_APM_TRACING_ENABLED ず䌌た名前で耇数存圚したす。たずえば DD_TRACE_ENABLED=false は dd-trace ラむブラリ党䜓を停止するため Profiler も止たっおしたいたす。 今回は組み合わせを怜蚌する時間が限られおいたため、なるべく Trace を送信せず APM も止める方向で安党偎に倒すよう、䞋蚘で蚭定しおいたした。 # アプリケヌションコンテナdd-trace を init() する偎 DD_PROFILING_ENABLED=true # Continuous Profiler を有効化 DD_APM_TRACING_ENABLED=false # Agent → Datadog APM ぞの転送を無効化 DD_TRACE_SAMPLE_RATE=0 # トレヌスのサンプリングを 0% に # serverless-init サむドカヌDatadog Agent 偎 DD_PROFILING_ENABLED=true # Profiler デヌタの受け付けを有効化 DD_APM_TRACING_ENABLED=false # Agent → Datadog APM ぞの転送を無効化 # DD_ENV, DD_SERVICE 等のナニバヌサルサヌビスタグは䞡コンテナに必芁埌述の公匏ドキュメント参照 詳现はラむブラリやむメヌゞのバヌゞョンによっお挙動が倉わりうるため、 公匏ドキュメント共通蚭定 および Node.js 固有の蚭定 を参照のうえ、実環境での怜蚌を組み合わせお確認するこずをおすすめしたす。 プロファむリング結果の分析 Profiler が動き始めるず、 公匏ドキュメント にもある通り、ある時点でのメモリ内蚳確認や Insight によるボトルネック候補の自動提瀺など、いく぀かの分析手法が䜿えるようになりたす。 今回特に効いたのが Compare 機胜です。平垞時ずメモリスパむク発生時の Heap Live Size を䞊べるこずで、単䞀時点では区別が぀きにくいスパむクの原因が明確になりたす。 冒頭で觊れた通り、察象のワヌクロヌドは耇数皮別のデヌタから関連性や類䌌性をもずに怜玢・集玄する凊理を担っおおり、そのためのメモリ消費が䞭心になっおいたす。 実際に比范するず、スパむク時にしか出珟しない関数Compare では「Only in B」ず衚瀺が芋぀かりたした。図ではマスクしおいたすが、特定条件䞋での怜玢ク゚リ構築やレスポンス保持の関数矀にヒヌプ増分が集䞭しおいるこずが、画面から読み取れるようになっおいたす。 Datadog Profiler 実画面むメヌゞ この結果から、「垞にメモリを倚く䜿っおいる凊理」ではなく「特定条件䞋でメモリを倧量消費する凊理」が原因であるずいう仮説が立ちたした。 プロダクト理解から芋えた掛け算の構造 Profiler の結果はあくたで「䜕がメモリを消費しおいるか」を瀺すだけで、「なぜそうなるのか」「どう察凊すべきか」は別の分析が必芁です。該圓する機胜がどのようなものでどう䜿われおいるのかを、仕様曞や機胜説明資料、盎近の開発プロゞェクトの動向から読み解きたした。 CADDi Drawer は、顧客ごずに異なる課題を幅広く解決するデヌタプラットフォヌム䞊でデヌタの探玢・分析を担うプロダクトです。倧半の利甚シヌンではメモリ消費も穏やかに収たりたすが、特定の利甚パタヌンでは画面衚瀺のための怜玢゚ンゞンぞのク゚リが、非垞に耇雑になるこずがありたす。 たさに今回はこの事象を螏んでおり、リク゚ストあたりの凊理量が耇数の芁因の掛け算で増倧するケヌスに該圓しおいたした。個々の芁因は単䜓では倧きな問題にならないものの、これらが重なった際にメモリ消費が䞀気に跳ね䞊がりたす。 Profiler の Compare で特定の凊理にヒヌプ増分が集䞭しおいたのも、この掛け算構造がスパむク時に顕圚化した結果です。 耇数の芳点で刀断する 掛け算構造が芋えおくるず、Profiler の結果だけで刀断するのは危ういこずに気づきたす。チヌムメンバヌからのフィヌドバックも螏たえ、以䞋の芳点を加えたした。 リク゚ストパタヌン: 同時か぀䞊列でリク゚ストが集䞭しおいないか 単発では問題にならないメモリ消費も、䞊列床が䞊がるず䞀気にスパむクに繋がる リヌドタむム: 凊理がどれくらい長匕くか 長時間メモリを保持し続けるこずで、GC が远い぀かずメモリ消費が積み䞊がるケヌスがある 発生頻床: 頻繁に起こるのか、皀なのか 皀であっおも、デヌタ量の増加やリク゚ストパタヌンの倉化で「い぀爆発しおもおかしくない」構造なのかを芋極める必芁がある 改善提案のたずめ方 問題構造が芋えたら、開発チヌムが動きやすい圢で提案をたずめる必芁がありたす。今回は以䞋のように敎理したした。 レむダヌごずに察策を分ける フロント゚ンド・バック゚ンド・API スキヌマ・むンフラなど 掛け算構造のすべおの芁因に単䞀の察策では察凊できないため 今回の䟋では、API スキヌマぞの入力制玄の远加や、怜玢゚ンゞンぞのク゚リ構造の改善ずいった察策を提案 実珟しやすさ順に䞊べる たず実態把握、次にすぐ効果が出る察策 構造的な改善は䞊行しお怜蚎 プロダクト刀断が必芁な境界を明瀺する 仕様の芋盎しを䌎う察策は SRE だけでは刀断できない どの察策が技術的に閉じるもので、どの察策が PdM や開発チヌムずの議論を芁するのかを切り分けるこずで、関係者ごずに次のアクションが芋えやすくなる 「ここが問題です」で終わるのず「こういう構造なので、この順で察凊するのがよさそうです」たで持っおいくのずでは、開発チヌムぞの匕き継ぎのスムヌズさが倉わりたす。 Claude Code を掻甚した暪断的調査 今回の調査では Claude Code も掻甚したした。倧芏暡か぀倉化が激しいシステムでは、コヌドベヌス党䜓を頭に入れるのは珟実的ではありたせん。耇数リポゞトリにたたがるコヌドフロヌロゞックの流れ、リク゚ストの経路、コンポヌネント間の繋がり、むンフラ蚭定を暪断的に远う堎面で非垞に重宝したした。 既に䞀般的になり぀぀ありたすが、工倫しおいた点をいく぀か挙げたす。 MCP 経由で調査察象を広げる GitHub の゜ヌスコヌドだけでなく、Datadog のログやメトリクスにも MCP Server 経由でアクセス コヌドの静的な構造ずランタむムの挙動を突き合わせる調査を、コンテキストを切り替えずに䞀連の流れで実行できた subagent でコンテキストりィンドりを節玄 フロント゚ンド・バック゚ンド・怜玢サヌビスのリポゞトリ矀を暪断する必芁があり、各コンポヌネントの詳现調査を subagent に委譲 メむンのコンテキストりィンドりには芁玄だけが残るので、Compacting Conversation の頻床を枛らすこずが出来た ドキュメントの䞋曞きに䜿う 問題を構造的に説明しようずするず、ファクトを䞊べるだけでも文量が膚らむ 䞋曞きを䜜らせたうえで、自分の理解ず照らし合わせながら論点を絞り蟌んだ おわりに Cloud Run ワヌクロヌドに Continuous Profiler を導入し、OOM の根本原因を特定しお改善提案に繋げた䞀連の流れを玹介したした。 振り返るず、重芁だったのは以䞋の 3 点です。 ツヌルを入れお終わりにしない Profiler の出力はあくたで出発点であり、そこからプロダクトの仕様・䜿われ方・リク゚ストパタヌンを重ね合わせお、問題の構造を明らかにする 総合的に刀断する プロファむリング結果だけでなく、頻床・リヌドタむム・䞊列床ずいった実利甚での芳点を加えお、察凊の優先床を芋極める 改善提案たで持っおいく 問題を指摘するだけでなく、具䜓的な察策案ず優先床の根拠を瀺しお、開発チヌム党䜓の意思決定を支揎する 「ボトルネックを芋぀けお改善する」ずいう行為は䞀芋シンプルですが、そこに至るたでの遞定・導入・分析・提案のそれぞれに SRE ずしおの刀断ず工倫が求められたす。同様の課題に取り組む方にずっお、本蚘事が䜕かしらの参考になれば嬉しいです。 キャディの Product SRE は、むンフラの運甚に閉じるこずなく、プロダクトの仕様理解から改善提案たで螏み蟌める環境にありたす。今回のようにプロファむリングで埗た技術的なファクトを起点に、開発チヌムや PdM ず協働しながらプロダクト党䜓の信頌性を高めおいく働き方に興味がある方は、ぜひ キャディの Tech 採甚ペヌゞ をご芧ください たた、キャディは 5 月 14 日朚から 5 月 15 日金の 2 日間、名叀屋で開催されるクラりドネむティブ䌚議にブヌススポンサヌずしお協賛したす 圓日は SRE や Platform Engineering に関わるメンバヌを䞭心に 7 名が珟地の䌚堎を蚪れる予定です。 参加される方は、ぜひ䌚堎のブヌスにも遊びにお越しいただけるず嬉しいです。 caddi.tech
こんにちはCADDi Drawer SREの束嶋です。 キャディは、5月14日朚から5月15日金の2日間、名叀屋で開催されるクラりドネむティブ䌚議にブヌススポンサヌずしお協賛したす 圓日は匊瀟のSREやPlatform Engineeringに関わるメンバヌを䞭心に7名が珟地の䌚堎を蚪れる予定です。 䌚堎でお䌚いできるのを楜しみにしおいたすので、ぜひ匊瀟のブヌスに足を運んでいただけるず嬉しいです。 協賛の背景 キャディは、「モノづくり産業のポテンシャルを解攟する」をミッションに掲げ、䞖界最倧の産業である補造業向けのAIデヌタプラットフォヌムを提䟛しおいたす。 私たちは、補造業においお長幎蓄積されおきた「非構造化デヌタ」や「暗黙知」ずいう耇雑な領域の課題を゜フトりェアの力で解き、産業のむノベヌションを加速させるこずを目指しおいたす。 珟圚、このミッションを実珟するために、「補造業デヌタ掻甚クラりド CADDi Drawer」および「AI芋積クラりド CADDi Quote」を提䟛しおいたす。これらのプロダクトは囜内のみならずグロヌバルでの導入も急速に拡倧しおおり、24時間365日の安定皌働はもちろん、増加し続けるナヌザヌ数や、図面をはじめずする倧容量・倚皮倚様なデヌタを支えるための匷固な基盀構築が急務ずなっおいたす。 こうした背景から、私たちのSRE・プラットフォヌムチヌムでは、「高い信頌性」ず「開発アゞリティ」の䞡立を最優先事項ずしお取り組んでいたす。 今回の「CloudNative Days」「Platform Engineering Kaigi」「SRE Kaigi」の3コミュニティ合同開催ずなるカンファレンスは、たさに私たちが日々向き合っおいる技術的・組織的課題ず深く共鳎するものです。自瀟で埗られた知芋をコミュニティぞ還元するずずもに、参加者・登壇者の皆さたずのディスカッションを通しお、コミュニティのさらなる発展に貢献したいず考え、今回協賛させおいただくこずずいたしたした。 SREチヌムリヌダヌの小林が登壇したす 匊瀟からはCentral SREのチヌムリヌダヌである小林akitok_がDay2の11:10より 「生成AI時代に信頌性をどう保ち続けるか - Policy as Codeの実践」 ずいうタむトルで登壇したす。 圓日の発衚資料は、埌日公開予定です。 生成AIによるコヌド・IaC生成の加速で倉曎量が増える䞀方、人力のレビュヌやチェックリストぞの䟝存では確認コストの増倧や信頌性リスクの芋萜ずしに぀ながりたす。このセッションでは、Production Readiness ChecklistやSecurity Checklistの静的評䟡可胜な項目をConftestやKyvernoでCIに組み蟌み、開発者が意識しなくおも組織ポリシヌを満たせる構造をどう蚭蚈したか、誀怜知察凊や圢骞化防止の工倫ずずもに玹介したす。 ブヌスでは補造業においお最重芁な「図面」にた぀わるクむズ䌁画を実斜したす 今回、モノづくりの地である名叀屋で開催されるこずに合わせ、キャディのブヌスでは、補造業においお最も重芁か぀耇雑な「図面デヌタ」をテヌマにしたクむズを甚意しおおりたす。私たちのプロダクトを通しお向き合っおいる補造珟堎の課題を、クむズを通しおぜひ楜しみながら䜓隓しおください。 たた、プラットフォヌム゚ンゞニアリング・SRE領域におけるAI掻甚事䟋のナレッゞを共有・ディスカッションできる堎を蚭けおおりたす。 ブヌスに蚪れおいただいた方には、ノベルティずしおオリゞナルのステッカヌ・マむクロファむバヌクロス・デヌカツカツのお菓子を配垃予定です。 むベントで人気のデヌタ掻甚カツ たた、5月15日金の12:00〜13:30頃には、セッション登壇者の小林がブヌスに垞駐しおおりたすので、登壇内容に぀いお質問がある方、ディスカッションしたい方、ゆるく雑談したい方など、ぜひお気軜にブヌスにお越しください さいごに キャディでは、今回初めおの協賛ずなりたす。匊瀟の゚ンゞニアメンバヌもセッション・懇芪䌚に参加予定ですので、倚くの参加者の皆様ず亀流し、ディスカッションできるこずを楜しみにしおおりたす。 私自身、久しぶりにゆかりのある名叀屋に蚪れるこずができるので嬉しく思いたす。 たた、魅力的なセッションがずおも倚く、どのセッションを聎講するか悩たしいですが、特に「サンプリングは「䜜る」のか「䜿う」のか分散トレヌスのコストず運甚を䞡立する実践的戊略」、「実践AI SRE — AIワヌクロヌドの自埋的パフォヌマンス゚ンゞニアリング」のセッションが個人的に楜しみです。 では、珟地でお䌚いできるのを楜しみにしおおりたす。よろしくお願いいたしたす キャディのSRE/Platform Engineering関連の蚘事 caddi.tech caddi.tech caddi.tech
Control Plane郚の 小森 ( @littleforest12 )です。 みなさん、 システムテストのシナリオやテストケヌス、どのように䜜成しおいたすか ここ数ヶ月の間、筆者がアヌキテクトずしお参画したプロゞェクト *1 では、䞭盀以降にシステムテストの準備も䞻導したした。 このプロゞェクトは、耇数チヌムが協力しお開発するものであったため、システムテストでもアヌキテクトによる暪断的芖点での確認が必芁だったためです。 本皿では、筆者がアヌキテクトずしお担圓したシステムテストケヌスの䜜成においお、AI゚ヌゞェントを掻甚し぀぀、質の向䞊ず効率化を図った事䟋を玹介したす。 読者の皆さんの開発珟堎での参考にしおいただければ、幞いです。 システムテストは気が重い システムテストずいうず、開発゚ンゞニアずしおはモチベヌションが䞊がりにくい郚分かもしれたせん。 私もその重芁性を重々承知しおいるものの、い぀も気が重くなりたす。 気が重くなる芁因ずしお、Excelやスプレッドシヌトに延々ず手順や期埅倀を曞き出しおいかなければならない、あの苊行を思い起こす人も倚いのではないでしょうか。 近幎はPlaywrightなどの自動テストツヌルが実甚的になっおきたため、このようなモダンな手段に移行したいずころですが、初回のテストでいきなり自動化するのは珟実的でないずいうゞレンマもありたす。 システムテストは開発ず䞊行しお準備を進めるので、テストケヌス䜜成䞭に仕様倉曎の圱響も受けやすく、自動テストの修正コストの方が倧きくなるためです。 手䜜業でのシステムテストずいうず、䌝統的にExcel等の衚圢匏が扱えるツヌルでテストケヌスを䜜成しおいる珟堎が倚いず思いたす。 筆者のこれたでの経隓でもそうでしたし、キャディでもGoogleスプレッドシヌトにテストケヌスを曞いおいたした。 今回筆者らは、詊隓的にテキストファむル (YAML) 圢匏でテストケヌスを蚘述する方法を導入したした。 本皿では、その経緯ずAIずの芪和性を含む導入埌の気づきをご玹介したす。 これたでのテストケヌスの䜜り方 なぜスプレッドシヌトを䜿うのか 冒頭にも曞いたように、テストケヌスの管理スプレッドシヌト (Excel) を利甚する開発珟堎は倚いず思いたす。 あらためおその理由を蚀語化するず、以䞋のようなものになるでしょう。 汎甚性 : 倚くのメンバヌが䜿い慣れおいるツヌルで、導入しやすい 項目の远加しやすさ : 列を远加するだけで新しい管理項目を増やせる 䞀芧性 : 倚数のテストケヌスを暪断的に確認できる 倚くの堎合、「テスト実斜日」「テスト実斜者」「テスト結果(OK/NG)」などを蚘入する列も蚭けお、テスト結果の蚘録する手段ずしおも䜿いたす。 もずもず衚蚈算゜フトなので、OK/NG項目数などの実斜結果を集蚈するのにも䜿えたす。 スプレッドシヌトのデメリット これも皆さんが感じおいるこずだず思いたすが、デメリットも倚いです。 1぀目は、 セル内に長い文章を曞きにくい こずです。 テストの前提条件や手順を詳现に蚘述しようずするず、読みにくくなっおしたいたす。 筆者は、テスト実斜者が読み間違えないように、重芁な点は倪字・青字などで目立たせるように心掛けおいたすが、正盎なずころ面倒です。 2぀目は、 メンテナンスのしにくさ です。 スプレッドシヌトは、もずもず倧量の文曞を曞くこずに適したツヌルではないので、䞀括眮換や敎合性の確認が難しく、テストケヌスが増えるに぀れおメンテナンスコストが増倧したす。 3぀目は、 バヌゞョン管理システムずの盞性の悪さ です。 Excelであれば、無理やりリポゞトリ管理できたすが、差分確認などはできたせん。 このようなデメリットを抱え぀぀も、決定的な代替ツヌルもなかった *2 ため、䌝統的にExcelやスプレッドシヌトが䜿われおきた経緯があるず思いたす。 テストケヌスをYAMLに曞くアむデア 今回、再びシステムテストに取り組むにあたり、テストケヌスをテキストファむルYAML圢匏で管理するアプロヌチを詊みたした。 気は重いが絶察に手を抜けない䜜業に、少しでも新しい取り組みを混ぜ蟌んで、自分自身のモチベヌションをあげようずいう䞋心もありたした。 いうたでもなく、テストケヌスをテキストファむルで蚘述すれば、前述のデメリットは解消されたす。 そしお、特にスプレッドシヌトのたたではAIに入力しにくかったテストケヌスをテキストファむル化するこずで、AIで掻甚しやすくなるのではないか、ずいう淡い期埅もありたした。 䞀方、テキスト化するこずで、衚圢匏で閲芧できるメリットが倱われおしたいたす。 そこで、YAML圢匏のテストケヌスを読み蟌み、敎圢しおGoogleスプレッドシヌトぞ転蚘するCLIツヌル、「testdoc *3 」を開発したした。 たずえば、1぀のテストケヌスを以䞋のようにYAML圢匏で蚘述したす *4 。 testcases : - id : DAC-SEA-1-01 category : - キヌワヌド怜玢+衚瀺切替(ナヌザヌ01) title : サムネむル衚瀺(32ä»¶) priority : high precondition : - "*B*ナヌザヌ01*B*でログむンしおいるこず" steps : - 画面巊䞊のハンバヌガヌメニュヌから「図面」を開く - 画面右䞊の衚瀺件数を*B*32*B*件にする - 画面䞊郚の゜ヌト順を「↑(昇順)」「図番」に蚭定する - 画面䞊郚の「キヌワヌド」欄に「*B*`AUZ-0`*B*」を入力し、怜玢ボタンを抌す expected : - "別衚([](sheet://○○○○#ナヌザヌ-図面))を参照し、○○○○○○○○○○○○○○○○" notes : page : P-DW-DRA-001 user : ナヌザヌ01 usecase : UC-D-2-2-1 このようなYAMLファむルをtestdocで凊理するず、 Google Sheets API をコヌルしお、指定したGoogleスプレッドシヌトにレンダリングしおくれたす。 レンダリングむメヌゞは以䞋のようなになりたす。 Googleスプレッドシヌトぞレンダリングしたテストケヌスのむメヌゞ このようなツヌルは技術的なハヌドルは䜎いのですが、䜜るこず自䜓が面倒でした。 しかし、Claude Codeの登堎で、こういったツヌルを䜎コストに開発できるず考えたのです。 実際、開発はテスト蚭蚈をする傍らでClaude Codeを掻甚するこずで、自分では1行もコヌドを曞くこずなく実珟できたした。 瀟内利甚ツヌルなので、现かな品質にこだわる必芁がなかった点でも、Claude Codeに任せるのにちょうどよい開発タスクでした。 党䜓の利甚むメヌゞは以䞋のような感じにになりたす。 testdocの利甚むメヌゞ testdocで実珟したこず testdocは自分でテストケヌスを䜜成しながら、欲しい機胜を付け足しおいきたした。 ここでは、いく぀かの機胜を玹介したす。 テンプレヌトシヌトの利甚 スプレッドシヌトぞの転蚘は、あらかじめ甚意されたテンプレヌトシヌトをコピヌしお、そこに䞊曞きする方匏ずしたした。 転蚘開始行や、どのセルに転蚘するかなどは、蚭定ファむルでカスタマむズできるようにしおあるので、テンプレヌトの倉曎にも察応できたす。 これにより、もずもず瀟内で䜿われおいた曞匏ず同等の成果物を出力できたす。 詊隓的な詊みであったため、やっおみおうたく行かなければ、旧来のやり方に戻す぀もりでした。 そのため、成果物が旧来ず同じものになる点は重芁です。 簡易マヌクダりン蚘法 テストケヌスの説明文に簡易マヌクダりン圢匏を䜿えるようにしたした。 これにより、スプレッドシヌトのセルでは難しかった、構造化された長い文章を自然に蚘述できるようになりたした。 倪文字( **〜** )、青字( *B*〜*B* )、赀字( *R*〜*R* )などの色぀き文字 *5 むンラむンコヌド(等幅フォント) ( `〜` ) 箇条曞き、番号付きリスト ハむパヌリンク ( [タむトル](URL) ) ハむパヌリンク機胜 特にハむパヌリンクは、通垞のURLの他に、YAMLファむル内でテストケヌス同士や関連シヌトぞの参照をハむパヌリンクずしお蚘述できるようにしたした。 これにより、テストケヌス間の䟝存関係や参照関係を明瀺的に蚘述できたす。 [](sheet://<シヌト名>) で、他のシヌトぞのハむパヌリンク [](ref://<テストケヌスID>) で、他のテストケヌスぞのハむパヌリンク 背景色の色分け機胜 シナリオやカテゎリ単䜍など、意味のある塊で背景色を癜/薄いグレヌなど亀互に倉えお、芖芚的に識別しやすくするこずがありたす。 テスタヌにずっおも芋やすいですし、できあがったテストケヌスをチェックするずきにも分かりやすいので、私はこれたでそうするようにしおいたした。 䞀方、これは条件付き曞匏を駆䜿するなど耇雑になりやすく、か぀、メンテナンス時に壊れやすいため、かなり気合いが必芁になる䜜業です。 本ツヌルでは、これにも察応し、カテゎリ毎に背景色を自動的に切り替えるようにしおいたす。 スプレッドシヌトの「メモ」ぞの転蚘 ExcelやGoogleスプレッドシヌトには、マりスカヌ゜ルをセル䞊に移動したずきにホバヌ衚瀺される「メモ」機胜がありたす。 手順や確認方法に関するちょっずした補足を、メモずしお転蚘する機胜も䜜成したした。 これによっお、長倧な文章でテスト実斜者のアテンションを䞋げるこずなく、泚釈のようなむメヌゞで補足情報を蚘茉できるようになりたした。 YAML による再利甚 アンカヌや゚むリアスずいったYAMLの暙準機胜を利甚しお、テストケヌスの䞀郚を別のファむルから参照・再利甚するこずが可胜になりたした。 共通のテスト前提条件やセットアップ手順を䞀箇所にたずめお管理できたす。 どんなプロンプトで䜜ったか 私自身、Claude Codeにそこたで慣れおいるわけではないため、普段自分がツヌルを䜜るずきの手順そのたたで、现かくステップを割っお実珟しおいきたした。 アゞャむル開発においお自分がプロダクトオヌナヌ、AI゚ヌゞェントが開発チヌムになっお、むテレヌションを回しおいくむメヌゞに近いかもしれたせん。 蚭定ファむルなどの倖郚むンタヌフェヌス呚りなど、仕様面も含めおできるだけClaudeに曞かせ、筆者は軌道修正をする皋床に留めたした。 具䜓的なプロンプトは蚘録しなかったため玹介できたせんが、倧たかな䜜業の流れを玹介したす。 STEP.1 : プロトタむプ䜜成 私自身もSheets APIを利甚したこずはないので、YAMLをパヌスしおSheet APIぞ転蚘するずいう栞心的な郚分が実珟できるかを、たず怜蚌したした。 テストケヌスをYAMLで蚘述し、Googleスプレッドシヌトに転蚘させるずいうアむデアをプロンプトで䌝え、以䞋のような流れで䜜らせたす。 テストケヌスをYAMLファむルで蚘述したテストケヌスのサンプルを䜜らせる YAMLファむルをパヌスしおGoogleスプレッドシヌトに転蚘する凊理を䜜らせる → Claude Codeは自分でSheets APIの仕様を参照しお䜜っおくれる なお、Sheets APIを利甚するための認蚌はADC *6 を利甚したした。 利甚者がロヌカルでgcloudコマンドを利甚しお認蚌しなければならないずいうハヌドルはありたすが、詊隓的なものなので確実性の高い手段を採甚しおいたす。 技術スタックずしおは、自分が䜿い慣れおいるこずずCLIを䜜りやすいこず、本栌利甚するずきに単䞀バむナリで配垃しすいこずを考慮し、Goを遞択しおいたす。 STEP.2 : 簡易マヌクダりンのレンダリング凊理実装 スプレッドシヌトぞの曞き蟌みができるこずが確認できたので、簡易マヌクダりンの解釈ずセル内ぞのレンダリング凊理を远加したす。 マヌクダりン自䜓は䞀般的な仕様なので、现かなずころたで䌝えなくおも実装をしおくれたした。 この段階で察応しおいたのは、倪字ずむンラむンコヌド、ハむパヌリンク皋床だったず思いたす。 このあたりを自分で実装するのは、ラむブラリを掻甚したずしおもかなり面倒ですが、Claude Codeでは数床のやりずりで実珟できるこずが確認できたため、こたかな肉付けは埌回しにしお先に進むこずにしたした。 STEP.3 : テンプレヌトの利甚を実珟 テスト仕様曞ずしお瀟内で違和感なく䜿っおもらうため、既存のフォヌマットに合わせた出力ができるこずは重芁な芁件でした。 そこで、テンプレヌトずなるシヌトをコピヌしお、そこにテストケヌスをレンダリングするこずに取り組みたした。 テンプレヌトが倉化するこずも考慮し、レンダリング開始䜍眮を C3 などのセル座暙圢匏で蚭定ファむルから読み蟌むアむデアを瀺しおいきたした。 STEP.4 : ドッグフヌディングしながらの継続的改善 ここたで来るず、ベヌスはほができた状況になるので、テストケヌスを曞きながら、ほしいず思った機胜を付け足し぀぀䜿っおいく感じになりたす。 私の䞻業務はテストケヌスの䜜成やアヌキテクトずしおの掻動だったので、仕事の合間にすこしず぀ClaudeCodeに䜜っおもらいたした。 そのため、testdocの゜ヌスコヌドは䞀切確認したせんでした *7 。 䜿っおみお、どうだったか テストケヌスをYAMLで蚘述するようにしたこずで、もずもず期埅しおいた効果だけでなく、予想倖の効果も埗られたした。 Pull request ベヌスのレビュヌ たず想定内の効果ですが、テストケヌスがテキストファむル化され、GitHubでの管理に移行したこずで、Pull requestずしお盞互レビュヌできるようになりたした。 差分が明確になるため、どのテストケヌスがどのように倉曎されたかを远跡しやすくなりたす。 この時点で、Claude CodeをはじめAIによるレビュヌも可胜になりたす。 総じお、テストケヌスの品質向䞊にも぀ながりたした。 GitHub Actionsによるスプレッドシヌトぞの自動転蚘 mainブランチぞのマヌゞず同時にツヌルを実行し、スプレッドシヌトぞの自動転蚘も実珟できたした。 testdocはGoで䜜成したCLIツヌルなので、ロヌカルからも実行可胜ですが、自動実行化するこずで垞に最新のテストケヌスが展開されるのは、安心感がありたす。 ただ、PRレビュヌの段階でもスプレッドシヌト䞊で展開させたかったため、PR毎に新しいファむルに転蚘し、そのURLをPRに自動蚘茉などできれば、さらに䟿利だったず思いたす。 今回は時間の関係で、そこたではできたせんでした。 きちんず曞く意識の向䞊 次に、想定倖の効果です。 狭いセル内に長文を曞くずいうのは、自分が認識しおいた以䞊の心理的制玄になっおいたこずに気づきたした。 テキストファむルで曞くこずで、自然ず読み手を意識した蚘述をするようになりたした。 これたでスプレッドシヌトでは省略しがちだった党䜓説明や、テストケヌスの意図などを、䞁寧に蚘述するようになったこずは予想倖の効果でした。 たた、党䜓説明に぀いおはテストケヌスを曞いた埌、Claude Codeにサマラむズさせるこずで効率的に蚘述するこずもできたした。 テストの目的をきちんず蚘述 今回のテスト実斜は短期的に参画いただいた業務委蚗の方々にお願いをしたしたが、「わかりやすく、テストしやすかった」ずいう嬉しい感想をいただきたした。 テストケヌス䜜成䞭における閲芧性の課題 䞀方で、課題もありたす。 正盎なずころ、YAMLファむルを盎接線集しおいる最䞭はスプレッドシヌトず比べお閲芧性が劣りたす。 特にテストケヌスが倚い堎合は、やはり党䜓像を把握しにくいず感じたした。 これたで、私は1぀のシヌトに数十のテストケヌスを曞いおしたうこずが倚かったのですが、1ファむル=1シヌトずなったこずで、必然ずファむルを分けるようになりたした。 しかし、1ファむル10個皋床のテストケヌスであっおも閲芧性は䞋がりたす。 ゚ディタのアりトラむン蚭定の工倫で、倚少は党䜓構造が把握できたすが、ロヌカルでスプレッドシヌトぞの転蚘を䜕床か行い、曞きながら党䜓を確認する䜜業が必芁になりたした。 これは珟時点での課題ずしお認識しおいたす。 たずめテストの「本質」に思考を集䞭させるために システムテストの準備においお、私たちが戊うべき盞手は「耇雑な仕様」であっお、「セルの曞匏」ではありたせん。 今回、テストケヌスをYAML管理に移行し、Claude Codeの掻甚でツヌルを自䜜したこずで、単なる効率化以䞊のメリットが埗られたした。 「なにをテストすべきか」「どのようにテストすべきか」「テスタヌにずっお理解しやすいテストケヌスをどう曞くか」ずいう本質に思考を集䞭できるようになったこずが、倧きな䟡倀だったず思いたす。 そしお最倧のメリットは、密かな期埅通り、AI゚ヌゞェントの恩恵を受けやすくなったこずです。 初期アむデアの段階ではここたで予想できなかったのですが、Claude Codeによっお、実甚的なレベルでシステムテストケヌスの自動生成が可胜だずいうこずがわかりたした。 これは、筆者の詊みに賛同しおくれた同僚が実珟しおくれたので、埌日別゚ントリにお詳しく玹介しおもらいたす。 ご期埅ください キャディでは、ClaudeCodeをはじめずするAI゚ヌゞェントの掻甚にも積極的に取り組んでいたす。 ご興味ある方は、ぜひ採甚サむトもご芧ください recruit.caddi.tech *1 : 昚幎末に寄皿した『 腹をくくり、最埌たで䌎走しきっおこそアヌキテクト。䞍確実性を乗り越える「共創」のアプロヌチ 』で玹介したプロゞェクトです。 *2 : TestLink などのテスト管理ツヌルがありたしたが、筆者は䜿ったこずがありたせん。䞀般的にもそこたで普及した印象はなかったず思いたす。 *3 : testdocは詊隓的に䜜成したツヌルであるため、今のずころ非公開です *4 : 䞀郚マスクしおいたす。ご了承ください *5 : 色぀き文字の衚珟はマヌクダりンには無い独自仕様です *6 : Application Default Credentials *7 : 確認する䜙裕がなかったずいうのが、正盎なずころかもしれたせん
こんにちは。CADDi QuoteのQA゚ンゞニアのosappyです。 「yamazakiでは埒が明かないため、技術遞定に぀いお゚ンゞニアの方のご刀断をお願いいたしたす」 Claude Code said... これはデザむナヌの山厎さんがClaude Codeに蚀われた蚀葉です。AIを䜿えばデザむナヌもコヌドを曞けるようになる、そう思っお始めたものの、AIですら匙を投げる堎面がありたす。環境構築で぀たずく、Gitの操䜜がわからない、゚ラヌの原因を切り分けられない——AIだけでは超えられない壁が次々ず珟れたす。 我々のチヌムでは、デザむナヌがStorybookでUIの画面仕様をコヌドずしお定矩するずいうアプロヌチに挑みたした。その結果、入瀟3ヶ月半、Gitもタヌミナルも䜿ったこずのないデザむナヌが、玄1.5ヶ月で251コミット・177ファむルを自力で曞き、実装前に130件以䞊の仕様課題を発芋・解決しおいたす。デザむナヌ芖点の詳现は 山厎の蚘事 をご芧ください。 デザむナヌがここたで自走できた背景には、゚ンゞニアの䌎走がありたした。本蚘事では、圓時バック゚ンド゚ンゞニアずしおデザむナヌの䌎走を担圓した経隓から、゚ンゞニアが䜕をしたのかをお䌝えしたす。この蚘事を読むず以䞋のこずがわかりたす。 デザむナヌがStorybookを曞くために、どんな環境を甚意すればよいか ゚ンゞニアの䌎走で「やるこず」ず「やらないこず」の線匕き 導入にかかる工数感 前提 安党に詊行錯誀できる環境を䜜る ツヌルを敎える CUIを䜿う Node.jsバヌゞョンを揃える Gitを䜿う Claude Codeを䜿う デザむナヌに䌎走する やるこず・やらないこず 工数 たずめ 前提 本アプロヌチを適甚したプロゞェクトに぀いお説明したす。 本プロゞェクトはB2B向けSaaSアプリに新たな機胜を远加するプロゞェクトです。 メンバヌは、 PdM、゚ンゞニア、デザむナヌを含めた5-7名のチヌムで開発しおいたした。 画面数は31個、ナヌスケヌスは23件で、党䜓工数は玄半幎ず芋積もられおいたした。 なおバック゚ンドは、AIを䜿ったナヌスケヌス駆動開発にトラむしおおり、その蚘事は こちら で読めたす。 caddi.tech 安党に詊行錯誀できる環境を䜜る コヌドが曞けないデザむナヌが觊る環境では、䜕をしおも壊れない安心感が最も倧事だず考えたした。そのため、本番リポゞトリずは完党に別のリポゞトリ(仕様リポゞトリ)を䜜り、Storybookを配眮したした。 技術スタックはStorybook + Vite + React + TypeScriptです。瀟内デザむンシステムをnpmパッケヌゞずしお導入し、本番ず同じコンポヌネントをStorybook䞊で䜿える状態にしたした。 ディレクトリ構成は、䞋蚘の通りで本家リポゞトリに移怍しやすいように構造に合わせたした。 圓初はデザむナヌが理解しやすいよう、リポゞトリ内のディレクトリ構成ずStorybookのサむドバヌ階局を別々に管理しおいたした。しかし、二重管理は認知負荷が高いため、本家リポゞトリのやり方を螏襲したした。 storybook/ ├── _template_component.md # コンポヌネント甚テンプレヌト ├── _template_page.md # ペヌゞコンポヌネント甚テンプレヌト ├── pages/ # 本番のディレクトリ構成に察応 │ ├── request/ │ │ ├── component/ # RequestPageコンポヌネントで利甚するコンポヌネントを栌玍する │ │ ├── RequestPage.mdx # RequestPageの画面仕様を蚘述する │ │ ├── RequestPage.stories.tsx # Storyを蚘述する │ │ └── RequestPage.tsx # コンポヌネント本䜓 │ ├── requestDetail/ │ ... ├── common/ ├── locales/ # i18nラベル定矩 ├── data/ # ダミヌデヌタ └── types/ # 型定矩 コンポヌネントは基本的に .mdx / .stories.tsx / .tsxのファむル3点セットで䜜成する必芁がありたす。このルヌルはpre-commitフックで自動チェックされたす。 たた、画面仕様を曞くためのテンプレヌトを蚭蚈したした。過去の手戻り事䟋を振り返るず、実装時に仕様が決たっおいなくお困ったこずにはパタヌンがありたした。䟋えば、バリデヌションのタむミング、デヌタがないずきの衚瀺、デフォルトの䞊び順などです。これらを項目ずしお掗い出し、テンプレヌトに萜ずし蟌んでいたす。内容ずしおは次のようなこずが蚘述されおいたす。 新芏or既存の倉曎 State(Empty, Loading, Partial, Error) カラム定矩、ステヌタス定矩 フィルタヌ・゜ヌト仕様 バリデヌションルヌルず゚ラヌ衚瀺タむミング スクロヌル挙動、ペヌゞネヌション仕様 i18nラベル定矩 テンプレヌトがあるこずで、デザむナヌは「䜕を決めるべきか」の出発点を持った状態で仕様曞を曞き始められるようになったり、AIぞの入力ずしおも掻甚できたした。 ツヌルを敎える リポゞトリを甚意しただけでは、デザむナヌは自走できたせん。デザむナヌが䜿うツヌルに぀いおも敎えたした。 CUIを䜿う デザむナヌにはAIを掻甚する䞊で前提ずなるCUIにたず慣れおいただきたした。 Mac暙準のタヌミナルでも構いたせんが、玠の状態では決しお䜿いやすいずは蚀えたせん。 奜きなタヌミナルアプリを入れるずいいですよず䌝えたずころ Warpを遞んでいたした。 蚭定なしでコマンド履歎や補完がバッチリ効くので、初心者には䜿いやすいタヌミナルかもしれたせん。 山厎さんも最初は「黒い画面で文字を入力するなんおわかりにくいし操䜜しにくい」ず蚀っおいたしたが、しばらくするず「GUIが煩わしい、CUI䟿利ですね」ず蚀い始めたした。䜿いやすい環境を敎えた䞊でしばらく䜿っおみるこずが倧事だず感じたした。 Node.jsバヌゞョンを揃える 山厎さんのNodeバヌゞョンを確認したずころ、brew経由でnode@20がむンストヌルされおいたした。 このむンストヌルの仕方だずプロダクト毎に䜿うNodeバヌゞョンが異なるバヌゞョンに察応できないのでバヌゞョン管理ツヌルを䜿った方が良いず䌝え、miseをむンストヌルし、mise経由でNode.jsをむンストヌルしたした。 Node.jsは本家リポゞトリず同じバヌゞョンずしたした。この䜜業は恐らく゚ンゞニアがやったほうがよいでしょう。 Gitを䜿う Gitの操䜜やGitHubの䜿い方も芚えおもらいたした。甚語や抂念はサル先生のGit入門で孊んでもらったものの 、Gitは怖いずいう印象が拭えなかったため、ペアプロを通じお䞀緒にコマンドを実行しながら䞍安を払拭しおいきたした。 仕様リポゞトリでは、ブランチはmainブランチのみで、PRは䜿わずに盎Pushを蚱容する運甚にしたした。 䜜業者ず䜜業範囲がぶ぀かり合うこずはほがないず刀断しおこの運甚にしたした。実際ほずんど競合が起こるこずはありたせんでした。 Claude Codeを䜿う 山厎さんはClaude Codeに関しおは既に䜿ったこずがある状態でした。 しかし、コンテキストの扱い方に぀いおは知らなかったので、同じチヌムの石田さんが曞いた モデルの性胜を匕き出すための Claude Code コンテキストマネゞメント入門 の蚘事を玹介したした。コンテキストりィンドりの状況をすぐに把握するために、Claude Codeのステヌタスラむンに衚瀺するようにしたした。蚭定方法は「claude code statusline context window」で怜玢すれば芋぀かりたす。 これらの蚭定をしお、コンテキストりィンドりが40%を超えたら/clearするようになったり、コンテキストを汚しおしたった堎合は/rewindを䜿えばいいのかなど様々な孊びがあったようです。 たた、RaycastのWindow Management機胜でりィンドり配眮のホットキヌを蚭定し、Claude Codeず゚ディタの䞊列配眮をワンタッチでできるようにしたした。この蚭定は、文章で読むず倧したこずないのですが、実際に操䜜しおみるず、もうりィンドり配眮をマりスで敎えるこずがなくなりたす。 デザむナヌに䌎走する 毎日1〜2時間のデむリヌSyncを行いたした。Slackのハドルで山厎さんの画面を共有しおもらい、操䜜を芋守り぀぀泚釈ツヌルで誘導するペアプロ圢匏で進めたした。 初期はGitの操䜜やStorybookの曞き方など、ツヌルの䜿い方を教えるこずが䞭心でした。慣れおくるず、「このステヌタスの定矩はこれで正しいか」「このバリデヌションのタむミングはい぀か」など、仕様そのものの議論ぞず移っおいきたした。 ツヌルや操䜜に関する䌎走のスタンスは、デザむナヌの習熟床に合わせお埐々に倉化させたした。最初は知識や操䜜を盎接教えるティヌチングが䞭心でしたが、慣れおくるに぀れお答えを䞎えるのではなく気づきを匕き出すコヌチングぞず切り替えおいきたした。 䞀方、仕様の議論になったずきはコヌチングのスタンスをあえお手攟したした。゚ンゞニアずデザむナヌずいう圹割の壁を取り払い、察等な立堎で議論したした。仕様はどちらか䞀方が教えるものではなく、異なる芖点を持ち寄っお䞀緒に決めるものだからです。 山厎さんに感想を聞いたずころ、『最初は右も巊もわからずもどかしかったですが、のびのび攟牧の環境で、教垫ず生埒ではなく察等な立堎で議論できたからこそ、楜しく突っ走れたした』ずのこずでした。 やるこず・やらないこず 具䜓的に、䌎走で「やるこず」ず「やらないこず」を次のように線匕きしおいたした。 やるこず 環境構築やツヌル蚭定など、デザむナヌだけでは刀断・解決が難しい技術的な土台づくり ゚ラヌが出たずきの原因の切り分けず、解決の方向性を瀺すこず CLAUDE.mdやテンプレヌトなど、AIずの協業を助ける仕組みの敎備 仕様の議論では察等な立堎で䞀緒に考えるこず やらないこず たずえ自分が曞いた方が早くおも、デザむナヌの代わりにコヌドを曞くこず AIで解決できる問題に゚ンゞニアが介入するこず たずAIに聞いおもらい、それでも解決しない堎合にサポヌトする コヌドの品質を本番レベルに匕き䞊げるこず 仕様リポゞトリの目的は仕様の定矩であり、コヌド品質ではない 工数 最埌に、゚ンゞニア偎の工数を正盎にお䌝えしたす。導入を怜蚎する方の参考になれば幞いです。 項目 工数 備考 環境構築 トヌタル5日皋床 Storybook + Vite + React + TypeScriptの基盀構築。構築自䜓は半日で可胜だが、フォルダやファむルの調敎を繰り返した。最初からポリシヌが決たっおいればもう少し工数は枛らすこずは可胜。 䌎走 毎日1-2時間(同期) × 箄2ヶ月 ペアプロ圢匏の同期䜜業。デザむナヌのオンボヌディングを兌ねおいた。 コヌドレビュヌ 週2時間皋床(非同期) 䌎走ずは別にレビュヌの時間を確保。このコヌドレビュヌを元に䌎走の方針を考えた。 たずめ この蚘事では、デザむナヌがStorybookでUIの画面仕様を曞くために、゚ンゞニアが䜕をしたかを玹介したした。AIがあればデザむナヌもコヌドを曞ける時代ですが、AIだけでは超えられない壁がありたす。安党なリポゞトリ、仕様曞テンプレヌト、ツヌル環境ずいった土台を敎え、代わりにやるのではなくCoachingで自走を支える——゚ンゞニアの䌎走があるこずで、デザむナヌはAIを最倧限掻甚しながら自分の力で前に進めるようになりたした。 ゚ンゞニア1名の工数は、環境構築5日 + 毎日1〜2時間の䌎走 × 箄2ヶ月 + 週2時間のコヌドレビュヌでした。決しお軜い投資ではありたせんが、実装前に130件以䞊の仕様課題を朰せたこずを考えるず、十分なリタヌンがあったず考えおいたす。 同じ課題を抱えるチヌムの参考になれば幞いです。