KINTOテクノロゞヌズのブログ - TECH PLAY

TECH PLAY

KINTOテクノロゞヌズ

KINTOテクノロゞヌズ の技術ブログ

å…š1132ä»¶

この蚘事は KINTOテクノロゞヌズアドベントカレンダヌ2025 の3日目の蚘事です🎅🎄 はじめに はじめたしお。KINTOテクノロゞヌズでAndroidアプリ開発を担圓しおいるJongSeokです。 Claude Codeを䜿っおAndroid開発をしながら、SubAgents機胜は少し䜿っおいたした。 䜿っおいるうちに、もっず効率よく䜿えるんじゃないかず思い始めお、いろいろ調べおみたした。 そしたら最近発衚された Skills ずいう機胜も芋぀けたした。 この機䌚に SubAgents ず Skills、䞡方詊しおみたので、その内容をたずめおみたした。 1. SubAgents? 䞀蚀で蚀うず 「別の䜜業スペヌスを持぀専門家」 です。 普通にClaude Codeず䌚話するず、すべおが䞀぀のコンテキスト䌚話の流れに入りたす。 でもSubAgentsは別のコンテキストで䜜業しお、結果だけ報告しおくれたす。 チヌムで䟋えるず、リヌダヌが専門家に仕事を任せお結果報告を受けるむメヌゞですね。 1.1 䞻な特城 特城 説明 独立したコンテキスト メむンの䌚話を汚さない 専門化されたプロンプト 圹割に特化した指瀺を蚭定できる ツヌル暩限の制限 必芁な機胜だけ蚱可できる 1.2 䜜り方 SubAgentsを䜜る方法は2぀ありたす。 1. コマンドで䜜成掚奚 Claude Codeでは /agents コマンドで簡単に䜜成できたす。 List Make Projectに定矩されおいるAgentsの確認や、新芏䜜成ができたす。 2. 盎接ファむルを䜜成 .claude/agents/ フォルダに .md ファむルを远加しお䜜るこずもできたす。 1.3 掻甚䟋kotlin-method-namer Kotlinでメ゜ッド名を考えるのは意倖ず悩むポむントです。 そこで、Android/Kotlinのスタむルに合ったメ゜ッド名を提案しおくれるSubAgentを䜜っおみたした。 どんな時に䜿う メ゜ッドの機胜を英語でどう衚珟するか迷う時 Kotlinの呜名芏則に合っおいるか確認したい時 より良いメ゜ッド名の候補が欲しい時 --- name: kotlin-method-namer description: Expert for suggesting Android/Kotlin method names tools: Read, Glob, Grep model: sonnet color: cyan --- You are an expert Android Kotlin developer specializing in creating clear, idiomatic method names. ... ( Full version ) DEMO SubAgentsは盎接指定しお呌ぶ必芁がありたす。 color: cyan を蚭定したので、Agentが実行されおいるのが分かりたす。 DEMOの結果 initializeVariable() ずいう名前を提案しおくれたした。 このように、SubAgentsは特定の䜜業に特化したAgentsを䜜れたす。 繰り返し発生する専門的な䜜業があれば、SubAgentsにしおみるず効率が䞊がるかもしれたせん。 2. Skills? 䞀蚀で蚀うず 「自分だけの業務ガむドブック」 です。 SubAgentsが別の䜜業スペヌスを持぀専門家だずすれば、 Skillsはメむン゚ヌゞェントに専門知識を远加するむメヌゞです。 Claudeが䜜業する時に参考にするガむドブックを事前に䜜っおおくず、 関連する䜜業を䟝頌した時に自動で認識しお䜿っおくれたす。 2.1 䞻な特城 特城 説明 メむンコンテキストに統合 SubAgentsず違い、別空間ではなくメむンの䌚話で動䜜 自動認識 (Auto-invoked) 関連する䜜業を䟝頌するず、Claudeが自動で䜿甚 Progressive Disclosure 必芁な情報だけを段階的にロヌド Deterministic スクリプト実行で䞀貫性のある結果を保蚌 2.2 Progressive Disclosureずは Skillsの栞心ずなる蚭蚈原則です。 䞀床にすべおの内容をロヌドせず、段階的に必芁な情報だけを取埗したす。 段階 ロヌドされる内容 タむミング 1段階 name , description 起動時にシステムプロンプトぞロヌド 2段階 SKILL.md 本文 関連する䜜業を䟝頌した時 3段階 远加ファむル (scripts, references など) 必芁な時だけ 敎理されたガむドブックのように、目次 → 該圓チャプタヌ → 付録の順で必芁なものだけ読む方匏です。 これにより、 耇数のSkillsをむンストヌルしおもコンテキストを無駄にせず䜿えたす。 2.3 䜜り方 .claude/skills/ フォルダ内にスキルフォルダを䜜成し、 SKILL.md ファむルを远加したす。 project/ └── .claude/ └── skills/ └── your-skill-name/ └── SKILL.md SKILL.md --- name: wildcard-import-fixer description: Converts wildcard imports (e.g., import java.util.*) to specific imports in Kotlin/Java files. allowed-tools: Bash, Read, Glob, Grep --- YAML Frontmatter 項目 ルヌル 必須 name 小文字 + ハむフン䜿甚、64文字以䞋 ✅ description 200文字以䞋、Claudeがい぀䜿うか刀断する重芁な郚分 ✅ version バヌゞョン管理甚 (䟋: 1.0.0) - SKILL.md 本文 500行以䞋掚奚 長くなったら別ファむルに分離 (䟋: reference.md , scripts/ ) セキュリティ APIキヌ、パスワヌドなどの機密情報をハヌドコヌディング犁止 信頌できる゜ヌスのスキルのみむンストヌル 💡 SubAgentsずの違い SubAgents: .claude/agents/ファむル名.md (ファむル単䜍) Skills: .claude/skills/スキル名/SKILL.md (フォルダ単䜍) 2.4 掻甚䟋: wildcard-import-fixer 💡 Skillsではスクリプトを実行できたす。 今回はAndroidプロゞェクトなのでKotlinを䜿甚したしたが、Python、JavaScriptnpmなども察応しおいたす。 Kotlinでよくある wildcard import ( import java.util.* ) を個別のimportに倉換するSkillを䜜っおみたした。 どんな時に䜿う wildcard importを敎理したい時 コヌド品質を改善したい時 import文を明確にしたい時 フォルダ構成 .claude/skills/wildcard-import-fixer/ ├── SKILL.md ← 必須 ├── scripts/ │ └── fix-wildcards.kts ← 任意自分で远加 ├── templates/ │ └── report_template.html ← 任意自分で远加 ├── backups/ ← 自動生成スクリプト実行時 └── reports/ ← 自動生成スクリプト実行時 💡 必須なのは SKILL.md だけです。 その他のファむルやフォルダは甚途に合わせお自由に構成できたす。 なぜスクリプトを䜿う LLMにコヌドを毎回生成させるず、結果が埮劙に倉わるこずがありたす。 でもスクリプトを事前に甚意しおおけば、 毎回同じ結果 が保蚌されたす。 これがSkillsの Deterministic な特城です。 SKILL.md --- name: wildcard-import-fixer description: Converts wildcard imports (e.g., import java.util.*) to specific imports in Kotlin/Java files. allowed-tools: Bash, Read, Glob, Grep --- # Wildcard Import Fixer Automatically converts wildcard imports to specific imports in Kotlin and Java files by analyzing actual class usage in the code. ## Instructions ### Step 1: Analyze the Request When a user asks to fix wildcard imports: 1. Determine the scope (entire project, specific directory, or single file) 2. Decide if a dry-run preview is appropriate first 3. Check if backups should be created ### Step 2: Run the Fixer Script Execute the appropriate command based on the scope... ### Step 3: Review Results After running, check the console output and HTML report... ### Step 4: Handle Edge Cases If no usage is detected, suggest removing the unused import... ( Full version ) 💡 このようにStep圢匏で指瀺を曞くず、Claudeが順番通りに䜜業を進めおくれたす。 DEMO このデモでは、䞀床実行した埌に /clear で䌚話をリセットしお、もう䞀床同じ䜜業を䟝頌しおいたす。 /clear しおもSkillsの name ず description は再ロヌドされるProgressive Disclosure スクリプト実行なので、 毎回同じ結果 が返っおくるDeterministic これがSkillsの匷みです。 DEMOの結果 結果を䞀目で確認しやすくhtmlにもするようにしたした。 3. SubAgents vs Skills SubAgents : 別宀で䜜業する専門家。結果だけ報告しおくれる。 Skills : 手元に眮いおおくマニュアル。必芁な時に参照しお䜜業する。 3.1 比范衚 項目 SubAgents Skills コンテキスト 独立別の䜜業スペヌス メむンに統合 呌び出し方 盎接指定しお呌ぶ 自動認識Auto-invoked ファむル構成 .claude/agents/ファむル名.md .claude/skills/スキル名/SKILL.md 単䜍 ファむル単䜍 フォルダ単䜍 スクリプト実行 ❌ ✅ 向いおいる䜜業 耇雑なワヌクフロヌ、䞊列䜜業 繰り返しのルヌティン䜜業 3.2 䜿い分け SubAgentsを䜿う堎面 コヌドレビュヌなど、専門的な芖点が必芁な時 メむンの䌚話を汚したくない時 耇数のステップがある耇雑な䜜業 Skillsを䜿う堎面 同じ䜜業を繰り返す時 䞀貫した結果が欲しい時Deterministic 耇数のプロゞェクトで再利甚したい時 3.3 組み合わせお䜿う SubAgentsずSkillsは競合するものではなく、 補完関係 にありたす。 䟋: PRレビュヌの自動化 compose-reviewer (SubAgent) がComposeコヌドをレビュヌ kotlin-style-checker (Skill) でスタむルチェック test-generator (SubAgent) がテストコヌドを生成 SubAgentが専門的な刀断を、Skillが䞀貫したルヌルチェックを担圓したす。 4. たずめ 今回SubAgentsずSkillsを詊しおみお、䜿い分けが少し芋えおきたした。 こんな時は 䜿うもの 専門的な芖点でレビュヌしおほしい SubAgents メむンの䌚話を汚したくない SubAgents 同じ䜜業を毎回同じ結果で実行したい Skills スクリプトで自動化したい Skills 䞡方必芁な耇雑なワヌクフロヌ 組み合わせ ただ䜿い始めたばかりですが、繰り返しの䜜業はSkillsに、専門的な刀断が必芁な䜜業はSubAgentsに任せるず効率が䞊がりそうです。 興味がある方はぜひ詊しおみおください References SubAgents SubAgents - Claude Docs Skills Agent Skills - Claude Docs Equipping agents for the real world with Agent Skills anthropics/skills - GitHub 比范 Skills explained - Claude Blog
Hello, I'm Moriya (emim) from the Engineering Office. In this article, I'll be reporting on the topic mentioned in the title as a cross-post for December 2nd of both the KINTO Technologies Advent Calendar 2025 and the Accessibility Advent Calendar 2025 . I work in the Engineering Office, a division dedicated to strengthening our organization’s development capabilities, where I focus on design. Alongside that, as a personal ongoing activity, I engage in advocacy to raise awareness about digital accessibility. I was amazed by a staff member who spontaneously did some wonderful accessibility work, and I asked him about what he did and what motivated him. Who Added Alt Text to the X (formerly Twitter) Post!? First, please take a look at the following post. https://x.com/KintoTech_Dev/status/1976163362016043509?s=20 Does it just look like an introduction to our Fukuoka office? Take a close look: the attached photo has been given wonderfully thoughtful alt text. ![KINTOテクノロゞヌズの10月9日のX投皿に4枚の写真が添付されおいお、すべおに「ALT」ボタンが衚瀺されおいる様子のキャプチャヌ](/assets/blog/authors/emim/2025-12-02-SNSA11y/2025-12-02-SNSA11y_post1.png =600x) ![ビルの写真に「KINTOテクノロゞヌズの犏岡オフィスが入居する犏岡倧名ガヌデンシティのビル倖芳」ず代替テキストが付いおいるのをポップアップしたずころ](/assets/blog/authors/emim/2025-12-02-SNSA11y/2025-12-02-SNSA11y_post2.png =500x) We have a chat channel called team-accessibility within the company where we regularly share information. However, the person who made this post wasn't someone who actively participated in those discussions, so I was absolutely astonished. Someone unexpectedly added proper alt text!!! I spoke with the following two people for this article: Takenaka Background: After 12 years of development and PM experience at a system integrator, worked as a Scrum Master for in-house development at a bank. Currently serves as manager of the Developer Relations Group. Is the one who made the X post Yukachi Background: First job was in the travel industry; moved to IT after being hit by the COVID-19 pandemic. At KINTO Technologies, originally handled accounting work, then over time transitioned to a dedicated role in the Developer Relations Group, handling event management and social media outreach. Is very interested in accessibility recently About the Alt Text in This Post The alt text added to these four images in the post. One screen reader user commented that it was high quality and wonderful, very readable (or rather, easy to listen to), and described it with an abstract expression as alt text that feels like a gentle breeze. So I asked Takenaka why he added alt text this time, and received the following response. —— (Takenaka) I had heard of digital accessibility, but didn't really understand what it meant. This time, the ALT button happened to stand out when I was posting on X, and I'd been exposed to accessibility information daily through the team-accessibility chat. I'd also heard it was gaining attention, so I gave it a go. I’d been putting things out there without knowing who’d see them, and it’s wild that they had a subliminal impact here! I also asked if they had any difficulty writing it. —— (Takenaka) I understood that I needed to write it, but I didn’t know how. So right before, I did a quick internet search and tried to keep it concise, making sure not to include anything outside the main text. I only found out how it would actually appear after checking the published post. I understood that this is a feature often overlooked unless you pay attention. For people familiar with accessibility, the button labeled ALT may be visible at a glance, but it’s important to keep in mind that some people won’t notice it at all. Insights Gained Through Alt Text Isn’t it wonderful to imagine a world where even those who aren’t very aware of accessibility add alternative text? I was both surprised and touched, so I posted about how I tracked down who had added it internally, and that post received quite a lot of likes. https://x.com/emim/status/1977921547869561149?s=20 When I shared the feedback again, Yukachi was really moved. She’s not an engineer, so she usually doesn’t show up in the accessibility chat. I asked both of them again about these responses. —— (Takenaka) I was surprised it became a topic, and I realized that even alt text alone could spark reactions. —— (Yukachi) I simply wasn't aware that you could add alt text, and I learned for the first time that adding it helps some people. Accessibility was something I’d never really thought about, but now I’m curious if there’s something I can do too. Hearing these words, I felt I'd received answers that clearly showed how even small things, when communicated as feedback, can influence people's behavior. She also added the following opinion. —— (Yukachi) I think it's important, but since I don't know what to do, it would be nice to have more learning opportunities that even beginners can understand. In recent years, accessibility-related study groups have certainly increased compared to the past. However, one of the industry’s challenges is that they tend to skip the basics and cater more to advanced participants. On the other hand, the Digital Agency released the Digital Society Promotion Standard Guidelines in October, which includes DS-672.1 Web Accessibility Guidebook for Public Relations, summarized for PR personnel (accessibility beginners). https://www.digital.go.jp/resources/standard_guidelines We’re planning to use these publicly available materials to organize study sessions for the Developer Relations Group. After checking with the Digital Agency, we received confirmation that we’re free to use them as much as we like. If we have the capacity, we’d also like to invite external participants to join these sessions. So please look forward to what we’ll be doing next year!
This article is the Day 2 entry of the KINTO Technologies Advent Calendar 2025 . Introduction Hello! I'm high-g ( @high_g_engineer ) from the Master Maintenance Tool Development Team in the KINTO Backend Development Group, KINTO Development Division at Osaka Tech Lab. In modern frontend development with heavy API integration, have you ever experienced challenges like these? Manually writing API type definitions often leads to missed updates when the spec changes Auto-generated files scattered everywhere often make it unclear where to import from Team members interpreting directory structures differently often lead to debates during code reviews The keywords to solve these challenges are type safety , schema-driven , auto-generation , and directory design . This article introduces an approach where OpenAPI serves as the single source of truth for auto-generating type-safe code, managed according to Feature-Sliced Design rules. Specifically, we'll walk through what code Orval generates and explain effective design patterns aligned with Feature-Sliced Design's directory structure. What This Article Covers The flow of outputting types and custom hooks from OpenAPI using Orval Detailed examples of the code Orval generates Feature-Sliced Design's layer structure and import rules Design patterns for managing Orval-generated code within Feature-Sliced Design's directory structure Target Audience Frontend developers tired of manually managing REST APIs and type definitions Developers using TypeScript + React Those interested in designs resilient to API changes Those interested in establishing directory structure rules Foundational Knowledge OpenAPI OpenAPI is a standard for defining HTTP APIs in a machine-readable format. By describing API specifications in YAML or JSON, you gain benefits like: Clearly defined API inputs and outputs Automated documentation generation Prevention of discrepancies between client and server Example: Partial OpenAPI Definition (Simplified) openapi: 3.1.0 paths: /posts: get: summary: Get list of posts parameters: - name: page in: query schema: type: integer responses: "200": description: Success content: application/json: schema: $ref: "#/components/schemas/GetPostsResponse" post: summary: Create a post requestBody: content: application/json: schema: $ref: "#/components/schemas/CreatePostRequest" responses: "201": description: Created content: application/json: schema: $ref: "#/components/schemas/CreatePostResponse" /posts/{postId}: put: summary: Update a post parameters: - name: postId in: path required: true schema: type: string requestBody: content: application/json: schema: $ref: "#/components/schemas/UpdatePostRequest" responses: "200": description: Success content: application/json: schema: $ref: "#/components/schemas/Post" delete: summary: Delete a post parameters: - name: postId in: path required: true schema: type: string responses: "204": description: No Content components: schemas: Post: type: object required: [id, title, createdAt, updatedAt, status] properties: id: type: string title: type: string body: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time status: type: string enum: [draft, published, archived] GetPostsResponse: type: object properties: items: type: array items: $ref: "#/components/schemas/Post" total: type: integer page: type: integer CreatePostRequest: type: object required: [title] properties: title: type: string body: type: string CreatePostResponse: allOf: - $ref: "#/components/schemas/Post" - type: object properties: createdBy: type: string UpdatePostRequest: type: object properties: title: type: string body: type: string status: type: string enum: [draft, published, archived] This YAML defines the following: /posts endpoint: list retrieval (GET) and creation (POST) /posts/{postId} endpoint: update (PUT) and deletion (DELETE) About Schema-Driven Development Problems with Traditional Manual Management Previously, frontend developers performed tasks like these manually: // Manually writing type definitions type Post = { id: string; title: string; body?: string; createdAt: string; updatedAt: string; status: "draft" | "published" | "archived"; }; // Manually writing API calls const getPost = async (id: string): Promise<Post> => { const response = await fetch(`/api/posts/${id}`); return response.json(); }; This approach has the following problems: Cost of manual updates Check OpenAPI → manually update type definitions → update all usage sites Risk of missed updates Type definitions and actual API specs get out of sync Easy to miss updates when the same type is used in multiple places Documentation and code desynchronization OpenAPI ≠ implementation code can happen The Schema-Driven Development Approach To address these manual management problems, a development methodology emerged: define the schema (API specification) first, then proceed with implementation. Traditional: Implementation → Documentation (afterthought) → Discrepancies with spec Schema-driven: Schema definition → Auto-generation → Implementation → Done (Implementation = Documentation, always in sync) Characteristics of Schema-Driven Development Implementation = Documentation : API specs and code are always synchronized Type safety : API inconsistencies detected at compile time Development efficiency : No manual type definition work Team collaboration : Both frontend and backend reference the same OpenAPI Orval Orval is a tool that auto-generates TypeScript type definitions and custom hooks with a single command from OpenAPI specifications. Main Features of Orval Feature Description Auto-generated type definitions Automatically creates types for API requests and responses Auto-generated custom hooks Also auto-generates hooks for TanStack Query and others Multiple library support Supports not just TanStack Query but also Axios and other libraries Mock generation Can also generate mock data for testing Benefits of Using Orval Time savings : Zero time spent hand-writing type definitions or API call code Error prevention : Eliminates typos and spec misreadings from manual writing Always current : Just regenerate when OpenAPI is updated to stay current Orval's Role in Schema-Driven Development Summarizing the content so far, Orval's role in schema-driven development is as follows: OpenAPI (single source of truth) ↓ Auto-generation by Orval keeps type definitions + TanStack Query hooks always in sync ↓ Low-cost, type-safe development is possible Feature-Sliced Design As mentioned at the beginning, the ongoing project adopts Feature-Sliced Design as an architectural pattern for frontend code organization. Feature-Sliced Design is an architecture that organizes the codebase using three concepts: Layers , Slices , and Segments . Concept Description Examples Layer Division by application responsibility. From top: app → pages → features → entities → shared (5 layers). app handles routing and layouts for the entire app, pages handles screens corresponding to URLs app/ , pages/ , features/ Slice Division unit by business domain or feature within each layer features/auth/ , entities/user/ Segment Division by technical role within a slice ui/ , model/ , api/ src/ ├── features/ ← Layer │ ├── auth/ ← Slice │ │ ├── ui/ ← Segment │ │ ├── model/ ← Segment │ │ └── index.ts This structure clarifies where to put what, enabling the team to unify code placement rules. Feature-Sliced Design Directory Structure Our team operates with the following directory structure. The segment divisions ( api/ , model/ , ui/ , etc.) are customized to fit the project. workspaces/typescript/src/ ├── app/ ← ① Application layer: routing, global settings │ ├── layouts/ Layouts used across all pages │ ├── routes/ Routing definitions │ └── App.tsx Root tsx file │ ├── pages/ ← ② Pages layer: each page component (corresponds to URL) │ ├── users/ │ └── login/ │ ├── features/ ← ③ Features layer: reusable business logic │ ├── {slice}/ Divided by domain into units called slices (e.g., user, auth) │ │ ├── {component}/ Components belonging to the domain │ │ │ ├── model/ Logic portion │ │ │ ├── ui/ UI portion │ │ │ └── index.ts Public API (barrel file) │ │ ... │ ... │ ├── entities/ ← ④ Entities layer: business domain definitions │ ├── user/ Various domains │ │ ├── @x Cross-import notation *described later │ │ ├── api/ Imports and uses auto-generated files from shared/ (facade) │ │ │ ├── hooks.ts API hooks │ │ │ └── index.ts Public API (barrel file) │ │ ├── model/ Domain logic │ │ ├── ui/ Minimal UI staying within the domain │ │ └── index.ts Public API (barrel file) │ ... │ └── shared/ ← â‘€ Shared layer: project-independent utilities ├── api/ │ └── generated/ Auto-generated files by Orval (modification prohibited) │ ├── types.ts │ ├── hooks.ts │ └── client.ts ├── config/ Configuration constants ├── errors/ Commonly used error functions ├── lib/ Utility functions └── ui/ Generic UI components Feature-Sliced Design Layer Import Restriction Rules The most important rule of Feature-Sliced Design: A layer can only import from layers below itself. Additionally, mutual imports between the same layer are also prohibited in principle (exception described later with @x notation). app ← Top level (highest abstraction) ↓ import allowed pages ↓ features ↓ entities * shared can be imported from any layer This means the following rules are established within the project: ✅ pages/ can import from features/, entities/, shared/ ✅ features/ can import from entities/, shared/ ✅ entities/ can import from shared/ ❌ entities/ must not import from features/ or pages/ ❌ shared/ must not import from any other layer Special Role of the Entities Layer: entities/@x (Cross-Import Notation) However, in the entities layer, business domains often relate to each other. For example, cases like "Post references User" occur. To solve this, a special import method allowed only within the entities layer is the @x notation. Directory Structure Example entities/ ├── user/ │ ├── @x/ │ │ └── post.ts # Types/functions exposed for external slices │ ├── model/ │ │ └── types.ts # Type definitions used internally │ ├── ui/ │ └── index.ts # Normal public API │ └── post/ ├── model/ │ └── usePost.ts # Wants to reference user's types from here └── index.ts Usage Example // When using entities/user from entities/post/model/usePost.ts // ❌ Normal import (Feature-Sliced Design violation: import between same layer) import type { User } from "@/entities/user"; // ✅ Cross-import using @x (allowed) import type { User } from "@/entities/user/@x/post"; // The @x directory represents "cross-import-specific API that this slice exposes externally." By using @x , it becomes explicit that something is intentionally exposed externally, making dependency tracking easier. Now that we've covered the foundational knowledge, let's get into the main topic. How to Use Orval and Output Code Setup The ongoing project uses pnpm as the package manager. Also, we'll proceed assuming OpenAPI is already defined. # Install Orval pnpm add -D orval Next, create the Orval configuration file. Note: hooks are defined to format auto-generated code with Biome. // orval.config.ts import { defineConfig } from "orval"; const API_DIR = "./src/shared/api"; const INPUT_DIR = "../../docs/api"; const GENERATED_DIR = `${API_DIR}/generated`; export default defineConfig({ postApi: { hooks: { afterAllFilesWrite: "pnpm format:write:generate", }, input: { target: `${INPUT_DIR}/openapi.yaml`, }, output: { clean: true, biome: true, client: "react-query", override: { mutator: { path: `${API_DIR}/customInstance.ts`, name: "useCustomInstance", }, query: { useSuspenseQuery: true, version: 5, }, }, schemas: `${GENERATED_DIR}/model`, target: `${GENERATED_DIR}/hooks/index.ts`, }, }, }); Next, create a custom instance that executes API requests. This is used as the mutator specified in the Orval configuration. // src/shared/api/customInstance.ts import { ApiHttpError, type ErrorDetail } from "../errors"; import { getAccessToken } from "../lib"; const BASE_URL = import.meta.env.VITE_API_BASE_URL || ""; // Type definition for request configuration export type RequestConfig = { url: string; method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; headers?: Record<string, string>; params?: Record<string, unknown>; data?: unknown; signal?: AbortSignal; }; // Request function using Fetch API const fetchApi = async <T>(config: RequestConfig): Promise<T> => { const { url, method, headers = {}, params, data, signal } = config; // Get authentication token const token = getAccessToken(); // Build query parameters const queryString = params ? `?${new URLSearchParams(params as Record<string, string>).toString()}` : ""; const fullUrl = `${BASE_URL}${url}${queryString}`; // Build headers const requestHeaders: Record<string, string> = { "Content-Type": "application/json", ...headers, }; if (token) { requestHeaders.Authorization = `Bearer ${token}`; } // Build request options const options: RequestInit = { method, headers: requestHeaders, signal, }; if (data && ["POST", "PUT", "PATCH"].includes(method)) { options.body = JSON.stringify(data); } const response = await fetch(fullUrl, options); // Error handling if (!response.ok) { let errorMessage = `API error: ${response.status}`; let errorDetails: ErrorDetail[] = []; try { const errorData = await response.json(); errorDetails = errorData?.errors?.details ?? []; if (typeof errorData.message === "string") { errorMessage = errorData.message; } } catch { // Use default message if JSON parsing fails } throw new ApiHttpError({ status: response.status, message: errorMessage, details: errorDetails, }); } // For 204 No Content if (response.status === 204) { return null as T; } return response.json(); }; // Custom instance function used by Orval export const useCustomInstance = <T>(config: RequestConfig): Promise<T> => { const controller = new AbortController(); const promise = fetchApi<T>({ ...config, signal: controller.signal, }); // For TanStack Query's cancel functionality // @ts-expect-error dynamically adding cancel property promise.cancel = () => controller.abort(); return promise; }; export default useCustomInstance; This useCustomInstance is used when executing HTTP requests within the hooks that Orval generates. You can centralize project-specific settings here, such as attaching authentication tokens and error handling. In actual projects, token refresh processing and retry logic are often added. For details, see the Orval Official Documentation - Custom Client . All that’s left is to run the code generation. # Run code generation pnpm orval In the ongoing project, we periodically run pnpm orval to batch-apply API spec changes. Actual Examples of Orval-Generated Code Now let's look at specific examples of what Orval actually generates. Generated Output 1: Type Definitions From OpenAPI's Post schema, TypeScript types like the following are auto-generated. // src/shared/api/generated/types.ts // ↓ Auto-generated from OpenAPI export type Post = { id: string; title: string; body?: string; createdAt: string; // ISO 8601 format updatedAt: string; status: "draft" | "published" | "archived"; }; export type GetPostsResponse = { items: Post[]; total: number; page: number; }; export type CreatePostRequest = { title: string; body?: string; }; export type CreatePostResponse = Post & { createdBy: string; }; export type UpdatePostRequest = { title?: string; body?: string; status?: "draft" | "published" | "archived"; }; Important Points OpenAPI schemas become types directly enum is converted to TypeScript Union Types Required/optional ( ? ) distinction is automatically determined Since it's a generated file, do not modify it (will be overwritten on next run) Generated Output 2: TanStack Query Custom Hooks Orval also auto-generates TanStack Query hooks. The following is a simplified example for easier understanding (actual generated code includes custom instances and detailed type definitions). // src/shared/api/generated/hooks.ts // ↓ Orval generates TanStack Query hooks (simplified example) import { useSuspenseQuery, useMutation } from "@tanstack/react-query"; import type { UseSuspenseQueryOptions, UseMutationOptions, } from "@tanstack/react-query"; import type { Post, GetPostsResponse, CreatePostRequest, CreatePostResponse, UpdatePostRequest, } from "./model"; import { useCustomInstance } from "../customInstance"; type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1]; // GET request → useSuspenseQuery hook export const useGetPosts = < TData = Awaited<ReturnType<ReturnType<typeof useCustomInstance<GetPostsResponse>>>>, TError = Error, >( options?: { query?: Partial<UseSuspenseQueryOptions<GetPostsResponse, TError, TData>>; request?: SecondParameter<ReturnType<typeof useCustomInstance>>; } ) => { const customInstance = useCustomInstance<GetPostsResponse>(); return useSuspenseQuery({ queryKey: ["posts"], queryFn: () => customInstance({ url: `/api/posts`, method: "GET" }), ...options?.query, }); }; // POST request → useMutation hook export const useCreatePost = <TError = Error, TContext = unknown>( options?: { mutation?: UseMutationOptions<CreatePostResponse, TError, CreatePostRequest, TContext>; request?: SecondParameter<ReturnType<typeof useCustomInstance>>; } ) => { const customInstance = useCustomInstance<CreatePostResponse>(); return useMutation({ mutationFn: (data: CreatePostRequest) => customInstance({ url: `/api/posts`, method: "POST", data, }), ...options?.mutation, }); }; // PUT request export const useUpdatePost = <TError = Error, TContext = unknown>( postId: string, options?: { mutation?: UseMutationOptions<Post, TError, UpdatePostRequest, TContext>; request?: SecondParameter<ReturnType<typeof useCustomInstance>>; } ) => { const customInstance = useCustomInstance<Post>(); return useMutation({ mutationFn: (data: UpdatePostRequest) => customInstance({ url: `/api/posts/${postId}`, method: "PUT", data, }), ...options?.mutation, }); }; // DELETE request export const useDeletePost = <TError = Error, TContext = unknown>( postId: string, options?: { mutation?: UseMutationOptions<void, TError, void, TContext>; request?: SecondParameter<ReturnType<typeof useCustomInstance>>; } ) => { const customInstance = useCustomInstance<void>(); return useMutation({ mutationFn: () => customInstance({ url: `/api/posts/${postId}`, method: "DELETE", }), ...options?.mutation, }); }; Convenience of These Hooks TypeScript type inference automatically infers data type as GetPostsResponse Error handling is also type-safe (Error type is determined) TanStack Query features like caching and refetching work as-is No manual API URL entry needed (prevents URL typos) Key Points for Using Orval-Generated Code Feature Benefit Automatic OpenAPI tracking API spec change → re-run → fully synchronized Types and hooks are linked Return type of useGetPosts is also auto-inferred Utilizes TypeScript generics Error handling is also type-safe Plugin extensible Can add custom generation logic Strong for API versioning Supports generation from older API spec versions Generated Code Must Not Be Modified Running pnpm orval overwrites type definitions and custom hooks, so files under src/shared/api/generated/ are modification prohibited . // ❌ Do not modify directly like this // src/shared/api/generated/hooks.ts export const useGetPosts = () => { // ↓ This code will be overwritten on Orval re-run return useSuspenseQuery({ // ... }); }; Customization Is Done in the Entities Layer When customization is needed, wrap in the entities layer to provide your own interface. This centralizes dependencies on generated code in one place. // src/entities/post/api/hooks.ts import { useGetPosts as useGetPostsGenerated } from "@/shared/api/generated"; /** * Provides a user-friendly interface * - Hides details of Orval-generated code * - Returns organized return values */ export const usePosts = () => { const { data, isLoading, error } = useGetPostsGenerated(); return { posts: data?.items ?? [], isLoading, hasError: !!error, }; }; Detailed implementation patterns are explained in the next chapter. Implementation Patterns and Structural Design From here, we'll introduce 3 design patterns for effectively using Orval-generated code. Pattern A: Simple Wrapping Scenario : API to get a list of posts Step 1: Check Orval-Generated Code The useGetPosts shown in "Generated Output 2: TanStack Query Custom Hooks" above is used as-is. Step 2: Wrap in Entities Layer // src/entities/post/api/hooks.ts import { useGetPosts as useGetPostsGenerated } from "@/shared/api/generated"; /** * Custom hook to get list of posts * Isolates dependency on shared/api/generated to entities layer */ export const usePosts = () => { const { data, isLoading, error } = useGetPostsGenerated(); return { posts: data?.items ?? [], isLoading, hasError: !!error, }; }; Step 3: Public API // src/entities/post/api/index.ts export { usePosts } from "./hooks"; Step 4: Use in Features Layer // src/features/PostManagement/ui/PostList.tsx import { usePosts } from "@/entities/post/api"; function PostList() { const { posts, isLoading } = usePosts(); if (isLoading) return <div>Loading...</div>; return ( <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> ); } Benefits of This Pattern Orval-generated code changes are limited to entities/post/api features/PostManagement only needs to know the simple interface Testing also works with mocking just entities/post/api From a Feature-Sliced Design Perspective entities/post/api creates a boundary between Orval (external) and features (internal) Features don't know the details of generated code Modification scope can be limited to entities Pattern B: Combining Multiple APIs Scenario : When both "list of posts + post details" are needed Multiple API calls need to be combined. This is also handled in the entities layer. Note: The following example assumes a useGetPostDetails hook is separately generated by Orval. Step 1: Combine Multiple APIs in Entities Layer // src/entities/post/api/hooks.ts import { useGetPosts as useGetPostsGenerated, useGetPostDetails as useGetPostDetailsGenerated, } from "@/shared/api/generated"; /** * Combines multiple API calls * Callers don't need to be aware of this complexity */ export const usePostWithDetails = (postId: string) => { const { data: posts, isLoading: postsLoading } = useGetPostsGenerated(); const { data: details, isLoading: detailsLoading } = useGetPostDetailsGenerated(postId); return { posts: posts?.items ?? [], details: details ?? null, isLoading: postsLoading || detailsLoading, // Also provide convenient derived data hasDetails: !!details, }; }; Step 2: Use from Features Layer Callers don't need to know the complexity. // src/features/PostManagement/ui/PostDetail.tsx import { usePostWithDetails } from "@/entities/post/api"; function PostDetail({ postId }: Props) { const { posts, details, isLoading, hasDetails } = usePostWithDetails(postId); // Hide Complexity in entities layer! return <div>{hasDetails && <PostInfo details={details} />}</div>; } Pattern C: Unified Error Handling Scenario : When you want to handle errors in a common format Convert Orval-generated error types to custom error types. Step 1: Define and Convert Error Types in Entities Layer // src/entities/post/api/hooks.ts export type ApiError = { message: string; code: "NETWORK_ERROR" | "NOT_FOUND" | "UNAUTHORIZED" | "SERVER_ERROR"; details?: unknown; }; export type UsePostsResult = { posts: Post[]; isLoading: boolean; error: ApiError | null; retry: () => void; }; export const usePosts = (): UsePostsResult => { const { data, isLoading, error, refetch } = useGetPostsGenerated(); // Convert Orval-generated error type to custom error type const mappedError: ApiError | null = error ? { message: error.message || "An error occurred", code: mapErrorCode(error), details: error, } : null; return { posts: data?.items ?? [], isLoading, error: mappedError, retry: () => refetch(), }; }; // Helper function // TanStack Query's error is treated as Error type // Assumes custom instance throws Error with status code type ApiErrorWithStatus = Error & { status?: number }; function mapErrorCode(error: unknown): ApiError["code"] { if (!navigator.onLine) return "NETWORK_ERROR"; const apiError = error as ApiErrorWithStatus; if (apiError.status === 404) return "NOT_FOUND"; if (apiError.status === 401) return "UNAUTHORIZED"; return "SERVER_ERROR"; } Step 2: Unified Error Processing in Features Layer Error handling becomes unified on the caller side. // src/features/PostManagement/ui/PostList.tsx import { usePosts } from "@/entities/post/api"; function PostList() { const { posts, isLoading, error, retry } = usePosts(); if (error) { return ( <div> <p>Error: {error.message}</p> <button onClick={retry}>Retry</button> </div> ); } // ... normal processing below } Architecture Diagram: Orval + Feature-Sliced Design Here's a diagram summarizing the patterns so far. Since dependency directions are unified, the scope of change impact becomes clear. shared/api/generated/ ← Orval output (modification prohibited) ├─ useGetPosts ├─ useCreatePost ├─ useGetPostDetails └─ types.ts ↓ [Boundary] ↓ entities/post/api/ ← Layer wrapping Orval output (modifiable) ├─ usePosts (customized version) ├─ usePostWithDetails (multiple API combination) ├─ ApiError type └─ index.ts (public API) ↓ features/ ← Features layer ├─ PostManagement/ │ ├─ ui/PostList.tsx │ ├─ ui/PostDetail.tsx │ ├─ lib/... │ └─ index.ts ... ↓ pages/ ← Pages layer └─ PostPage/ ↓ app/ ← Application layer ├─ routes/ └─ ... Impressions After Adoption ✅ Benefits Dramatically improved type safety : Cannot go back to development with manually typed definitions. High resilience to API changes : Modifications complete in one place (entities layer). Documentation = Code : OpenAPI and code can always stay synchronized. Improved team-wide efficiency : Smooth flow from API design → implementation → testing. Fewer bugs : Bugs from type mismatches have nearly disappeared. ⚠ Important Notes Learning cost for the entire team : Feature-Sliced Design is an architecture that takes time to master, requiring understanding from all team members. Wait time until OpenAPI is finalized : For UI implementation involving API spec changes, you need to wait for OpenAPI updates to complete. As a countermeasure, using mock APIs like MSW allows frontend development to proceed in parallel. Need for compatibility checks during Orval version upgrades : During Orval major version upgrades, generated code format may change, so checking release notes before upgrading is necessary. Summary Schema-driven development using Orval significantly improves resilience to API changes and type safety in frontend development. In the ongoing project, Orval was introduced from the start, reducing communication costs between backend and frontend engineers and nearly eliminating wasteful implementation costs. Additionally, while adopting Feature-Sliced Design took time for the entire team to understand and implement in code, the clear rules improved code readability and maintainability. If you're experiencing challenges like the following, please try the Orval × Feature-Sliced Design combination: Manually writing API types and custom hooks, incurring costs Schema-driven development is already adopted, but there are no directory structure rules Auto-generated files are imported from various places Thank you for reading to the end. References Orval Official Documentation OpenAPI Specification v3.1.0 TanStack Query Feature-Sliced Design Official Documentation
こんにちは、Engineering Officeの守谷emimです。 この蚘事では、 KINTOテクノロゞヌズ Advent Calendar 2025 ず アクセシビリティ Advent Calendar 2025 の12月2日のクロスポストずしお衚題の件をレポヌトしおいきたす。 普段わたしは瀟内で、組織の開発力を䞊げるこずをミッションにした郚眲Engineering Officeでデザむン呚りのこずを考える傍ら、個人掻動でラむフワヌクずしおいるアクセシビリティの啓発掻動を行っおいたす。 そこで、想定倖に自発的に玠敵なアクセシビリティ掻動を行っおくれたスタッフがいたので、その内容ず心意気に぀いお䌺いたした。 X旧Twitterポストに誰が代替テキストを たずは、以䞋のポストをぜひご芧ください。 https://x.com/KintoTech_Dev/status/1976163362016043509?s=20 ただの匊瀟犏岡オフィスのご玹介に芋えたすか よくご芧ください、添付されおいる写真に、なんずも玠敵な代替テキストaltが付䞎されおいたす。 ![KINTOテクノロゞヌズの10月9日のX投皿に4枚の写真が添付されおいお、すべおに「ALT」ボタンが衚瀺されおいる様子のキャプチャヌ](/assets/blog/authors/emim/2025-12-02-SNSA11y/2025-12-02-SNSA11y_post1.png =600x) ![ビルの写真に「KINTOテクノロゞヌズの犏岡オフィスが入居する犏岡倧名ガヌデンシティのビル倖芳」ず代替テキストが付いおいるのをポップアップしたずころ](/assets/blog/authors/emim/2025-12-02-SNSA11y/2025-12-02-SNSA11y_post2.png =500x) 瀟内のチャットに「team-accessibility」ずいうものがあり、普段から情報共有などを行っおいたす。しかしこのポストを行っおくれたのは、そこで前のめりで発蚀しおいる方でもなかったので、わたしは仰倩したした。 そんな方でも適切な代替テキストを付けおくれるずは 今回お話しを䌺ったのは、以䞋の2人です。 竹䞭さん 経歎SIer䌁業で開発やPMを12幎経隓した埌、銀行の内補開発でスクラムマスタヌを担圓 珟圚は技術広報のマネヌゞャヌを務める ポストをされた匵本人 ゆかちさん 経歎1瀟目は旅行業界、コロナ犍の打撃を受けIT業界ぞ KINTOテクノロゞヌズではもずもず経理事務を担圓〜時を経お技術広報専任ずなり、むベント運営やSNSの発信などを担圓しおいる アクセシビリティに぀いお今ずおも関心を高めおいる人 身内ですが敬称付きで統䞀しお掲茉しおいたす。 このポストの代替テキストに぀いお この4枚の投皿に付けられた代替テキスト。ずあるスクリヌンリヌダヌナヌザヌは「クオリティが高くお玠敵ですねずおも読みやすい聞きやすいです」「抜象的な衚珟なのですが、そよ颚が吹くような代替テキスト」ず評しおくれたした。 そこで、どうしお今回代替テキストを付けようず思ったか、竹䞭さんに聞いおみるず、以䞋のような意芋をいただきたした。 ―― 竹䞭さんアクセシビリティは聞いたこずがあったけれど、内容に぀いおはあたり理解しおいたせんでした。今回は、X投皿時にたたたた「ALT」ず曞かれたボタンが目立っおいたこずず、「team-accessibility」のチャットで日々アクセシビリティの情報に觊れおおり、䞖間でも泚目が高たっおいるず聞いおいたので、蚭定しようず思いたした。 普段から誰に届くずもわからず䌝えおいたこずが、こんな所でサブリミナル効果を発揮するずは 蚘述方法など困らなかったかも聞いおみたした。 ―― 竹䞭さん蚘茉の必芁があるこずはわかったけれど具䜓がわからなかったため、盎前にネット怜玢を行い「簡朔に、本文に曞いおいない内容を入れない」こずを意識したした。投皿されるたでどんな感じで入るのかわからなかった為、投皿されたものを確認しお「こうなるのか」ず初めおわかりたした。 改めお、普段䜕気なく利甚しおいるず気付かない機胜だずいうこずがわかりたした。アクセシビリティに慣れおいる人だず、「ALT」ず曞かれたボタンを目芖できたりもしたすが、そこも気付かない人も居るずいうこずを意識する必芁がありそうです。 「代替テキスト」を通しおの気付き 「アクセシビリティを普段意識しおない」人が「代替テキストを぀ける」䞖界線、ずおも玠敵ではないですか個人的にびっくりほっこりしたので「誰が付けたか瀟内で探し出したよ」ずいう旚をポストしたら、結構な「いいね」をいただきたした。 https://x.com/emim/status/1977921547869561149?s=20 これらの反響があったこずを、曎に改めお共有をしたら感動しおくれたのが、ゆかちさんです。ゆかちさんも普段は゚ンゞニアではないこずもありアクセシビリティのチャットには出おこない方です。 2人にあらためお、この反響に぀いお尋ねおみたした。 ―― 竹䞭さん話題になるんだずびっくりしたした。代替テキストだけで反応があるこずに、なるほどず思いたした。 ―― ゆかちさんシンプルに「代替テキストを付けられる」こずを把握しおいなかったし、なおか぀これを぀けるこずで助かる人がいるんだな、ずいうこずを初めお知りたした。アクセシビリティずいう抂念党䜓が今たで気にしおいなかったゞャンルだし、自分でもできるこずがあるのかなず気になりだしたした。 この蚀葉を聞いお、ちょっずしたこずでもフィヌドバックずしお䌝えるず「人の行動に圱響を䞎える」ずいうこずが明らかになったように思う回答を埗られたした。たた、さらにこのような意芋も加えおくれたした。 ―― ゆかちさん倧事なこずだずは思うけれど、䜕をしおいいのかがわからないため、初心者でもわかる孊習機䌚がもっずあるずいいですね。 昚今、アクセシビリティ界隈では過去に比べ、確かに勉匷䌚は増えおきおいたす。それでも前提を飛ばした䞊玚者向けになっおきおいるのも業界課題です。 䞀方で、デゞタル庁が10月にたずめお公開しおくれた「 デゞタル瀟䌚掚進暙準ガむドラむン 」に、広報担圓者アクセシビリティ初心者向けにたずめた「DS-672.1 りェブアクセシビリティ広報向けガむドブック」などがありたす。 https://www.digital.go.jp/resources/standard_guidelines こういった公開資料を利甚しお、技術広報メンバヌ向けの勉匷䌚などを䌁画しようず考えおいたす。きちんずデゞタル庁の担圓の方にも確認をしたら「いくらでも䜿っおください」ずの回答をいただきたした。䜙裕があったら、倖郚の方も招埅する圢での勉匷䌚などもやっおみたいず考えおいたすので、来幎の我々に乞うご期埅を
この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の2日目の蚘事です🎅🎄 はじめに こんにちは KINTO開発郚 KINTOバック゚ンド開発G マスタヌメンテナンスツヌル開発チヌム、Osaka Tech Lab 所属の high-g @high_g_engineer です。 API 連携が倚い珟代のフロント゚ンド開発においお、こんな課題を感じたこずはないでしょうか API の型定矩を手動で曞いおいお、仕様倉曎のたびに修正挏れが発生する 自動生成ファむルの眮き堎所がバラバラで、どこから䜕を import すればいいか分からない チヌムメンバヌごずにディレクトリ構造の解釈が異なり、コヌドレビュヌで議論になる これらの課題を解決するキヌワヌドが、 「型安党」「スキヌマ駆動」「自動生成」「ディレクトリ蚭蚈」 です。 この蚘事では、OpenAPI を唯䞀の情報源ずしお型安党なコヌドを自動生成し、それを Feature-Sliced Design のルヌルに則っお管理するアプロヌチを玹介したす。 具䜓的には、Orval で「どんなコヌドが生成されるのか」を芋ながら、Feature-Sliced Design のディレクトリ構造に沿った効果的な蚭蚈パタヌンを解説したす。 この蚘事で玹介するこず OpenAPI を元に Orval から型ずカスタムフックを出力する流れ Orval が実際に出力するコヌド䟋の詳现 Feature-Sliced Design の局構造ずむンポヌトルヌル Orval 生成コヌドを Feature-Sliced Design のディレクトリ構造で管理する蚭蚈パタヌン 想定読者 REST API ず型定矩の手動管理に疲れおいるフロント゚ンド開発者 TypeScript + React を䜿っおいる方 API 倉曎に匷い蚭蚈に興味がある方 ディレクトリ構造のルヌル化に関心がある方 基瀎ずなる知識 OpenAPI に぀いお OpenAPI は、HTTP API をプログラムで解釈可胜な圢匏で定矩するための暙準です。API の仕様を YAML たたは JSON で蚘述するこずで、以䞋のようなメリットがありたす。 API の入出力が明確に定矩される ドキュメント生成が自動化される クラむアント・サヌバヌ間での霟霬を防ぐ 䟋OpenAPI の蚘述の䞀郚簡略版 openapi: 3.1.0 paths: /posts: get: summary: 投皿䞀芧を取埗 parameters: - name: page in: query schema: type: integer responses: "200": description: Success content: application/json: schema: $ref: "#/components/schemas/GetPostsResponse" post: summary: 投皿を䜜成 requestBody: content: application/json: schema: $ref: "#/components/schemas/CreatePostRequest" responses: "201": description: Created content: application/json: schema: $ref: "#/components/schemas/CreatePostResponse" /posts/{postId}: put: summary: 投皿を曎新 parameters: - name: postId in: path required: true schema: type: string requestBody: content: application/json: schema: $ref: "#/components/schemas/UpdatePostRequest" responses: "200": description: Success content: application/json: schema: $ref: "#/components/schemas/Post" delete: summary: 投皿を削陀 parameters: - name: postId in: path required: true schema: type: string responses: "204": description: No Content components: schemas: Post: type: object required: [id, title, createdAt, updatedAt, status] properties: id: type: string title: type: string body: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time status: type: string enum: [draft, published, archived] GetPostsResponse: type: object properties: items: type: array items: $ref: "#/components/schemas/Post" total: type: integer page: type: integer CreatePostRequest: type: object required: [title] properties: title: type: string body: type: string CreatePostResponse: allOf: - $ref: "#/components/schemas/Post" - type: object properties: createdBy: type: string UpdatePostRequest: type: object properties: title: type: string body: type: string status: type: string enum: [draft, published, archived] この YAML は以䞋を定矩しおいたす。 /posts ゚ンドポむント䞀芧取埗GETず䜜成POST /posts/{postId} ゚ンドポむント曎新PUTず削陀DELETE スキヌマ駆動開発に぀いお 埓来の手動管理の問題 これたで、私たちフロント゚ンド開発者は以䞋のような䜜業を手動で行っおいたした。 // 手動で型定矩を曞く type Post = { id: string; title: string; body?: string; createdAt: string; updatedAt: string; status: "draft" | "published" | "archived"; }; // API 呌び出しも手で曞く const getPost = async (id: string): Promise<Post> => { const response = await fetch(`/api/posts/${id}`); return response.json(); }; この方法には以䞋の問題がありたす。 手動修正のコスト OpenAPI を確認 → 型定矩を手で修正 → 利甚箇所をすべお修正 修正挏れのリスク 型定矩ず実際の API 仕様がズレる 耇数の箇所で同じ型を䜿っおいるず挏れが生じやすい ドキュメントずコヌドの非同期 OpenAPI ≠ 実装コヌド になるこずもある スキヌマ駆動開発のアプロヌチ 䞊蚘で挙げた手動察応の問題を解消するために考えられたのが、「スキヌマAPI 仕様を最初に定矩し、そこから実装を進める」開発手法です。 埓来実装 → ドキュメント埌付け → 仕様ずの霟霬 スキヌマ駆動スキヌマ定矩 → 自動生成 → 実装 → 完了 実装 = ドキュメント、垞に同期 スキヌマ駆動開発の特城 実装 = ドキュメント 垞に API 仕様ずコヌドが同期 型安党性 コンパむル時に API 䞍敎合を怜出 開発効率 型定矩の手䜜業が䞍芁 チヌム連携 フロント゚ンドずバック゚ンド䞡方が同じ OpenAPI を参照 Orval に぀いお Orval は、OpenAPI の仕様曞から TypeScript の型定矩やカスタムフックなどのコヌドを コマンドひず぀で自動生成 しおくれるツヌルです。 Orval の䞻な特城 特城 説明 型定矩の自動生成 API のリク゚スト・レスポンスの型を自動で䜜成 カスタムフックの自動生成 TanStack Query などのフックも自動生成 耇数ラむブラリ察応 TanStack Query だけでなく、Axios などのラむブラリにも察応 モック生成 テスト甚のモックデヌタも生成可胜 Orval を䜿うメリット 時間の節玄 型定矩や API 呌び出しコヌドを手曞きする時間がれロに ミスの防止 手曞きによるタむプミスや仕様の読み間違いがなくなる 垞に最新 OpenAPI が曎新されたら、再生成するだけで最新の状態に スキヌマ駆動開発における Orval の圹割 ここたでの内容をたずめるず、スキヌマ駆動開発における Orval の圹割は以䞋のようになりたす。 OpenAPI信頌できる唯䞀の情報源 ↓ Orval によるコヌドの自動生成で、 型定矩 + TanStack Query フックを垞に同期 ↓ 䜎コストで型安党な開発が可胜 Feature-Sliced Design に぀いお 冒頭でも觊れた通り、珟圚開発䞭のプロゞェクトでは、フロント゚ンドのコヌド構成に Feature-Sliced Design ずいうアヌキテクチャパタヌンを採甚しおいたす。 Feature-Sliced Design は、コヌドベヌスを レむダヌ 、 スラむス 、 セグメント ずいう3぀の抂念で敎理するアヌキテクチャです。 抂念 説明 䟋 レむダヌ (Layer) アプリケヌションの責務による分割。䞊䜍から app → pages → features → entities → shared の5局。 app はルヌティングやレむアりトなどアプリ党䜓の蚭定、 pages は URL に察応する画面を担圓 app/ , pages/ , features/ スラむス (Slice) 各レむダヌ内でのビゞネスドメむンや機胜ごずの分割単䜍 features/auth/ , entities/user/ セグメント (Segment) スラむス内での技術的な圹割による分割 ui/ , model/ , api/ src/ ├── features/ ← レむダヌ │ ├── auth/ ← スラむス │ │ ├── ui/ ← セグメント │ │ ├── model/ ← セグメント │ │ └── index.ts この構造により、「どこに䜕を眮くか」が明確になり、チヌム党䜓でコヌドの配眮ルヌルを統䞀できたす。 Feature-Sliced Design のディレクトリ構造 私たちのチヌムでは、以䞋のようなディレクトリ構造で運甚しおいたす。セグメント api/ 、 model/ 、 ui/ などの分け方はプロゞェクトに合わせおカスタマむズしおいたす。 workspaces/typescript/src/ ├── app/ ← ① アプリケヌション局ルヌティング、グロヌバル蚭定 │ ├── layouts/ 党䜓的なペヌゞで利甚するレむアりト │ ├── routes/ ルヌティング定矩 │ └── App.tsx ルヌトずなるtsxファむル │ ├── pages/ ← ② ペヌゞ局各ペヌゞコンポヌネントURLに察応 │ ├── users/ │ └── login/ │ ├── features/ ← ③ 機胜局再利甚可胜なビゞネスロゞック │ ├── {slice}/ ドメむンごずにスラむスずいう単䜍で分割 (䟋:user, auth) │ │ ├── {component}/ ドメむンに属するコンポヌネント │ │ │ ├── model/ ロゞック郚分 │ │ │ ├── ui/ UI郚分 │ │ │ └── index.ts 公開APIバレルファむル │ │ ... │ ... │ ├── entities/ ← ④ ゚ンティティ局ビゞネスドメむンの定矩 │ ├── user/ 各皮ドメむン │ │ ├── @x クロスむンポヌト蚘法 ※埌述 │ │ ├── api/ shared/ の自動生成ファむルを import しお利甚ファサヌド │ │ │ ├── hooks.ts apiフック │ │ │ └── index.ts 公開APIバレルファむル │ │ ├── model/ ドメむンロゞック │ │ ├── ui/ ドメむン内にずどたる最小レベルのUI │ │ └── index.ts 公開APIバレルファむル │ ... │ └── shared/ ← â‘€ 共有局プロゞェクト非䟝存のナヌティリティ ├── api/ │ └── generated/ Orval による自動生成ファむル修正犁止 │ ├── types.ts │ ├── hooks.ts │ └── client.ts ├── config/ 蚭定定数 ├── errors/ 共通利甚゚ラヌ関数 ├── lib/ ナヌティリティ関数 └── ui/ 汎甚UIコンポヌネント Feature-Sliced Design の局間むンポヌト制限ルヌル Feature-Sliced Design の最も重芁なルヌル レむダヌは自身より䞋䜍のレむダヌのみをむンポヌト可胜 です。 たた、同䞀レむダヌ間の盞互むンポヌトも原則䞍可です䟋倖は埌述の @x 蚘法。 app ← 最䞊䜍抜象床が高い ↓ import可胜 pages ↓ features ↓ entities ※ shared はどのレむダヌからもむンポヌト可胜 ぀たり、以䞋のようなルヌルがプロゞェクト内で蚭けられおいたす。 ✅ pages/ は features/、entities/、shared/ を import 可胜 ✅ features/ は entities/、shared/ を import 可胜 ✅ entities/ は shared/ を import 可胜 ❌ entities/ は features/ や pages/ を import しおはいけない ❌ shared/ は他のどのレむダヌも import しおはいけない entities 局の特別な圹割entities/@xクロスむンポヌト蚘法 しかし、entities 局ではビゞネスドメむン同士が関連するこずが倚く、䟋えば「Post が User を参照する」ずいったケヌスが発生したす。 これを解決するために、entities 局内でのみ蚱可される特別なむンポヌト方法が @x 蚘法です。 ディレクトリ構造の䟋 entities/ ├── user/ │ ├── @x/ │ │ └── post.ts # 倖郚スラむス向けに公開する型・関数 │ ├── model/ │ │ └── types.ts # 内郚で䜿甚する型定矩 │ ├── ui/ │ └── index.ts # 通垞の公開API │ └── post/ ├── model/ │ └── usePost.ts # ここから user の型を参照したい └── index.ts 䜿甚䟋 // entities/post/model/usePost.ts から entities/user を䜿甚する堎合 // ❌ 通垞のむンポヌトFeature-Sliced Design違反同䞀レむダヌ間のむンポヌト import type { User } from "@/entities/user"; // ✅ @x を䜿ったクロスむンポヌト蚱可 import type { User } from "@/entities/user/@x/post"; // @x ディレクトリは「このスラむスが倖郚に公開する、クロスむンポヌト専甚のAPI」を衚したす。 @x を䜿うこずで、「意図的に倖郚公開しおいる」こずが明瀺され、䟝存関係が远跡しやすくなりたす。 では、基瀎ずなる知識が抌さえられたずころで、ここから本題に入っおいきたす。 Orval の䜿い方ず出力コヌド セットアップ 珟圚開発䞭のプロゞェクトでは pnpm をパッケヌゞマネヌゞャヌずしお䜿甚しおいたす。 たた、OpenAPI は予め定矩された前提で話を進めたす。 # Orval のむンストヌル pnpm add -D orval 次に、Orval の蚭定ファむルを䜜成したす。 ※ hooks は、自動生成されたコヌドを Biome で format するために定矩しおいたす。 // orval.config.ts import { defineConfig } from "orval"; const API_DIR = "./src/shared/api"; const INPUT_DIR = "../../docs/api"; const GENERATED_DIR = `${API_DIR}/generated`; export default defineConfig({ postApi: { hooks: { afterAllFilesWrite: "pnpm format:write:generate", }, input: { target: `${INPUT_DIR}/openapi.yaml`, }, output: { clean: true, biome: true, client: "react-query", override: { mutator: { path: `${API_DIR}/customInstance.ts`, name: "useCustomInstance", }, query: { useSuspenseQuery: true, version: 5, }, }, schemas: `${GENERATED_DIR}/model`, target: `${GENERATED_DIR}/hooks/index.ts`, }, }, }); 次に、API リク゚ストを実行するカスタムむンスタンスを䜜成したす。これは Orval の蚭定で指定した mutator ずしお䜿甚されたす。 // src/shared/api/customInstance.ts import { ApiHttpError, type ErrorDetail } from "../errors"; import { getAccessToken } from "../lib"; const BASE_URL = import.meta.env.VITE_API_BASE_URL || ""; // リク゚スト蚭定の型定矩 export type RequestConfig = { url: string; method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; headers?: Record<string, string>; params?: Record<string, unknown>; data?: unknown; signal?: AbortSignal; }; // Fetch API を䜿甚したリク゚スト関数 const fetchApi = async <T>(config: RequestConfig): Promise<T> => { const { url, method, headers = {}, params, data, signal } = config; // 認蚌トヌクンを取埗 const token = getAccessToken(); // ク゚リパラメヌタの構築 const queryString = params ? `?${new URLSearchParams(params as Record<string, string>).toString()}` : ""; const fullUrl = `${BASE_URL}${url}${queryString}`; // ヘッダヌの構築 const requestHeaders: Record<string, string> = { "Content-Type": "application/json", ...headers, }; if (token) { requestHeaders.Authorization = `Bearer ${token}`; } // リク゚ストオプションの構築 const options: RequestInit = { method, headers: requestHeaders, signal, }; if (data && ["POST", "PUT", "PATCH"].includes(method)) { options.body = JSON.stringify(data); } const response = await fetch(fullUrl, options); // ゚ラヌハンドリング if (!response.ok) { let errorMessage = `API error: ${response.status}`; let errorDetails: ErrorDetail[] = []; try { const errorData = await response.json(); errorDetails = errorData?.errors?.details ?? []; if (typeof errorData.message === "string") { errorMessage = errorData.message; } } catch { // JSONパヌスに倱敗した堎合はデフォルトメッセヌゞを䜿甚 } throw new ApiHttpError({ status: response.status, message: errorMessage, details: errorDetails, }); } // 204 No Content の堎合 if (response.status === 204) { return null as T; } return response.json(); }; // Orval で䜿甚するカスタムむンスタンス関数 export const useCustomInstance = <T>(config: RequestConfig): Promise<T> => { const controller = new AbortController(); const promise = fetchApi<T>({ ...config, signal: controller.signal, }); // TanStack Query のキャンセル機胜甚 // @ts-expect-error cancel プロパティを動的に远加 promise.cancel = () => controller.abort(); return promise; }; export default useCustomInstance; この useCustomInstance は Orval が生成するフック内で HTTP リク゚ストを実行する際に䜿甚されたす。認蚌トヌクンの付䞎や゚ラヌハンドリングなど、プロゞェクト固有の蚭定をここに集玄できたす。 実際のプロゞェクトでは、トヌクンリフレッシュ凊理やリトラむロゞックなどを远加するこずが倚いです。詳现は Orval 公匏ドキュメント - Custom Client を参照しおください。 あずは、コヌド生成を実行するだけです。 # コヌド生成実行 pnpm orval 珟圚開発䞭のプロゞェクトでは、定期的に pnpm orval を実行し、API 仕様の倉曎をたずめお反映する運甚をしおいたす。 Orval が生成するコヌド実䟋 それでは、Orval が実際に䜕を生成するか、具䜓䟋で芋おいきたす。 生成物 1型定矩 OpenAPIの Post スキヌマから、以䞋のような TypeScript 型が自動生成されたす。 // src/shared/api/generated/types.ts // ↓ OpenAPIから自動生成される export type Post = { id: string; title: string; body?: string; createdAt: string; // ISO 8601圢匏 updatedAt: string; status: "draft" | "published" | "archived"; }; export type GetPostsResponse = { items: Post[]; total: number; page: number; }; export type CreatePostRequest = { title: string; body?: string; }; export type CreatePostResponse = Post & { createdBy: string; }; export type UpdatePostRequest = { title?: string; body?: string; status?: "draft" | "published" | "archived"; }; 重芁なポむント OpenAPIのスキヌマがそのたた型になる enum は TypeScript の Union Type に倉換される 必須・オプション ? の区別も自動刀定される 生成ファむルなので修正しおはいけない次の再実行で䞊曞きされる 生成物 2TanStack Query カスタムフック Orval は TanStack Query のフックも自動生成したす。以䞋は理解しやすいよう簡略化した䟋です実際の生成コヌドはカスタムむンスタンスや詳现な型定矩を含みたす。 // src/shared/api/generated/hooks.ts // ↓ Orval が TanStack Query のフックを生成簡略化した䟋 import { useSuspenseQuery, useMutation } from "@tanstack/react-query"; import type { UseSuspenseQueryOptions, UseMutationOptions, } from "@tanstack/react-query"; import type { Post, GetPostsResponse, CreatePostRequest, CreatePostResponse, UpdatePostRequest, } from "./model"; import { useCustomInstance } from "../customInstance"; type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1]; // GET リク゚スト → useSuspenseQuery フック export const useGetPosts = < TData = Awaited<ReturnType<ReturnType<typeof useCustomInstance<GetPostsResponse>>>>, TError = Error, >( options?: { query?: Partial<UseSuspenseQueryOptions<GetPostsResponse, TError, TData>>; request?: SecondParameter<ReturnType<typeof useCustomInstance>>; } ) => { const customInstance = useCustomInstance<GetPostsResponse>(); return useSuspenseQuery({ queryKey: ["posts"], queryFn: () => customInstance({ url: `/api/posts`, method: "GET" }), ...options?.query, }); }; // POST リク゚スト → useMutation フック export const useCreatePost = <TError = Error, TContext = unknown>( options?: { mutation?: UseMutationOptions<CreatePostResponse, TError, CreatePostRequest, TContext>; request?: SecondParameter<ReturnType<typeof useCustomInstance>>; } ) => { const customInstance = useCustomInstance<CreatePostResponse>(); return useMutation({ mutationFn: (data: CreatePostRequest) => customInstance({ url: `/api/posts`, method: "POST", data, }), ...options?.mutation, }); }; // PUT リク゚スト export const useUpdatePost = <TError = Error, TContext = unknown>( postId: string, options?: { mutation?: UseMutationOptions<Post, TError, UpdatePostRequest, TContext>; request?: SecondParameter<ReturnType<typeof useCustomInstance>>; } ) => { const customInstance = useCustomInstance<Post>(); return useMutation({ mutationFn: (data: UpdatePostRequest) => customInstance({ url: `/api/posts/${postId}`, method: "PUT", data, }), ...options?.mutation, }); }; // DELETE リク゚スト export const useDeletePost = <TError = Error, TContext = unknown>( postId: string, options?: { mutation?: UseMutationOptions<void, TError, void, TContext>; request?: SecondParameter<ReturnType<typeof useCustomInstance>>; } ) => { const customInstance = useCustomInstance<void>(); return useMutation({ mutationFn: () => customInstance({ url: `/api/posts/${postId}`, method: "DELETE", }), ...options?.mutation, }); }; このフックの䟿利さ TypeScript の型掚論により、 data の型が自動的に GetPostsResponse に掚論される ゚ラヌハンドリングも型安党Error の型が決たっおいる TanStack Query のキャッシング、再フェッチなどの機胜もそのたた䜿える API URL の手入力が䞍芁URL の蚘述ミスを防げる Orval 生成コヌドの掻甚ポむント 特城 メリット OpenAPI の自動远跡 API 仕様倉曎 → 再実行 → 完党に同期 型ずフックが連動 useGetPosts の戻り倀の型も自動掚論 TypeScript ゞェネリクスを掻甚 ゚ラヌハンドリングも型安党 プラグむン拡匵可胜 カスタム生成ロゞックを远加できる API のバヌゞョン管理に匷い 叀いバヌゞョンの API 仕様からの生成もサポヌト 生成コヌドは修正犁止 pnpm orval を実行するず型定矩ずカスタムフックが䞊曞きされるため、 src/shared/api/generated/ 配䞋のファむルは 修正犁止 です。 // ❌ こうやっお盎接修正しおはいけない // src/shared/api/generated/hooks.ts export const useGetPosts = () => { // ↓ このコヌドは Orval の再実行で䞊曞きされる return useSuspenseQuery({ // ... }); }; カスタマむズは entities 局で行う カスタマむズが必芁な堎合は、entities 局でラップしお独自のむンタヌフェヌスを提䟛したす。これにより、生成コヌドぞの䟝存を䞀箇所に集玄できたす。 // src/entities/post/api/hooks.ts import { useGetPosts as useGetPostsGenerated } from "@/shared/api/generated"; /** * 利甚偎に䜿いやすいむンタヌフェヌスを提䟛 * - Orval 生成コヌドの詳现を隠蔜 * - 戻り倀を敎理しお返す */ export const usePosts = () => { const { data, isLoading, error } = useGetPostsGenerated(); return { posts: data?.items ?? [], isLoading, hasError: !!error, }; }; 詳现な実装パタヌンは次章で解説したす。 実装パタヌンず構造蚭蚈 ここから、Orval が生成したコヌドを効果的に䜿うための 蚭蚈パタヌン を 3 ぀玹介したす。 パタヌン A単玔なラッピング シナリオ 投皿䞀芧を取埗する API ステップ 1Orval による生成コヌドを確認 前述の「生成物 2TanStack Query カスタムフック」で瀺した useGetPosts がそのたた䜿甚されたす。 ステップ 2entities 局でラッピング // src/entities/post/api/hooks.ts import { useGetPosts as useGetPostsGenerated } from "@/shared/api/generated"; /** * 投皿䞀芧を取埗するカスタムフック * shared/api/generated ぞの䟝存を entities局に隔離 */ export const usePosts = () => { const { data, isLoading, error } = useGetPostsGenerated(); return { posts: data?.items ?? [], isLoading, hasError: !!error, }; }; ステップ 3公開 API // src/entities/post/api/index.ts export { usePosts } from "./hooks"; ステップ 4features 局で䜿甚 // src/features/PostManagement/ui/PostList.tsx import { usePosts } from "@/entities/post/api"; function PostList() { const { posts, isLoading } = usePosts(); if (isLoading) return <div>読み蟌み䞭...</div>; return ( <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> ); } このパタヌンのメリット Orval の生成コヌド倉曎が entities/post/api に限定される features/PostManagement はシンプルなむンタヌフェヌスだけを知ればいい テストも entities/post/api をモック䞀箇所で OK Feature-Sliced Design の芖点 entities/post/api が Orval倖郚ず features内郚の 境界を䜜る features は generated コヌドの詳现を知らない 修正範囲を entities に限定できる パタヌン B耇数 API の組み合わせ シナリオ 「投皿䞀芧 + 投皿の詳现」が必芁な堎合 耇数の API 呌び出しを組み合わせる必芁がありたす。これも entities 局で察応したす。 ※ 以䞋の䟋では、投皿詳现を取埗する useGetPostDetails フックが別途 Orval で生成されおいる想定です。 ステップ 1entities 局で耇数 API を組み合わせ // src/entities/post/api/hooks.ts import { useGetPosts as useGetPostsGenerated, useGetPostDetails as useGetPostDetailsGenerated, } from "@/shared/api/generated"; /** * 耇数のAPI呌び出しを組み合わせる * 呌び出し偎はこの耇雑性を意識しない */ export const usePostWithDetails = (postId: string) => { const { data: posts, isLoading: postsLoading } = useGetPostsGenerated(); const { data: details, isLoading: detailsLoading } = useGetPostDetailsGenerated(postId); return { posts: posts?.items ?? [], details: details ?? null, isLoading: postsLoading || detailsLoading, // 䟿利な導出デヌタも提䟛 hasDetails: !!details, }; }; ステップ 2features 局から利甚 利甚偎は耇雑さを知らなくお OK です。 // src/features/PostManagement/ui/PostDetail.tsx import { usePostWithDetails } from "@/entities/post/api"; function PostDetail({ postId }: Props) { const { posts, details, isLoading, hasDetails } = usePostWithDetails(postId); // 耇雑さは entities局に隠蔜 return <div>{hasDetails && <PostInfo details={details} />}</div>; } パタヌン C゚ラヌハンドリングの統䞀 シナリオ ゚ラヌを共通のフォヌマットで扱いたい堎合 Orval 生成の゚ラヌ型を、独自の゚ラヌ型に倉換したす。 ステップ 1entities 局で゚ラヌ型を定矩・倉換 // src/entities/post/api/hooks.ts export type ApiError = { message: string; code: "NETWORK_ERROR" | "NOT_FOUND" | "UNAUTHORIZED" | "SERVER_ERROR"; details?: unknown; }; export type UsePostsResult = { posts: Post[]; isLoading: boolean; error: ApiError | null; retry: () => void; }; export const usePosts = (): UsePostsResult => { const { data, isLoading, error, refetch } = useGetPostsGenerated(); // Orval生成の゚ラヌ型を独自の゚ラヌ型に倉換 const mappedError: ApiError | null = error ? { message: error.message || "゚ラヌが発生したした", code: mapErrorCode(error), details: error, } : null; return { posts: data?.items ?? [], isLoading, error: mappedError, retry: () => refetch(), }; }; // ヘルパヌ関数 // TanStack Query の error は Error 型ずしお扱われる // カスタムむンスタンス偎でステヌタスコヌドを含めた Error を throw する想定 type ApiErrorWithStatus = Error & { status?: number }; function mapErrorCode(error: unknown): ApiError["code"] { if (!navigator.onLine) return "NETWORK_ERROR"; const apiError = error as ApiErrorWithStatus; if (apiError.status === 404) return "NOT_FOUND"; if (apiError.status === 401) return "UNAUTHORIZED"; return "SERVER_ERROR"; } ステップ 2features 局で統䞀的に゚ラヌ凊理 利甚偎でぱラヌハンドリングが統䞀されたす。 // src/features/PostManagement/ui/PostList.tsx import { usePosts } from "@/entities/post/api"; function PostList() { const { posts, isLoading, error, retry } = usePosts(); if (error) { return ( <div> <p>゚ラヌ: {error.message}</p> <button onClick={retry}>再詊行</button> </div> ); } // ... 以䞋、通垞の凊理 } Orval + Feature-Sliced Design のアヌキテクチャ図 ここたでのパタヌンを図にたずめたした。䟝存の方向が統䞀されおいるため、倉曎の圱響範囲が明確になりたす。 shared/api/generated/ ← Orvalの生成物修正犁止 ├─ useGetPosts ├─ useCreatePost ├─ useGetPostDetails └─ types.ts ↓ [境界線] ↓ entities/post/api/ ← Orvalの生成物をラッピングする局修正可胜 ├─ usePostsカスタマむズ版 ├─ usePostWithDetails耇数API組み合わせ ├─ ApiError型 └─ index.ts公開API ↓ features/ ← 機胜局 ├─ PostManagement/ │ ├─ ui/PostList.tsx │ ├─ ui/PostDetail.tsx │ ├─ lib/... │ └─ index.ts ... ↓ pages/ ← ペヌゞ局 └─ PostPage/ ↓ app/ ← アプリケヌション局 ├─ routes/ └─ ... 導入しおみた感想 ✅ メリット 型安党性が圧倒的に向䞊 手入力で型を定矩する開発には戻れたせん。 API 倉曎ぞの耐性が高い 䞀箇所修正entities 局で党おが完了したす。 ドキュメント = コヌド OpenAPI ずコヌドを垞に同期できたす。 チヌム党䜓の効率が向䞊 API 蚭蚈 → 実装 → テストの流れがスムヌズです。 バグが枛る 型䞍敎合によるバグがほがなくなりたす。 ⚠ 泚意点 チヌム党䜓での孊習コストがかかる Feature-Sliced Design は習埗に時間がかかるアヌキテクチャであり、チヌム党員の理解が必芁です。 OpenAPI 確定たでの埅ち時間が発生 API 仕様倉曎を䌎う UI 実装では、OpenAPI の曎新完了を埅぀必芁がありたす。察策ずしお MSW などのモック API を掻甚するこずで、フロント゚ンド開発を䞊行しお進められたす。 Orval のバヌゞョンアップ時の互換性確認の必芁性 Orval のメゞャヌバヌゞョンアップ時には生成コヌドの圢匏が倉わる可胜性があるため、アップグレヌド前にリリヌスノヌトの確認が必芁です。 たずめ Orval を利甚したスキヌマ駆動開発は、フロント゚ンド開発における 「API 倉曎ぞの耐性」 ず 「型安党性」 を倧幅に向䞊させたす。 珟圚開発䞭のプロゞェクトでは、立ち䞊げ圓初から Orval を導入しおおり、バック゚ンドずフロント゚ンドの゚ンゞニア間のコミュニケヌションコストが軜枛され、無駄な実装コストもほずんどなくなりたした。 たた、Feature-Sliced Design の導入により、チヌム党䜓で理解しコヌドに萜ずし蟌むたでに時間がかかったものの、明確なルヌルのおかげでコヌドの可読性ず保守性が向䞊したした。 以䞋のような課題を感じおいる方は、ぜひ Orval × Feature-Sliced Design の組み合わせを詊しおみおください。 API の型やカスタムフックを手曞きしおいお、コストがかかっおいる スキヌマ駆動開発は導入枈みだが、ディレクトリ構造にルヌルがない 自動生成ファむルを様々な堎所から import しおいる状態 最埌たでお読みいただきありがずうございたした。 参考文献 Orval 公匏ドキュメント OpenAPI Specification v3.1.0 TanStack Query Feature-Sliced Design 公匏ドキュメント
This article is the Day 1 entry of the KINTO Technologies Advent Calendar 2025:santa::christmas_tree: I'm okapi from the Mobile team in the QA Group. When creating images with AI, have you ever experienced telling the AI exactly what you want through prompts, only to have your intent misunderstood, forcing you to redo it multiple times? This time, I've created a prompt that can generate tech blog cover images in a single generation! This approach can be applied to other image creation tasks as well. Please give it a try! How to Use AI Image‑generation to Use Microsoft Copilot *Basically, any generative AI tool that supports image generation will work (e.g., ChatGPT, DALL-E, Midjourney, etc.) Prompt Modification Points There are only 4 points to modify in the prompt! Modification Points Content 1. Display Title Setting Paste your tech blog title into Display Title 2. Style Selection Choose 1 from ■Style and delete the other 2 3. Overview Setting Paste your tech blog content into ■Tech Blog Content 4. Previous Cover Image Attachment Attach your previously used cover image to the prompt Actual Prompt Used Please create a cover image for a tech blog. Please use the same format as the image used in the previous tech blog I'm attaching. ■Purpose I want to create a cover image for the following blog article. ■Display Title (Paste article title here) ■Notes ・Please ensure there are no unnatural Japanese expressions. ・Please keep the image style and layout the same as before. ・The title should be placed in the center or a prominent position ■Style (Choose one from the following 3) ・Tech feel (technical atmosphere) ・AI and machine learning style (collaboration with generative AI) ・Motion graphics style (even as a still image) ■Tech Blog Content (Paste article overview here) Previous Cover Image Attached Images Actually Created for This Article For this article, I created images in the 3 patterns mentioned above. Style Generated Image Tech feel (technical atmosphere) AI and machine learning style (collaboration with generative AI) Motion graphics style (even as a still image) Key Points of Prompt Design Explained Point Explanation 1. Minimize modification points By narrowing down the parts that need modification in the prompt to 4 points, I created a template that anyone can easily use with copy-paste. 2. Attach reference images Simply saying "with the same atmosphere as before" in words doesn't accurately convey to AI. By attaching actual images, you can share ambiguous parts that are difficult to express such as layout, color scheme, and font feel. 3. Structured instructions By clearly categorizing information into purpose, title, notes, style, and content, it becomes easier for AI to understand the priority of each element. 4. Specify elements to avoid By including negative instructions like "avoid unnatural Japanese expressions," it becomes easier to select natural Japanese. 5. Present options (style) Instead of leaving everything to AI, by making it a format where you choose from 3 styles, simply adding this option makes the prompt customizable. Not Complete (Still Not Perfect) This template can mass-produce images while maintaining reproducibility just by replacing 4 points: title, style, overview, and reference image. Actually, There Are 2 Issues Although I could generate images in one shot, upon closer inspection, the following 2 problems were found. Issue 1: Japanese Typos Despite stating "avoid unnatural Japanese expressions" in the prompt, typos occurred. Tech feel (technical atmosphere): It's written as "自動化化", where "化" is repeated The display of "開発" is distorted AI and machine learning style (collaboration with generative AI): It's written as "機械孊", where "習" is missing Issue 2: Logo Modification I wanted the reference image's logo to be reproduced, but the generative AI subtly modified the logo. At first glance they look the same, but upon closer inspection, you can see that the design has subtly changed . From a copyright and brand guidelines perspective, we want to avoid logo modifications . Tried to Improve Response to Issue 1: Japanese Typos I adjusted the prompt notes so the Japanese wouldn’t sound awkward, and tried out a few versions. Trial Changes Result ① ・Please use correct kanji and phrases for Japanese text. ・Ensure no typos or meaningless Japanese is included. ・Make Japanese text in the image natural and readable. No change - Same typos occurred ② ・Avoid unnatural Japanese expressions. ・Please review that kanji are correct before creating. All kanji disappeared - Text stopped displaying ③ Attached image with "Please correct 自動化化 in the upper left to 自動化" Not corrected - Original typo remained Response to Issue 2: Logo Modification To accurately reproduce the logo, I tried the following prompt adjustments. Additional prompt: I want the logo below to be exactly the same, so please attach the logo and use the attached file(rogo.png). As a result, a logo close to the original was created, but the angle and thickness were slightly different. Conclusion While image creation itself can be done in one shot, there were the following 2 issues: Japanese kanji expressions - Difficult to control perfectly with prompts alone Accurate logo reproduction - AI automatically modifies it Through this trial and error process, I think we can understand the characteristics and limitations of generative AI and find more effective ways to use it. Practical operational method: Leave layout, atmosphere, and background generation to the image‑generation AI (AI's strong point) Add logos later with image editing tools (humans control accurately) With this combination, I found that we can leverage the strengths of image-generation AI while ensuring a certain level of quality . This tech blog cover image was created using the above operation with the logo manually pasted. If anyone has a prompt that can accurately reproduce kanji and logos in AI-generated images, please let me know! I’ll write more articles when I find new and interesting AI applications, along with challenges and solutions.
This article is the Day 1 entry for the KINTO Technologies Advent Calendar 2025 🎅🎄 Hello, I'm Yukachi (@ukcpo) from the Developer Relations Group! KINTO Technologies is doing an Advent Calendar again this year☆* This is the fifth year for our Advent Calendar! This year, we have two series on free topics with a total of 50 articles planned! @ card In the past, the Developer Relations Group would individually reach out to each division to gather contributions for the Advent Calendar, but this time, most of the participants were recruited through a Slack channel call for submissions(^^) By the way, half of the 50 total articles will be written by first-time contributors! It's wonderful to see so many members taking on the challenge, thinking "why not give it a try"! As a side note, since last year's Advent Calendar, the Developer Relations Group has been hosting a casual 30-minute consultation session every day via Slack huddle during the writing period. Being able to pop into the huddle and quickly ask questions when you're a bit stuck lowers the barrier to seeking help, so from our perspective as the hosts, it feels like a great initiative. What do you think!? We're happy to receive questions like "This is my first time writing, so is it okay to ask a basic question...?" ![スクリヌンショット](/assets/blog/authors/uka/advent/advent1.png =400x) Our manager who's great at creating an approachable atmosphere With all that said, we hope you will enjoy our company's "real" through the Advent Calendar! Updates will be posted daily on our official X account (@KINTOTech_Dev) . If any articles catch your interest, please give them a read♩ One more month left this year—let's do our best(^^)
この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の1日目の蚘事です🎅🎄 はじめに QAグルヌプのMobileチヌムのokapiです。 AIで画像を䜜成するずき、「こういう画像が欲しい」ずプロンプトで䌝えたはずなのに、なぜか意図が䌝わらず、䜕床もやり盎す矜目に 。そんな経隓、ありたせんか? そこで今回は、テックブログのカバヌ画像を「䞀床の生成」で䜜れるプロンプトを䜜成したした! この考え方は、他の画像䜜成にも応甚可胜です。ぜひ掻甚しおみおください。 䜿い方 䜿甚する画像生成AI Microsoft Copilot ※画像生成に察応した生成AIツヌルであれば、基本的にどれでもOKです䟋ChatGPT、DALL-E、Midjourneyなど プロンプトの修正箇所 プロンプトの修正箇所は、たったの4点だけ! 修正箇所 内容 1. 衚瀺タむトルの蚭定 執筆したテックブログのタむトルを「衚瀺タむトル」に貌り付ける 2. スタむルの遞択 「■スタむル」から1぀遞び、残り2぀を削陀 3. 抂芁の蚭定 執筆したテックブログの内容を「■テックブログの蚘茉内容」に貌り付ける 4. 以前のカバヌ画像添付 以前䜿っおいたカバヌ画像を「プロンプト」に添付 実際に䜿ったプロンプト テックブログのカバヌ画像を䜜成しおください。 添付しおいる前回のテックブログで䜿甚した画像ず同じ圢匏でお願いしたす。 ■目的 以䞋のブログ蚘事のカバヌ画像を䜜成したいです。 ■衚瀺タむトル ここに蚘事のタむトルを貌り付け ■泚意点 ・日本語衚珟に䞍自然な点が入らないようにしおください。 ・画像のテむストやレむアりトは前回ず同様でお願いしたす。 ・タむトルが䞭倮たたは目立぀䜍眮に配眮されおいるこず ■スタむル 䞋蚘3぀からお奜きなのを遞ぶ ・テック感技術的な雰囲気 ・AIず機械孊習系生成AIずの協働 ・モヌショングラフィック颚静止画でも ■テックブログの蚘茉内容 ここに蚘事の抂芁を貌り付け 添付した以前のカバヌ画像 本蚘事で実際に䜜った画像 本蚘事では、䞊蚘3パタヌンのスタむルで䜜りたした。 スタむル 生成された画像 テック感技術的な雰囲気 AIず機械孊習系生成AIずの協働 モヌショングラフィック颚静止画でも プロンプト蚭蚈のポむント解説 ポむント 解説 1. 修正箇所を最小限に蚭定 プロンプト内で修正が必芁な箇所を「4点に絞り蟌む」こずで、誰でも簡単にコピペで䜿いやすいテンプレヌトずしたした。 2. 参考画像の添付 蚀葉だけで「前回ず同じ雰囲気で」ず䌝えおも、AIには正確に䌝わりたせん。実際の画像を添付するこずで、レむアりト・配色・フォント感などの「䌝えるのが難しい曖昧な郚分」を共有できたす。 3. 構造化された指瀺 目的・タむトル・泚意点・スタむル・内容ず、情報を明確に分類するこずで、AIが各芁玠の優先床を理解しやすくなりたす。 4. 避けたい芁玠の明蚘 「日本語衚珟に䞍自然な点が入らないように」ずいう吊定圢の指瀺を入れるこずで、自然な日本語を遞定しやすくなりたす。 5. 遞択肢を提瀺(スタむル) AIに完党に任せるのではなく、3぀のスタむルから遞ぶ圢匏にするこずで、ここを増やすだけで、カスタマむズが可胜なプロンプトずなりたす。 おわらないただ完璧ではない 今回のテンプレヌトは「タむトル・スタむル・抂芁・参考画像」の4点を差し替えるだけで、再珟性を保ったたた量産できたす。 実は課題が2぀ありたす 䞀発で画像生成できたものの、よく芋るず以䞋の2぀の問題が発生しおいたした。 課題1: 日本語の誀字 「日本語衚珟に䞍自然な点が入らないように」ずプロンプトに蚘茉しおいるにも関わらず、誀字が発生しおいたした。 テック感(技術的な雰囲気): 「自動化 化 」ずなっおいる(「化」が重耇) 「開発」が衚瀺厩れ AIず機械孊習系(生成AIずの協働): 「機械孊」ずなっおいる(「習」が抜けおいる) 課題2: ロゎの改倉 参考画像のロゎを再珟しおほしかったのですが、生成AIによっおロゎが埮劙に改倉されおしたいたした。 䞀芋するず同じように芋えたすが、よく芋るず 现郚のデザむンが倉わっおいる こずがわかりたす。 著䜜暩やブランドガむドラむンの芳点から、 ロゎの改倉は避けたい ずころです。 改善を詊みたした 課題1ぞの察応: 日本語の誀字 プロンプトの泚意点(日本語衚珟に䞍自然な点が入らないように)をカスタマむズしお耇数パタヌンを詊しおみたした。 詊行 倉曎内容 結果 ① ・日本語の文字は、正しい挢字・語句を䜿甚しおください。 ・誀字脱字や意味䞍明な日本語が含たれないようにしおください。 ・画像内の日本語テキストは、自然で読みやすい衚珟にしおください。 倉わらず - 同様の誀字が発生 ② ・日本語衚珟に䞍自然な点が入らないようにしおください。 ・䜜成する前に挢字は正しい挢字ずなっおいるかレビュヌしおから䜜成しおください。 挢字自䜓が党郚消される - テキストが衚瀺されなくなる ③ 画像を添付の䞊、「巊䞊の『自動化化』→『自動化』に修正しおください」 修正されず - 元の誀字がそのたた残る 課題2ぞの察応: ロゎの改倉 ロゎを正確に再珟するため、以䞋のプロンプト調敎を詊したした。 远加プロンプトロゎを添付の䞊、䞋のロゎは党く同じずしたいので、添付しおいるrogo.pngを貌り付けお䜿っおください。 を远加した結果、本物に近いロゎができたすが、埮劙に角床や倪さが異なりたした。 おわりに 画像䜜成自䜓は䞀発でできるものの、以䞋の2぀の課題がありたした: 日本語の挢字衚珟 - プロンプトだけでは完璧な制埡が難しい ロゎの正確な再珟 - AIが自動的に改倉しおしたう このようなトラむ&゚ラヌを繰り返すこずで、生成AIの特性や限界を理解でき、より効果的な掻甚方法を芋぀けられるず感じおいたす。 珟実的な運甚方法: 画像生成AIに「レむアりト・雰囲気・背景」の生成を任せる(画像生成AIの埗意分野) 「ロゎ」は画像線集ツヌルで埌から远加(人間が正確に制埡) この組み合わせで、 画像生成AIの匷みを掻かし぀぀、䞀定の品質も担保できる ず分かりたした。 本テックブログカバヌ画像は、䞊蚘運甚で手動でロゎを貌り付けお䜜りたした。 もし「AIで生成した画像内の挢字やロゎを正確に再珟できるプロンプト」をお持ちの方がいらっしゃいたしたら、ぜひ教えおください! 今埌も「おもしろいAIの掻甚方法」や「぀たずいた課題ず解決策」を芋぀けたら、蚘事を執筆しおいきたす。
この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の 1 日目の蚘事です🎅🎄 こんにちは、技術広報の ゆかち(@ukcpo) です KINTOテクノロゞヌズは今幎もアドベントカレンダヌを実斜したす☆* アドベントカレンダヌ、今幎で 5 回目 今幎はフリヌテヌマで 2 シリヌズ、蚈 50 蚘事公開予定です @ card 過去アドベントカレンダヌは技術広報から各郚眲ぞ個別で声がけをしお集めおおりたしたが、 今回はSlackチャンネルでの公募でほずんどの数が集たりたした(^^) ちなみに合蚈 50 蚘事䞭半分のメンバヌが執筆デビュヌずなりたす せっかくなので・・ずチャレンゞしおくれるメンバヌが倚くお玠敵 䜙談ですが、去幎のアドベントカレンダヌからアドベントの執筆時期は技術広報メンバヌが毎日 30 分、 Slackのハドルにおゆるっず盞談䌚を開いおおりたす。 ちょっず困った時にハドルに入ればサクッず聞けちゃうの、 盞談のハヌドルが䞋がるず思うので開催しおいる偎ずしお良い取り組みな気がしおいたすがいかがでしょう " 初の執筆なので初歩的な質問なのですがいいですか・・ " などちょこちょこ盞談いただけお嬉しいです ![スクリヌンショット](/assets/blog/authors/uka/advent/advent1.png =400x) 盞談しやすい雰囲気を぀くるのが埗意なマネ そんなこんなで匊瀟の "リアル" をアドベントカレンダヌを通しお楜しんでいただけたら嬉しいです 曎新内容は 公匏X(@KINTOTech_Dev) にお毎日曎新予定です。 気になる蚘事があればぜひ目を通しおみおください♩ 今幎もあず1ヶ月、頑匵りたしょう〜(^^)
AI画像線集ツヌル培底比范どれが䞀番自然 Google・OpenAI・ByteDanceの最新モデルを怜蚌【2025秋】 はじめに 2025幎10月24日金、匊瀟の倧阪テックラボにおCO-LAB Tech Night vol.4に発衚者ずしお参加しおきたした。「gpt-image-1 Gemini 2.5 Flash Image Seedream4.0の䞀貫性を怜蚌」ず題したしお、その時に発衚した内容の䞀郚をこちらでも共有させおいただきたいず思いたす。 内容ずしおはOpenAI、Google、ByteDanceが提䟛する画像生成・線集機胜を䜿っお同じお題で画像線集を行い、どの様な出力結果になるのかを怜蚌するずいったものになりたす。䞀郚以前にこちらのテックブログでも披露した内容ず重なりたすが、新たにSeedream4.0も加えお改めお出力結果を怜蚌しおおりたす。 どのツヌルがいいのかなず悩んでいる方はぜひ参考にしおいただければず思いたす。 改めお、gpt-image-1ずは こちらはOpenAIが2025幎3月に発衚し、GPT-4oに暙準搭茉された画像生成・線集が可胜な機胜です。APIなどでは「gpt-image-1」ずいうモデル名で参照されるこずもありたす。 input_fidelity ずいうパラメヌタが提䟛されおおり、「high」に蚭定するこずで線集時の被写䜓やキャラクタヌの䞀貫性を栌段に䞊がるず話題になりたした。参照機胜なし、むンペむント機胜あり。 Gemini 2.5 Flash Imageずは 通称Nano Bananaず呌ばれ被写䜓やキャラクタヌの䞀貫性を維持する胜力に特化しおチュヌニングされおいるず蚀われおいたす。発衚圓初はその性胜の高さにSNSで非垞に話題になりたした。提䟛開始は2025幎8月。参照機胜あり、むンペむント機胜なし。 Seedream4.0ずは 特城ずしおは4K出力ずいう巚倧な画像が出力可胜で、スピヌドも速いこずからプロの商甚ワヌクフロヌにも耐えうるず蚀われおいたす。こちらも被写䜓やキャラクタヌの䞀貫性の高さがSNSなどで話題に䞊りたした。2025幎9月に提䟛開始されたした。参照機胜あり、むンペむント機胜あり。 AIの匱点被写䜓やキャラクタヌの䞀貫性の維持 画像の䞀郚分だけを線集したい堎合においおも、画像党䜓が生成し盎されおしたうこずから䞀貫性を保぀こずが難しく、生成を繰り返しおいるうちに元の画像から埐々に芋た目が倉化しおしたうこずが起こりたすが、そうした「匱点」は珟圚克服され぀぀ありたす。 ずいうわけで、これら3぀のツヌルの出力画像を比范怜蚌しおみたいず思いたす。 ちなみに、Gemini2.5 Flash Image、Seedream4.0に関しおは参照機胜別の画像を参考に元の画像を倉曎する機胜を䜿甚しおおりたすが、gpt-image-1は参照機胜がないので、元の画像に被写䜓を重ねるずいった方法で線集を行なっおおりたす。ですので、プロンプトはなるべく同じ内容にし぀぀もgpt-image-1は若干違う内容で行いたした。 たた、平均10枚前埌を出力しおその䞭で最も良奜な結果を瀺した出力を掲茉しおいたす。 お題01:空癜のラベルに文字を蚘茉する 空癜のラベルに商品名を蚘茉するずいうお題です。 ![ボトル](/assets/blog/authors/aoshima/image-edit-evaluation/01/sample01.jpg =50%x) 出力結果の比范 gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/01/gpt.png =50%x) 文字の倪さにばら぀きがありたすが、砎綻は芋られたせんでした。党䜓的に䞀貫性が保たれおいたす。 Gemini2.5 Flash Image ![Gemini2.5 Flash Image](/assets/blog/authors/aoshima/image-edit-evaluation/01/gemini.png =50%x) 文字の倪さ、倧きさも問題なく、特に砎綻は芋られたせんでした。党䜓的に䞀貫性が保たれおいたす。 Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/01/seedream.png =50%x) 文字の倪さ、倧きさも問題なく、特に砎綻は芋られたせんでした。党䜓的に䞀貫性が保たれおいたす。ちなみにこちらのみセリフ䜓ですね。 お題02:透明な花瓶远加 右䞋の空間に透明な花瓶を远加しおもらうずいうお題です。 ![ボトル](/assets/blog/authors/aoshima/image-edit-evaluation/02/sample01.jpg =50%x) 出力結果の比范 gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/02/gpt.png =50%x) 花瓶の配眮、角床、光の透過具合など特に違和感なく出力されおいたす。菜の花ず花瓶に぀いおも䞀貫性が保たれおいたす。 Gemini2.5 Flash Image ![Gemini2.5 Flash Image](/assets/blog/authors/aoshima/image-edit-evaluation/02/gemini.png =50%x) こちらも花瓶の配眮、角床、光の透過具合など特に違和感なく出力されおいたす。菜の花ず花瓶に぀いおはこちらも䞀貫性が保たれおいたす。 Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/02/seedream.png =50%x) 花瓶の配眮はちょっず遠くになっおしたい花瓶の䞀郚が切れおしたっおいたすが、角床、光の透過具合など特に違和感なく出力されおいたす。菜の花ず花瓶に぀いおはこちらも䞀貫性が保たれおいたす。 お題03:家族を車の埌郚座垭に座らせる 家族写真に映っおいる人々を車の埌郚座垭に座っおいる様に線集するずいうお題です。 出力結果の比范 gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/03/gpt.png =50%x) 顔の䞀貫性は維持されおいないようです。そしお党䜓的にやや黄色味がかっおしたっおいたす。ただ人物ずシヌトの倧きさのバランスはいいず思いたす。 Gemini2.5 Flash Image ![Gemini2.5 Flash Image](/assets/blog/authors/aoshima/image-edit-evaluation/03/gemini.png =50%x) こちら、12枚生成したしたが砎綻なく出力されるこずはありたせんでした。たたシヌトに察しお人物が小さいです。ただし顔の䞀貫性に぀いおはかなり維持されおいたす。 Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/03/seedream.png =50%x) こちらはシヌトに察しお人物がやや小さい気がしたす。しかし顔の䞀貫性はたあたあ保たれおいる気がしたす。 お題04:男女を゜ファに座らせる 別々の画像の男女を仲良く゜ファに座っおいる様に線集するずいうお題です。 出力結果の比范 gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/04/gpt.png =50%x) 構図が被写䜓により過ぎおいたす。そしお今回も顔の䞀貫性は保たれおいないようです。 Gemini2.5 Flash Image ![Gemini2.5 Flash Image](/assets/blog/authors/aoshima/image-edit-evaluation/04/gemini.png =50%x) 䞀芋よさそうなのですが、゜ファに察しお人物が小さいようです。 Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/04/seedream.png =50%x) こちらは構図、゜ファず人物の倧きさのバランス、顔の䞀貫性、いずれも問題ないようです。 お題05:スヌツ姿の男性をバむクに跚らせる スヌツ姿の男性をバむクに跚らせるずいうお題です。 出力結果の比范 gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/05/gpt.png =50%x) たたもや構図が被写䜓により過ぎおいたす。そしお顔のAI感が匷いです。バむクのディテヌルに察する䞀貫性は䞀郚維持されおいない様です。 Gemini2.5 Flash Image ![Gemini2.5 Flash Image](/assets/blog/authors/aoshima/image-edit-evaluation/05/gemini.png =50%x) 党䜓的なバランスが良いです。たた人物の顔、スヌツの柄、バむクのディテヌルに察しお䞀貫性が維持されおいたす。 Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/05/seedream.png =50%x) 倕焌けが匷く出おしたっおいたす。そしお人物がバむクに察しおやや倧きいですね。 お題06:雑誌のタむトルを日本語ぞ倉曎する 雑誌のタむトルを日本語ぞ倉曎するずいうお題です。 ![雑誌を持っおいる女性](/assets/blog/authors/aoshima/image-edit-evaluation/06/sample01.jpg =50%x) 出力結果の比范 gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/06/gpt.png =50%x) タむトルに関しおは挢字もひらがなやや倪いも問題ないかなずいったずころでしょうか。タむトル以倖の现かい郚分は完党に砎綻しおいたす。そしお党䜓的な色味が黄色っぜくなっおいる感じがしたす。 Gemini2.5 Flash Image ![Gemini2.5 Flash Image](/assets/blog/authors/aoshima/image-edit-evaluation/06/gemini.png =50%x) こちらはタむトル、现かい芋出しは党く日本語になっおおりたせんが、それ以倖の䞀貫性は完党に維持されおいるようです。 Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/06/seedream.png =50%x) こちらは日本語は成立しおいたすが、ひらがなが倪字になっおしたっおいたす。现かい文字も他ず同じく日本語の䜓おいをなしおいたせん。たた、腕時蚈もなくなっおしたっおいたすし、袖も短くなっおしたっおおりたす。 お題07:真䞊からのアングルに倉曎 真暪から撮圱された花瓶に入ったひたわりを真䞊からのアングルに倉曎するずいうお題です。 ![ひたわり](/assets/blog/authors/aoshima/image-edit-evaluation/07/sample01.jpg =50%x) 出力結果の比范 gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/07/gpt.png =50%x) アングルは真䞊からになっおいたすが、花が䞍自然に敎列されおしたっおいたす。 Gemini2.5 Flash Image ![Gemini2.5 Flash Image](/assets/blog/authors/aoshima/image-edit-evaluation/07/gemini.png =50%x) アングルはやや斜め䞊からですが、花の配眮や高さなど元の画像からの䞀貫性が非垞に高く感じたす。 Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/07/seedream.png =50%x) こちらも同じくアングルはやや斜め䞊からですが、花の配眮など䞀貫性が高く感じたす。ただし、䞭倮の奥にある花の高さは明らかに違っおしたっおいるようです。 お題08:男性の髪型をむラストに合わせお倉曎 男性の髪型をむラストの髪型に合わせお倉曎し、4枚䞊べお出力するずいうお題です。 ![男性](/assets/blog/authors/aoshima/image-edit-evaluation/08/sample01.jpg =50%x) 出力結果の比范 gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/08/gpt.png =50%x) 䞀芋悪くないのですが、元の画像ず比べるず顔の皮膚の感じがのっぺりずしおおり、ほくろなどが消えおしたっおいたす。 Gemini2.5 Flash Image ![Gemini2.5 Flash Image](/assets/blog/authors/aoshima/image-edit-evaluation/08/gemini.png =50%x) 党おではないですがほくろなどが維持されおいたりなど、顔の䞀貫性は高く感じたすが、色が倉わっおしたっおいるなど髪型の再珟床は䜎く感じたす。 Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/08/seedream.png =50%x) 今たで高い䞀貫性を芋せおきたSeedream4.0ですが、髪型に関しおは完党に指瀺に背く結果ずなっおしたっおいるようです。出力結果の䞭には髪型が長髪化しおしたうなど、指瀺から倧きく倖れるものも芋られたした。 この様に比范怜蚌を行なっおみるず、それぞれの癖などが分かっおくるので非垞に興味深いず感じたした。ただしこの様に各瀟ごずのバラツキや傟向など今は顕著に芋えおおりたすが、すぐにその差も分からないくらいに粟床を䞊げおくるのではないかず思いたす。 最埌に安党な画像生成・線集に぀いお この様に画像線集を簡単に行える様になっおきたしたが、簡単であるがゆえに意図せずずも間違った䜿い方をしおしたう可胜性がありたす。 著䜜暩を䟵害する様なアりトプットをしない 生成の過皋で著䜜暩を䟵害する恐れのあるものを参照しない こういったこずはもちろんのこず、 未成幎者など瀟䌚的立堎の匱い人々に配慮する 差別や䟮蟱ずいった暎力から他者の尊厳を守る ディヌプフェむクなどによる誀情報の拡散をしない 画像生成・線集を行う際には、この様な配慮も忘れないこずを心がけたいず思っおおりたす。
AI Image Editing Tool Comparison! Which is the Most Realistic Image Generator through Testing the Latest Models: Google, OpenAI, and ByteDance? [Fall 2025] Introduction On Friday, October 24, 2025, I participated as a presenter at CO-LAB Tech Night vol.4 held at our Osaka Tech Lab. At this event, I presented on the topic of testing the consistency of gpt-image-1, Gemini 2.5 Flash Image, and Seedream 4.0. Since Google recently released Nano Banana pro, I have updated some of the content and would like to share it here as well. The content involves using image generation and editing features provided by OpenAI, Google, and ByteDance to perform image editing on the same tasks and examine what kind of output results we get. If you are wondering which tool is the most suitable for you, I hope this will be helpful. What is gpt-image-1? The model is released in March 2025 and integrated as standard in GPT-4o with a feature capable of image generation and editing. In APIs and other contexts, it is sometimes called by its model name gpt-image-1. A parameter called input_fidelity is enabled. Setting the parameter to high helps significantly improve the consistency of subjects and characters in image editing, which gathered attention. The model has no reference feature but inpainting feature. What is Gemini 3 Pro Image? Commonly known as Nano Banana, it is said to be tuned specifically to maintain consistency of subjects and characters. At its launch, the model with high performance become a hot topic on social media. Upgraded to 3 Pro, the model’s text generation feature is apparently enhanced. Nano Banana was released in August 2025 with reference feature support but without inpainting. What is Seedream 4.0? The model includes a feature to output massive 4K images with fast speed, as well as a capability of handling professional commercial workflows. Particularly, the model’s high subject and character consistency also became a topic on social media. The model was released in September 2025 with both reference and inpainting feature support. AI's Weakness: Maintaining the Subject and Character Consistency When you want to edit only part of an image, AI models often regenerate the entire image, which makes it difficult to maintain the image consistency. Iterated generation by AI models causes gradual changes in the original image; however, such weakness is currently being overcome. So, I would like to compare and examine the output images from these three tools. By the way, for Gemini 3 Pro Image and Seedream 4.0, I used the reference feature (a function that modifies the original image by referencing another image). On the other hand, for gpt-image-1, which does not have a reference feature, I performed editing by overlaying subjects onto the original image. Therefore, while I tried to keep the prompts for all the tools as similar as possible, I applied the ones with slightly different content for gpt-image-1. In this comparison experiment, I generated an average of around 10 images and am posting the output that showed the best results among them. Task 01: Writing Texts on a Blank Label The task is to write a product name on a blank label on a bottle in the following image. ![ボトル](/assets/blog/authors/aoshima/image-edit-evaluation/01/sample01.jpg =50%x) Comparison of Output Results gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/01/gpt.png =50%x) The text is somewhat distorted, but no major breakdown was observed. Overall consistency is maintained. Gemini 3 Pro Image ![Gemini 3 Pro Image](/assets/blog/authors/aoshima/image-edit-evaluation/01/gemini.jpg =50%x) The thickness and size of the text are fine, and no particular breakdown was observed. Overall consistency is maintained. Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/01/seedream.jpg =50%x) The thickness and size of the text are fine, and no particular breakdown was observed. Overall consistency is maintained. Task 02: Change to a Top-Down Angle The task is to change an image of sunflowers in a vase photographed from the side to a top-down angle. ![ひたわり](/assets/blog/authors/aoshima/image-edit-evaluation/02/sample01.jpg =50%x) Comparison of Output Results gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/02/gpt.png =50%x) The angle is from directly above the sunflowers. Their petals somehow feel artificial. Gemini 3 Pro Image ![Gemini 3 Pro Image](/assets/blog/authors/aoshima/image-edit-evaluation/02/gemini.jpg =50%x) The angle is from directly above the sunflowers, but they may look slightly small. The texture of the petals looks realistic. Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/02/seedream.jpg =50%x) The image is ended up being slightly from above at an angle, but the texture of the flowers and the detail where just a sunflower on the right side has changed direction have been reproduced. Task 03: Seat a Family in the Back Seat of a Vehicle The task is to edit the people in a family photo as if they are seated in the back seat of a vehicle. Comparison of Output Results gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/03/gpt.png =50%x) Facial consistency does not appear to be maintained. And the overall color of the image appeared somewhat yellowish. However, the balance between the people and seat sizes seems good. Gemini 3 Pro Image ![Gemini 3 Pro Image](/assets/blog/authors/aoshima/image-edit-evaluation/03/gemini.png =50%x) The balance, color tone, and other aspects appear to be output with quite high quality. Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/03/seedream.jpg =50%x) The color tone came out dark, but I felt the consistency of the people and the balance were quite high quality. Task 04: Seat a Man and Woman on a Sofa The task is to edit a man and woman from separate images to appear sitting together on a sofa. Comparison of Output Results gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/04/gpt.png =50%x) The composition is too close to the subjects, and the people feel a bit large in comparison to the sofa. Facial consistency does not appear to be maintained. Gemini 3 Pro Image ![Gemini 3 Pro Image](/assets/blog/authors/aoshima/image-edit-evaluation/04/gemini.jpg =50%x) At first glance it looks good, but the people are small in comparison to the sofa. Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/04/seedream.jpg =50%x) There is seemingly no problem with all the composition, balance between sofa and people sizes, and facial consistency. Task 05: Convert English Title on a Magazine to Japanese The task is to convert an English magazine title to Japanese. ![雑誌を持っおいる女性](/assets/blog/authors/aoshima/image-edit-evaluation/05/sample01.jpg =50%x) Comparison of Output Results gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/05/gpt.png =50%x) The title font has become quite bold, but it does not appear to be broken. The cover page photo has also changed to the one showing a castle, giving it a Japanese feel. Gemini 3 Pro Image ![Gemini 3 Pro Image](/assets/blog/authors/aoshima/image-edit-evaluation/05/gemini.jpg =50%x) Since the model’s text generation feature was enhanced, the output is quite good. The magazine in the image even includes the Japanese subtitle below the title. Moreover, the subtitle clearly makes sense as Japanese. The cover shows cherry blossoms in full bloom alongside red autumn leaves, which is an odd seasonal mismatch. Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/05/seedream.jpg =50%x) The title font is not particularly broken, but unnecessary punctuation is inserted. Small text in the cover has broken down. The photo shows a harbor town-like location with cherry blossoms, giving it a Japanese feel. Task 06: Change a Man's Hairstyle Based on an Illustration The task is to restyle a man's hair to match three different hairstyles from an illustration, outputting the results side by side. Comparison of Output Results gpt-image-1 ![gpt-image-1](/assets/blog/authors/aoshima/image-edit-evaluation/06/gpt.png =50%x) There seems that subjects tend to be output large. Facial consistency does not appear to be maintained. Also, the long-permed hairstyle could not be reproduced. Gemini 3 Pro Image ![Gemini 3 Pro Image](/assets/blog/authors/aoshima/image-edit-evaluation/06/gemini.jpg =50%x) The face with long permed hair leans slightly toward an illustrated look, but overall the hairstyles from the illustration have been reproduced well. Seedream4.0 ![Seedream4.0](/assets/blog/authors/aoshima/image-edit-evaluation/06/seedream.jpg =50%x) Seedream 4.0, which had shown high consistency so far, did not produce results according to instructions when it came to hairstyles. Conducting this kind of comparative examination reveals the quirks of each, which I found very interesting. While the differences and tendencies of each model are now clearly visible, I think the models will quickly improve their accuracy to the level where these differences become indistinguishable. Finally, about Safe Image Generation and Editing As image editing becomes increasingly easy, the risk of unintentional misuse also grows. To this end, we should NOT: Produce output that infringes copyright; or Reference things that may infringe copyright in the generation process. Of course, as well as these, we should also: Show consideration for minors and others in socially vulnerable positions; Protect the dignity of others from violence such as discrimination and insult; or Not spread misinformation through deepfakes. I would like to take the above points in consideration when performing image generation and editing.
Hello, I'm Uehara, a backend engineer in the FACTORY E-commerce Development Group at KINTO Technologies. We will be participating in Techbook Fest 19 as the KINTO Technologies Writing Club formed by volunteer engineers from KINTO Technologies. ※This activity is conducted by volunteers for the purpose of sharing technical knowledge and is not an official corporate activity. What is Techbook Fest? Techbook Fest is a doujinshi convention exclusively for technical books. It will be held for 16 days from November 15 (Sat) to November 30 (Sun), 2025, both in an online marketplace and at a physical venue. The offline event will be held on November 16 (Sun) at Ikebukuro Sunshine City Exhibition Hall D. It will bring together knowledge from a wide range of technical fields and provide a space where participants with a keen interest in technology can interact directly. At the physical venue, you can pick up books and talk directly with the authors, while at the online venue, you can access technical books from anywhere in Japan. The appeal lies in gaining access to valuable knowledge available only here, including specialized technologies and practical know‑how that are seldom addressed in commercial publishing. For more details, please check the official Techbook Fest website. https://techbookfest.org/event/tbf19 New Book to be Distributed For distribution at Techbook Fest 19, volunteers from within KINTO Technologies formed the KINTO Technologies Writing Club and wrote the technical book "TECH BOOK By KINTO Technologies Vol.01." It is an omnibus-format book that compiles chapters written by each author on their respective themes. ![衚玙](/assets/blog/authors/uehara/2025-10-24-techbookfest19-announcement/cover.webp =300x) Cover of the new book "TECH BOOK By KINTO Technologies Vol.01." This book covers a wide range of topics, from testing methods in Go language to AWS security, generative AI, infrastructure automation, mobile development, and organizational building. Chapter 1: Best Practices for Unit Testing with Go Chapter 2: Why Using IAM Roles Provides Higher Security Than IAM Users Chapter 3: Let's Implement Responsible Generative AI Using AWS Chapter 4: Practical Frontend Error Monitoring Learned from New Relic Implementation Chapter 5: Past, Present, and Future of Cloud Infrastructure Automation and Integrated Management Using Infrastructure as Code Chapter 6: Getting Started with iOS App Development Chapter 7: Toyota Group's In-House Development Organization Pursuing Collaboration with AI Through Both Culture and Technology Chapter 8: Creating an Autonomous Organization with the Power of Facilitation Chapter 9: Let's Create an MCP Server with Azure Functions Chapter 10: Balancing AWS Governance and Agility Chapter 11: Making AWS Operations Easier Using Generative AI Chapter 12: Recommendations for Home K8s Starting (About) Two Laps Behind Chapter 13: Let's Try a Hands-On Session with AWS IoT Greengrass Using a Sample Application We will distribute this book, packed with content, for free ! Recommended For Those interested in development using Go language or AWS Those who want to learn about mobile app development or infrastructure automation Those who want to know practical applications of generative AI Those interested in organizational building or team management Those interested in in-house development within the Toyota Group We hope that the technical challenges and solutions covered in each chapter will serve as a reference for those facing similar problems. Venue We will exhibit at both physical and online venues. Physical Venue Date and Time: Sunday, November 16, 2025 Location: Ikebukuro Sunshine City Exhibition Hall D (Cultural Center Building 2F) Booth Number: O15 Floor map at Techbook Fest 19. The KINTO Technologies Writing Club booth is "お15" Online Venue Saturday, November 15 - Sunday, November 30, 2025 Electronic version PDF will be distributed at the online marketplace Conclusion If you visit the Techbook Fest 19 physical venue, please come see us at booth お15. For those who live far away and cannot attend in person, we plan to publish the electronic version on the Techbook Fest online marketplace, so please take a look!
Introduction Hello, I'm Nomura, who joined in August 2025! In this article, I interviewed four new members who joined KINTO Technologies Corporation (KTC) in August 2025 about their impressions right after joining to compile their responses. I hope this provides useful information for those interested in KTC, especially those considering joining us, as well as serving as a reflection for the members who participated. I would be happy if you could get interested in our company through learning from the article about the corporate culture, atmosphere, and candid voices of its new employees. Hikaru Matsukura - MatsuIchi Self-introduction I'm in the Mobile App Development Group, where I'm responsible for developing the backend that mobile apps access. I mainly work in the domain of Dealer Digital Transformation (DX) projects. How is your team structured? We work as one team with members from the Digital Transformation Development Group, Digital Transformation Solution Group, and Digital Transformation Engagements Group to deliver products to accelerate DX. What was your first impression of KTC when you joined it? Were there any surprises? Being able to have discussions with the Cloud Infrastructure Team about infrastructure matters is extremely helpful and encouraging. What is the atmosphere like on-site? Everyone proactively takes initiative and moves forward—it's amazing! I’ll do my best, not to falling behind. How did you feel about writing a blog post? I thought like, "So it's finally my turn!" (lol) I'd like to continue to share information if I get any chance to post my blogs in the future. Question from Yusuke Miwa to Hikaru Matsukura Are you a cat person or a dog person? I like both! My wife's family has a cat, so I probably have more opportunities to interact with cats. Hiroki Nomura Self-introduction I belong to the AI First Group, which is a cross-functional organization. I’m based in Nagoya. In my previous job, I worked as a system integrator (SIer) for an automotive company, particularly focusing on applying generative AI to automotive control areas. How is your team structured? We do everything AI-related. As a cross-functional group, we also develop systems and tools related to generative AI. We're involved in developing and supporting KINTO products and internal generative AI apps, as well as Toyota Group projects. Additionally, using the knowledge shared across the whole company, we are providing generative AI training externally. Last month, we held the Vibe Coding Week event, and we've been implementing internal initiatives to master generative AI. What was your first impression of KTC when you joined it? Were there any surprises? Unlike the atmosphere of traditional Japanese companies, here you continuously think for yourself and keeping up a cycle of input and output. In terms of tools used in KTC, I was surprised by the difference between Teams culture and Slack culture! I really appreciate the culture where everyone actively posts. What is the atmosphere like on-site?? We focus on achieving what we want to accomplish by any means necessary, rather than thinking about the means first! How did you feel about writing a blog post? This is a culture that was not at my previous job. I personally write technical blogs, so I feel comfortable with it. By producing output, I can objectively reflect on my own activities, so it's very positive! Question from Hikaru Matsukura to Hiroki Nomura What do you recommend us as a local specialty food in Nagoya? I used to frequently go to Nan House, a buffet-style Indian restaurant in Higashiura-cho (that is currently closed, though). I like hitsumabushi. It's so expensive that I can't enjoy it often, though... There's Sumiyaki Una Fuji Meieki Branch on the 1st floor of the building where our office is located. Please try it when you come to Nagoya! Yusuke Miwa - Y.M Self-introduction I belong to the New Vehicle Subscriptions Product Management Group, working at the Muromachi office. In my previous job, I worked as a PM to develop a furusato nozei (hometown tax) website, planning and driving projects. How is your team structured? Our group has 7 members, and I communicate with developers and people from different divisions. In practice, I manage QCD for new vehicle subscription development projects and other miscellaneous projects to complete them. What was your first impression of KTC when you joined it? Were there any surprises? Communication among engineers in KTC is more active than at my previous company. Not only do they publish tech blogs, but they also actively communicate with others during project development and requirements confirmation, which is very helpful! What is the atmosphere like on-site? Rather than developing products simply by following requirements, we thoroughly understand the product users’ intent behind their requests and continuously try to define the requirements and build the structures to produce maximum effect. How did you feel about writing a blog post? This is my first experience to share information externally, so I'm nervous (lol). Question from Hiroki Nomura to Yusuke Miwa What are you most into these days, whether for work or personal life? On the personal side, I'm into watching baseball! I used to go to baseball games only a few times a year, but this year I'm going once or twice a month! Closing Thanks to everyone for sharing their impressions after joining KTC! KINTO Technologies is constantly welcoming new members! We'll continue to feature more blog posts to introduce new members from various divisions going forward, so we hope you to look forward to them. And we are still recruiting members to work with us in various divisions and positions! Please check here for details!
こんにちは、KINTOテクノロゞヌズのFACTORY EC開発グルヌプでバック゚ンド゚ンゞニアをやっおいる䞊原です。 技術曞兞19に、KINTOテクノロゞヌズの有志゚ンゞニアによるサヌクル「KINTOテクノロゞヌズ執筆郚」ずしお参加したす。 ※本掻動は有志による技術知識の共有を目的ずしおおり、䌁業の公匏掻動ではありたせん。 技術曞兞ずは 技術曞兞は、技術曞限定の同人誌即売䌚むベントです。2025幎11月15日(土)から11月30日(日)の16日間、オンラむンマヌケットずオフラむン䌚堎で開催されたす。 オフラむン䌚堎は11月16日(日)に池袋サンシャむンシティ 展瀺ホヌルDで開催されたす。幅広い技術分野の知芋が集たり、技術に察しおアンテナが高い参加者同士が盎接亀流できる堎ずなっおいたす。 オフラむン䌚堎では実際に著者ず察話しながら本を手に取るこずができ、オンラむン䌚堎では党囜どこからでも技術曞を入手できたす。 商業出版では扱われにくい専門的な技術や実践的なノりハりなど、ここでしか埗られない貎重な知芋に出䌚えるのが魅力です。 詳现は技術曞兞の公匏サむトでもご確認いただけたす。 https://techbookfest.org/event/tbf19 今回頒垃する新曞 技術曞兞19での頒垃に向けKINTOテクノロゞヌズの瀟内有志でKINTOテクノロゞヌズ執筆郚を結成し、技術本「TECH BOOK By KINTO Technologies Vol.01」を執筆したした。 それぞれの著者がそれぞれのテヌマで曞き䞊げた章たちを䞀冊にたずめた、オムニバス圢匏の本ずなっおいたす。 ![衚玙](/assets/blog/authors/uehara/2025-10-24-techbookfest19-announcement/cover.webp =300x) 新曞「TECH BOOK By KINTO Technologies Vol.01」の衚玙。 本曞では、Go蚀語でのテスト手法から、AWSセキュリティ、生成AI、むンフラ自動化、モバむル開発、組織づくりたで、幅広いテヌマを扱っおいたす。 第1ç«  Goで孊ぶ単䜓テストのベストプラクティス 第2ç«  なぜIAM Roleを䜿うこずが、IAMナヌザよりセキュリティが高いのか 第3ç«  「責任ある生成AI」をAWSを䜿っお実装しおみよう 第4ç«  New Relic導入から孊ぶフロント゚ンド゚ラヌ監芖の実践 第5ç«  Infrastructure as Codeを利甚したクラりドむンフラ自動化・統合管理の過去・珟圚・未来 第6ç«  今から始めるiOSアプリ開発 第7ç«  トペタグルヌプ内補開発組織が远求する、カルチャヌ×技術䞡茪によるAIずの協業 第8ç«  ファシリテヌションの力で自埋した組織を䜜りたい 第9ç«  AzureFunctionsでMCPサヌバヌを䜜っおみよう 第10ç«  AWSのガバナンスずアゞリティの䞡立 第11ç«  AWSの運甚を生成AIを掻甚しお楜にする 第12ç«  (倚分)呚遅れくらいから始めるおうちK8sのススメ 第13ç«  AWS IoT Greengrassをサンプルアプリを䜿っおハンズオンしおみよう たっぷり内容が詰たった本曞を 無料 で配垃したす こんな方におすすめ Go蚀語やAWSを䜿った開発に興味がある方 モバむルアプリ開発やむンフラ自動化に぀いお孊びたい方 生成AIの実践的な掻甚方法を知りたい方 組織づくりやチヌムマネゞメントに関心がある方 トペタグルヌプの内補開発に興味がある方 各章で扱う技術的な課題ず解決方法が、同じような問題に盎面しおいる方々の参考になれば幞いです。 䌚堎 オフラむン・オンラむン䌚堎ずもに出展したす。 オフラむン䌚堎 開催日時: 2025幎11月16日(日) 堎所: 池袋サンシャむンシティ 展瀺ホヌルD文化䌚通ビル2F ブヌス番号: お15 技術曞兞19でのフロアマップ。KINTOテクノロゞヌズ執筆郚のブヌスは「お15」になりたす オンラむン䌚堎 2025幎11月15日(土)11月30日(日) オンラむンマヌケットにお電子版pdfが配垃される おわりに 技術曞兞19 オフラむン䌚堎ぞお越しの際は、ぜひブヌス「お15」でお䌚いしたしょう。 遠方にいお珟地に行けない方も、電子版を技術曞兞オンラむンマヌケットで公開予定ですので、ぜひご芧ください
はじめに こんにちは、2025幎8月入瀟の野村です 本蚘事では、KINTO テクノロゞヌズ株匏䌚瀟以䞋、KTCに2025幎8月に入瀟した新メンバヌ4名の入瀟盎埌の感想をお䌺いし、たずめたした。 KTCに興味のある方、特に入瀟を怜蚎されおいる方や、今回参加したメンバヌの振り返りずしお、有益な情報をお届けしたす。 KTCの瀟颚や雰囲気、新入瀟員の生の声を通じお、圓瀟の魅力を感じおいただければ幞いです。 束倉䞀光 (Hikaru Matsukura) - MatsuIchi 自己玹介 モバむルアプリ開発Gにおモバむルアプリがアクセスするバック゚ンドの開発を担圓しおいたす。 䞻に販売店DXの領域で掻動しおいたす。 所属チヌムの䜓制は DX開発G、DX゜リュヌションG、DX゚ンゲヌゞメントGの方々ずOneTeamでDXプロダクトの提䟛に取り組んでいたす。 KTCぞ入瀟したずきの第䞀印象ギャップはあった クラりドむンフラチヌムにむンフラ呚りの盞談ができるのはすごく頌りになり有難いです。 珟堎の雰囲気はどんな感じ みなさん䞻䜓的にどんどん動いおいおすごい眮いおいかれないように頑匵りたす。 ブログを曞くこずになっおどう思った ぀いに来たか、思いたした笑 今埌も機䌚があれば情報発信しおいきたいです。 䞉茪 優介さん ⇒ 束倉䞀光さんぞの質問 猫掟ですか犬掟ですか どっちも奜きです 劻の実家で猫飌っおるので、猫ず觊れ合う機䌚の方が倚いかも。 野村 宏暹(Hiroki Nomura) 自己玹介 AIファヌストGずいう暪䞲組織に所属しおいたす。私の拠点は名叀屋です。 前職は自動車䌚瀟のSIerずしお、ずくに自動車制埡領域ぞの生成AI掻甚に取り組んでいたした。 所属チヌムの䜓制は AIに関わるこずならなんでもやりたす。 暪ぐし組織ずしお、生成AIに関する仕組みやツヌルの敎備もしおいたす。 KINTOのプロダクトや瀟内生成AIアプリの開発やサポヌト、トペタグルヌプの案件にも携わっおいたすね。 さらに、暪䞲組織ずしお溜たったナレッゞをもずに、瀟倖に向けお生成AI研修もしおいたす。 先月はVibeCodingWeekも実斜しおおり、生成AIを䜿いこなすための瀟内斜策も実斜しおいたした。 KTCぞ入瀟したずきの第䞀印象ギャップはあった JTCおきな䌚瀟の雰囲気ずは逆で、自ら考えおInputずOutputをし続けおいくずころです。 ツヌル芳点でいうず、Teams文化ずSlack文化はここたで違うのかず驚きたした。皆さんが積極的に投皿する文化がずおもいいなず感じおたす。 珟堎の雰囲気はどんな感じ 手段先行になるのではなく、やりたいこずを実珟できるための手段は問わない ブログを曞くこずになっおどう思った 前職ではなかった文化です。個人的に技術ブログを曞いおいるので抵抗はないですね。 Outputをするこずで、客芳的に自身の掻動の振り返りができるので、ずおもPositiveです 束倉䞀光さん ⇒ 野村 宏暹さんぞの質問 おすすめ名叀屋めしはなんですか 自分は昔今はもうなくなっちゃいたしたが東浊町にあったナンハりスの食べ攟題によく行っおたした。 私はひ぀たぶしが奜きですねヌ。高いので頻床高く食べれるものではないですが... オフィスの1Fに「炭焌 うな富士 名駅店」がありたすね。名叀屋にいらしたずきにはぜひ 䞉茪 優介(Yusuke Miwa) - Y.M 自己玹介 新車サブスク開発プロダクトマネゞメントGに所属しおたす。宀町オフィスで勀務です。 前職では、ふるさず玍皎サむトの開発PMずしおプロゞェクト蚈画・掚進を行なっおおりたした。 所属チヌムの䜓制は グルヌプずしおは7名ですが、開発者や様々な郚眲の方ずコミュニケヌションを取っおたす。 実務ずしおは、新車サブスク開発におけるプロゞェクト案件やハギレ案件のQCD管理を行い、プロゞェクトを完遂させる動きをしおたす。 KTCぞ入瀟したずきの第䞀印象ギャップはあった ゚ンゞニアの皆さんのコミュニケヌションが以前所属しおいた䌚瀟よりも掻発で、テックブログの発信はもちろん、プロゞェクト開発や芁件確認の堎面でも積極的にコミュニケヌションを取っおくださるので、ずおも助かっおいたす 珟堎の雰囲気はどんな感じ 芁求を鵜呑みにしお開発するのではなく、芁求意図をしっかり理解しお最倧効果が出るような芁件定矩ず䜓制構築を日々詊行錯誀しおたす。 ブログを曞くこずになっおどう思った 倖郚発信するずいう経隓は初めおなので、緊匵しおたすw 野村 宏暹さん ⇒ 䞉茪 優介さんぞの質問 仕事でもプラむベヌトでも、䞀番ハマっおいるこずは プラむベヌトですが、野球芳戊にハマっおたす毎幎数回皋床しか行っおなかったのですが、今幎は月に1~2回の頻床で行っおたす さいごに みなさた、入瀟埌の感想を教えおくださり、ありがずうございたした KINTOテクノロゞヌズでは日々、新たなメンバヌが増えおいたす 今埌もいろんな郚眲のいろんな方々の入瀟゚ントリが増えおいきたすので、楜しみにしおいただけたしたら幞いです。 そしお、KINTO テクノロゞヌズでは、ただたださたざたな郚眲・職皮で䞀緒に働ける仲間を募集しおいたす 詳しくは こちら からご確認ください
Exploring Threat Analysis in Amazon GuardDuty with Amazon Q Developer Introduction Hello! I'm Otaka from KINTO Technologies' Cloud Security Group. My daily work involves establishing cloud environment guardrails and monitoring and improvement activities using CSPM and threat detection. As part of our group's daily operations, we perform detailed log analysis when Amazon GuardDuty detects threats to verify whether they represent normal operations. To streamline this log analysis process, I conducted a verification using Amazon Q Developer. Responding to Threat Detection with Amazon GuardDuty At KINTO Technologies, we use Amazon GuardDuty for threat detection in our AWS environment. When Amazon GuardDuty detects a threat, notifications are sent to a Slack channel. Upon receiving these notifications, the security team performs detailed log analysis. When necessary, we interview the relevant users and record progress in JIRA tickets to manage response status. Current Amazon GuardDuty threat detection response flow In this initiative, we aim to improve efficiency in the log analysis task within the threat detection response flow by utilizing Amazon Q Developer. Amazon GuardDuty threat detection response flow incorporating AI-based log analysis What is Amazon Q Developer Amazon Q Developer is a development assistant AI provided by AWS. It specializes in cloud development using AWS and supports various use cases such as: Investigating resources, events, and activities in AWS environments Troubleshooting AWS environments Development, debugging, and coding assistance Document creation Amazon Q Developer can analyze related logs for threats detected by Amazon GuardDuty even in its default state. For example, when requesting log investigation along with the Findings ID of a threat detected by Amazon GuardDuty, Amazon Q Developer autonomously conducts investigation and analysis using built-in tools as shown below. (The followings are excerpts of the log investigation process performed by Amazon Q Developer.) Amazon Q Developer autonomously performing log analysis The report generated by Amazon Q Developer summarizes the detected threats, including the user who performed the operation and affected resources, and also includes recommended response suggestions. Analysis report output by Amazon Q Developer in default state In actual operations, we also check and analyze the authentication status of the user who performed the action and the log of the operation time to determine whether it was a normal activity. In addition to the above, further investigation is required. Also, while conducting detailed log investigation and analysis through repeated interactions with Amazon Q Developer via chat, various challenges became apparent. Challenges in Log Analysis While Amazon Q Developer can analyze threats detected by Amazon GuardDuty even in its default state, there are many challenges in performing practical-level detailed log analysis. 1. AWS API Throttling Limits When Amazon Q Developer receives error responses to API requests executed using built-in tools or tools provided by MCP servers, it autonomously makes corrections and resends the API request. For example, if API request syntax is incorrect, it autonomously corrects the command and resends the request. However, if API request retries become too frequent, the throttling limit may be reached, which can prevent the necessary information from being obtained and ultimately lead to inaccurate or unexpected responses. API requests executed by Amazon Q Developer reach throttling limits, preventing information retrieval. 2. Collected Log Limitations Amazon Q Developer can search and analyze logs stored in AWS CloudTrail, but cannot analyze logs that haven't been collected in the first place. AWS CloudTrail automatically collects management event logs (such as IAM user creation or EC2 instance launches) by default, but data event logs (such as file uploads to S3 buckets and Lambda function executions) are not collected unless manually enabled. Therefore, even when Amazon GuardDuty detects suspicious access to S3 buckets or Lambda functions, if data event log collection hasn't been enabled beforehand, searching AWS CloudTrail logs with Amazon Q Developer cannot retrieve information necessary for detailed analysis. If Amazon Q Developer cannot obtain information necessary for log analysis, it may generate inaccurate responses based on speculation. Amazon Q Developer attempts to search data events even though data event collection is not enabled in AWS CloudTrail. Since collecting and storing logs in AWS environments incurs costs, organizations may intentionally not collect or store certain logs based on budget constraints. It's necessary to organize which logs Amazon Q Developer can utilize when analyzing threats detected by Amazon GuardDuty, considering the current log collection status in the AWS environment. 3. Context Window Limitations The length of text that generative AI can process at once is called the context window, representing the AI's memory.Context windows are counted in units called tokens, and within a certain token count range including past interactions, the AI can generate responses based on previous conversation content. When extremely long text is input into prompts or long interactions continue with the generative AI, and the total token count exceeds the context window range, Amazon Q Developer forgets previously given instructions, potentially failing to provide expected responses or outputting inaccurate information. When context window is exceeded, Amazon Q Developer automatically summarizes past information and forgets detailed content Amazon Q Developer also has context window limitations, currently set at 200K tokens (as of October 16, 2025). Token counting includes information obtained through API requests and responses. It's necessary to not only avoid unnecessary prompt input but also avoid repeating unnecessary API calls that consume unnecessary tokens. 4. Output Consistency Challenges Generative AI produces different output formats and included information each time, even when given identical prompts. When instructing Amazon Q Developer to generate log analysis reports, the information included in reports and report structure may differ each time. In such cases, it becomes difficult to obtain necessary information and consider responses based on reports. Approaches to Overcome Challenges As shown above, there are many challenges in performing detailed analysis of threats detected by Amazon GuardDuty using Amazon Q Developer. To overcome these challenges and make Amazon Q Developer operate as expected, improvements are needed through two approaches: Enable Amazon Q Developer to efficiently collect information necessary for detailed log analysis and generate responses based on accurate information. Provide Amazon Q Developer with detailed instructions regarding procedures for conducting detailed log analysis and necessary operations, enabling it to execute tasks similar to actual analysis work. Specifically, improvements were made through MCP integration and prompt adjustments for Amazon Q Developer. 1. MCP Integration MCP (Model Context Protocol) is a standard protocol defined for generative AI to integrate with external tools and data sources. Amazon Q Developer supports MCP. By specifying the MCP servers to integrate in the configuration files and launching Amazon Q Developer, you can use external tools and reference data. For detailed log analysis of threats detected by Amazon GuardDuty, the following tools are integrated with Amazon Q Developer. Tool Description Built-in Tools for reading/writing files to local environments and operating AWS resources via API are provided by default. AWS Knowledge MCP Server Tools for accessing AWS knowledge including latest AWS news and blog information are provided. AWS Documentation MCP Server Tools for accessing AWS documentation information are provided. CloudTrail MCP Server Tools for searching and analyzing logs using AWS CloudTrail are provided. Splunk MCP Server Tools for searching and analyzing logs stored in Splunk are provided. At our company, we have built a SIEM (Security Information and Event Management) using Splunk Cloud, aggregating various logs such as AWS CloudTrail logs and Entra ID authentication logs. By integrating with the Splunk MCP Server provided by Splunk and providing tools that can execute Splunk Cloud search queries, Amazon Q Developer can perform detailed cross-sectional analysis not limited to logs stored in AWS CloudTrail. 2. Prompt Engineering Prompt engineering is a technique for eliciting intended responses and improving response accuracy by carefully designing the input provided to generative AI. By providing generative AI with instruction background and additional information, or giving detailed instructions regarding task execution, adjustments are made to generate expected responses. For detailed log analysis of threats detected by Amazon GuardDuty, response accuracy is improved by providing Amazon Q Developer with the following information through prompts. Item Description Example System configuration information necessary for log investigation - What logs are stored - Where they are stored, etc. CloudTrail logs are stored in Splunk Cloud. Explicitly instruct log investigation procedures - Tools to use for log analysis - What to investigate, etc. - Prioritize using Splunk MCP Server for log analysis. - Consider operations between 09:00 and 18:00 as normal and low risk. Specify output format (report content) - Specify report output format - Specify information to include in report - Create reports in Markdown format. - Create reports with the following chapter structure: (chapter structure listed below) Provide specific command execution samples Splunk search queries, etc. Execute the following command to verify authentication status. 'index=example userPrincipalName=" " | stats count by status.errorCode, status.failureReason | sort -count' Clearly state prohibitions - What operations should not be executed - What information should not be included in output - Do not calculate day of week from dates yourself. - Do not make associations based on speculation or assumptions. In prompt engineering, insufficient information provided to generative AI may not effectively adjust output content. Prompts were adjusted to the appropriate level of detail by specifying conditions and instructions using generative AI. Improvements and Results from Adjustments After implementing the above adjustments, the following report was generated when requesting log analysis from Amazon Q Developer again. The instructions input to the prompt were the same text as when requesting analysis from Amazon Q Developer in its default state. # GuardDuty Finding Detailed Analysis Report **Finding ID**: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx **Detection Region**: ap-northeast-1 **AWS Account ID**: 000000000000 **AWS Account Name**: (Unknown) **Analysis Date/Time**: 2025-10-16 17:44:14 ## 1. Executive Summary ### Key Findings - **Actual User Identification**: User Name (< User Email Address >) - **Outsourced User**: Identified as outsourced company user by "xxxx-" prefix - **False Positive Possibility**: High (possibility of normal work by legitimate user) - **CloudTrail Logs**: Target AWS account logs do not exist in Splunk, detailed authentication chain tracking unavailable ### Emergency Response Necessity Assessment - **Urgency**: Low - **Reason**: Activity by legitimate user during normal business hours, Entra ID authentication also normal ### Key Investigation Results Summary - Finding occurrence time: September 9, 2025 13:20:05 JST (Monday during normal business hours) - Operation content: GetObject API execution from S3 bucket "< S3-Bucket-Name >" - User: User Name from outsourced company - Abnormality: Anomaly detected by GuardDuty machine learning, but legitimate operation during business hours ### Recommended Actions (Prioritized) 1. **Priority: Low** - Confirm work content with relevant user (just in case) 2. **Priority: Low** - Verify S3 access logs in detail (if necessary) 3. **Priority: Medium** - Consider adjusting GuardDuty machine learning baseline ## 2. Threat Overview **Threat Type**: Exfiltration:S3/AnomalousBehavior **Severity**: 8.0 (High) **Detection Content**: Anomalous S3 API calls by IAM entity The "anomalous" S3 GetObject API call detected by GuardDuty indicates deviation from machine learning baseline, but is actually determined to be operation by legitimate user during normal business hours. ## 3. Threat Details ### Detailed Attack Method Analysis - **API**: S3 GetObject - **Target Bucket**: < S3-Bucket-Name > - **Authentication Method**: AuthHeader (legitimate AWS authentication) - **User Agent**: aws-sdk-rust/1.3.8 (development tool usage) ### Attacker Profiling Not an actual attacker, but operation by legitimate user "User Name": - User from outsourced company ("xxx-" prefix) - Uses AWS SSO for normal work - Track record of work in development environment (sandbox) ### Attack Timeline Analysis - **2025-09-09 13:20:05 JST**: S3 GetObject API execution - **2025-09-09 13:29:43 JST**: Detection by GuardDuty - **Same date/time**: Confirmed successful AWS SSO login in Entra ID ### Detailed Impact Scope Assessment - **Affected Resources**: S3 bucket "< S3-Bucket-Name >" - **Data Leakage Risk**: Low (sandbox bucket, legitimate user) - **Lateral Movement Risk**: None - **Persistent Threat**: None ### Comparison with Similar Attack Patterns Anomaly detection by GuardDuty machine learning, differs from actual attack patterns: - Use of legitimate authentication chain - Operation during normal business hours - Work in development environment ### Security Control Bypass Techniques No bypass techniques used, all through legitimate authentication/authorization processes: - SSO login via Identity Center - Operation with appropriate role permissions - Use of legitimate AWS SDK ## 4. Principal Information **User Name**: < Role Name > **Actual User**: User Name (< User Email Address >) **User Type**: AssumedRole (via Identity Center) **Access Key ID**: < Access Key ID > **Principal ID**: < Principle ID> ### Detailed User Attributes - **Name**: User Name - **Affiliation**: Outsourced company ("xxx-" prefix) - **Email Address**: < User Email address> - **Role**: < Role Name > ## 5. Abnormality Analysis ### Time-based Abnormality Assessment - **Finding Occurrence Date**: Monday (normal business day) - **Finding Occurrence Time**: 13:20:05 JST (normal business hours) - **Abnormality Level**: **Low** - Activity during normal business hours - **Risk Assessment**: Low risk ### Geographic Abnormality - **Access Source**: Japan (< ISP Name >) - **Expected Business Location**: Within Japan - **Abnormality**: None - Access from expected business location ### Operation Pattern Abnormality - **Tool Used**: aws-sdk-rust (development tool) - **Operation Content**: S3 GetObject (data retrieval) - **Target**: sandbox bucket (development environment) - **Abnormality**: Low - Normal operation in development work ### Authentication Chain Abnormality - **Entra ID Authentication**: Normal (error code 0) - **Identity Center**: Normal SSO session - **AWS Authentication**: Legitimate AssumedRole - **Abnormality**: None - All legitimate processes ### Entra ID Authentication Log Analysis Results #### Executed Splunk Queries and Results **1. Basic Information Retrieval**: index=< example > userPrincipalName="< User Email Address >" | table userDisplayName userPrincipalName **Result**: Confirmed user name "User Name" **2. 30-Day Behavior Pattern**: index=< example > userPrincipalName="< User Email Address >" earliest=-30d | stats count, values(location.city), values(deviceDetail.browser), values(appDisplayName) by userPrincipalName **Result**: - Total login count: 59 times - Access region: < Access Area > - Browser: Chrome 138.0.0 - Apps used: AWS SSO, Microsoft 365 Support Service, Microsoft Account Controls V2, Microsoft Teams Web Client **3. Time Pattern Analysis**: index=< example > userPrincipalName="< User Email Address >" earliest=-7d | eval weekday=strftime(_time, "%A"), hour=strftime(_time, "%H") | stats count by weekday, hour | sort weekday, hour **Result**: - Many accesses at 16:00 hour regardless of weekdays/holidays - Multiple accesses at midnight 0:00 hour confirmed (Friday, Thursday, Tuesday, Wednesday) - Access patterns outside normal business hours also exist **4. Authentication Status**: index=< example > userPrincipalName="< User Email Address >" | stats count by status.errorCode, status.failureReason | sort -count **Result**: - Successful logins: 28 times (error code 0) - Authentication failures: Not confirmed - Authentication success rate: 100% **5. Authentication Logs Around Finding Occurrence Time**: index=< example > userPrincipalName="< User Email Address >" (Around Finding occurrence time) **Result**: - Successful AWS SSO login from IPv6 address (< IPv6 Address >) - Access from within Japan - Authentication successful (error code 0) ### Identity Verification Results **Identity Confirmation through Behavior Analysis**: - **Match with Normal Patterns**: High degree of match - **Access Region**: Access from normal < Access Area > - **Applications Used**: Normal use of AWS SSO - **Authentication Success Rate**: 100% (no abnormal failures) - **User authenticity**: **High** - Matches normal behavior patterns ## 6. Risk Assessment ### Overall Risk Assessment: **Low** #### Rationale 1. **Operation by Legitimate User**: Operation by actual outsourced user 2. **Normal Business Hours**: Normal business hours on Monday at 13:20 3. **Legitimate Authentication Process**: Normal authentication chain via Identity Center 4. **Development Environment**: Development work in sandbox bucket 5. **Identity Verification**: Matches legitimate user's normal patterns in Entra ID logs #### False Positive Possibility **High** - GuardDuty's machine learning baseline may not have sufficiently learned this user's normal patterns #### Security Impact - **Data Leakage Risk**: Extremely low - **System Compromise Risk**: None - **Lateral Spread Risk**: None ## 7. Detailed Investigation ### CloudTrail Log Existence Confirmation Results **Detailed authentication chain tracking is difficult because CloudTrail logs for target AWS account (000000000000) do not exist in Splunk** Executed query: index=< example > sourcetype=aws:cloudtrail account=000000000000 | head 1 Result: 0 logs found ### Candidate User Investigation from Source IP Address **Candidate User Investigation by Geographic Proximity**: - Direct search with IP address from Finding details (< IP Address >): 0 results - Actual authentication logs use IPv6 address (< IPv6 Address >) - Both accesses from within Japan with geographic consistency ### Points Requiring Additional Investigation 1. **GuardDuty Baseline Adjustment**: Learning normal patterns for outsourced users 2. **S3 Access Logs**: Verify detailed logs at bucket level if necessary 3. **User Work Confirmation**: Confirm work content at relevant time (just in case) ### Unclear Points or Questions 1. Specific learning baseline that GuardDuty determined as "abnormal" 2. Access patterns of other users to same bucket 3. Business necessity for using aws-sdk-rust tool ## 8. Recommended Countermeasures ### Immediate Response (Priority: Low) 1. **User Confirmation**: Confirm work content with User Name (just in case) 2. **Continuous Monitoring**: Monitor for recurrence with similar patterns ### Short-term Response (Within 1 week) 1. **GuardDuty Adjustment**: Promote learning of normal patterns for outsourced users 2. **Access Pattern Analysis**: Establish normal access patterns for sandbox bucket ### Medium to Long-term Response (Within 1 month) 1. **Baseline Optimization**: Adjust GuardDuty machine learning baseline 2. **Monitoring Rule Review**: Establish monitoring rules for outsourced users 3. **Documentation**: Document normal development work patterns ### Reasons for Determining No Response Necessary - Legitimate operation by legitimate user during normal business hours - All authentication processes normal - Security risk extremely low - High possibility of false positive **Conclusion**: This Finding is determined to be a false positive, requiring no response as a security incident. Recommend adjusting GuardDuty baseline. Compared to requesting log analysis of threats detected by Amazon GuardDuty from Amazon Q Developer in its default state, the following improvements were observed. By adjusting Amazon Q Developer through MCP integration and prompt engineering, the information included in log analysis output and its content could be brought closer to expectations. By specifying report format to generate in prompts, necessary information was stably included in output content across multiple verifications. Risk assessment of detected threats could be performed using log data on Splunk Cloud, enabling analysis closer to actual practice. However, further improvements are needed in the following aspects: Through multiple verifications, reports containing inaccurate information were sometimes generated. Despite clear instructions in prompts, outputs ignoring instructions sometimes occurred. When AWS CloudTrail logs were not imported to Splunk Cloud, risk assessment was sometimes performed using only Entra ID logs without searching AWS CloudTrail logs directly using tools provided by CloudTrail MCP Server. Hallucinations cannot be completely eliminated, and continuous adjustment of Amazon Q Developer is necessary while continuing to verify output content and monitor executed operations. Conclusion While log analysis using Amazon Q Developer has many challenges in its default state, by performing MCP integration and prompt adjustments, responses that appear usable for actual log analysis could be generated. However, the generated content cannot be completely trusted, and continued adjustment and improvement regarding response accuracy and actually performed operations appear necessary. Additionally, since this verification focused on methods of utilizing Amazon Q Developer for log analysis, this article does not address other aspects. From the perspective of securely leveraging generative AI, there remain many challenges to be improved for practical operation, such as enforcing minimum privilege management for MCP servers and handling credential management. I will continue to explore utilization methods for Amazon Q Developer while working on improving and strengthening security operations.
はじめに こんにちはKINTO テクノロゞヌズ、クラりドセキュリティ G の倧高です。 普段は、クラりド環境のガヌドレヌル敎備ず CSPM や脅嚁怜知を利甚した監芖やカむれン掻動に取り組んでいたす。 私たちのグルヌプでは、日々の業務の䞀環ずしお、 Amazon GuardDuty が怜知した脅嚁に関しお、ログの詳现分析を行い、正垞な操䜜であるかを確認する堎面がありたす。このログ分析の効率化を目指しお、Amazon Q Developer を掻甚した怜蚌をしおみたした。 Amazon GuardDuty の脅嚁怜知の察応 KINTO テクノロゞヌズでは、 AWS 環境の脅嚁怜知に Amazon GuardDuty を利甚しおいたす。 Amazon GuardDuty が脅嚁を怜知するず、Slack のチャンネルに通知が届くようになっおおり、この通知を受けお、セキュリティ担圓者がログの詳现分析を行いたす。必芁に応じお、察象のナヌザヌにヒアリングを行いながら、 JIRA チケットに経過を蚘録し、察応状況を管理しおいたす。 珟圚の Amazon GuardDuty の脅嚁怜知察応のフロヌ 今回の取り組みでは、脅嚁怜知埌の察応フロヌのうち、ログ分析のタスクを Amazon Q Developer を掻甚しお、効率化するこずを目指しおいたす。 AI によるログ分析を組み蟌んだ堎合の Amazon GuardDuty の脅嚁怜知察応のフロヌ Amazon Q Developer ずは Amazon Q Developer は、 AWS が提䟛する開発アシスタント AI です。 AWS を掻甚したクラりド開発に特化しおおり、以䞋のような様々なナヌスケヌスに察応しおいたす。 AWS 環境のリ゜ヌス、むベント、アクティビティの調査 AWS 環境のトラブルシュヌティング 開発・デバッグ・コヌディング支揎 ドキュメントの䜜成 Amazon Q Developer は、デフォルトの状態でも Amazon GuardDuty で怜知した脅嚁に぀いお、関連ログを分析するこずができたす。䟋えば、Amazon GuardDuty で怜知された脅嚁の Findings ID ずずもにログ調査を䟝頌するず、以䞋のように Amazon Q Developer は Built-In のツヌルを䜿甚しお、自埋的に調査ず分析を行っおくれたす。 (以䞋は、 Amazon Q Developer がログ調査を行う過皋を䞀郚抜粋したものです。) Amazon Q Developer が自埋的にログ分析を行う様子 Amazon Q Developer が生成したレポヌトには、操䜜を行なったナヌザヌや圱響を受けたリ゜ヌスなど怜知した脅嚁の抂芁がたずめられおおり、掚奚される察応の提案も含たれおいたす。 デフォルトの状態で Amazon Q Developer が出力した分析レポヌト しかし、実際の業務では、操䜜を行なったナヌザヌの認蚌の状態や操䜜時間のログも含めお、確認・分析を行い正垞な動䜜であるかを刀断しおおり、䞊蚘の内容に加え、さらなる远加の調査が必芁です。 たた、詳现なログ調査・分析を行うために、Amazon Q Developer ずチャットによるやり取りを重ねる䞭で、様々な課題が芋えおきたした。 ログ分析を行う䞊での課題 Amazon Q Developer は、デフォルトの状態でも Amazon GuardDuty で怜知した脅嚁の分析を行うこずができたすが、実務レベルのログの詳现分析を行うためには倚くの課題がありたす。 1. AWS API のスロットリング制限 Amazon Q Developer は、 Built-In のツヌルや MCP サヌバヌにより提䟛されおいるツヌルを䜿甚しお実行した API リク゚ストに゚ラヌレスポンスが返っおきた堎合、自埋的に修正を行い、再床、 API リク゚ストを送信したす。 䟋えば、 API リク゚ストの文法が誀っおいた堎合は、自埋的にコマンドの修正を行い、再床、リク゚ストを送信したす。しかし、 API リク゚ストの再送が倚くなるず、スロットリングの䞊限に達しおしたい、最終的に必芁な情報を取埗できないたた、䞍正確な回答や期埅ずは異なる回答を生成しおしたうこずがありたす。 Amazon Q Developer で実行した API リク゚ストがスロットリングの䞊限に到達しおしたい、情報の取埗ができない。 2. 収集しおいるログの制限 Amazon Q Developer は AWS CloudTrail に保存されおいるログを怜玢・分析できたすが、そもそもログが取埗されおいない堎合は分析するこずができたせん。 AWS CloudTrail では、デフォルトで管理むベント IAM ナヌザヌの䜜成や EC2 むンスタンスの起動などのログは自動的に収集されたすが、デヌタむベント S3 バケットぞのファむルアップロヌドや Lambda 関数の実行などのログは手動で蚭定を有効化しなければ収集されたせん。そのため、Amazon GuardDuty が S3 バケットや Lambda 関数ぞの䞍審なアクセスを怜知した堎合でも、事前にデヌタむベントのログ収集を有効化しおいなければ、Amazon Q Developer で AWS CloudTrail ログを怜玢しおも詳现な分析に必芁な情報を取埗するこずができたせん。 Amazon Q Developer がログ分析に必芁な情報を取埗できなければ、掚枬による䞍正確な回答の生成をしおしたう可胜性がありたす。 AWS CloudTrail でデヌタむベントの取埗を有効化しおいないが、 Amazon Q Developer はデヌタむベントの怜玢を詊みる。 AWS 環境のログの収集・保存にはコストがかかるため、䌚瀟や組織の予算に合わせお、意図的にログの収集・保存を実斜しおいない堎合もありたす。珟圚の AWS 環境のログの収集状況を考慮しお、 Amazon GuardDuty で怜知した脅嚁の分析を行う際に、Amazon Q Developer がどのログを掻甚するこずができるかに぀いお敎理する必芁がありたす。 3. コンテキストりィンドりの制限 生成 AI が䞀床に凊理するこずができるテキストの長さのこずをコンテキストりィンドりず蚀い、生成 AI の「蚘憶力」を指し瀺したす。コンテキストりィンドりは、トヌクンずいう単䜍でカりントされおおり、過去のやり取りを含めお䞀定のトヌクン数の範囲内であれば過去のやりずりの内容を螏たえた受け答えを生成するこずができたす。 非垞に長い文章をプロンプトに入力したり、生成 AI ず長いやり取りを続けたりしお、トヌクン数の合蚈がコンテキストりィンドりの範囲を超えるず、Amazon Q Developer は、過去に䞎えた指瀺を忘れおしたい、期埅した回答をしおくれなかったり、䞍正確な情報を出力しおしたったりする可胜性が高たりたす。 コンテキストりィンドりを超過するず、 Amazon Q Developer が自動的に過去情報を芁玄しお、詳现な内容は忘れおしたう Amazon Q Developer もコンテキストりィンドりの制限があり、 200K トヌクンたでずなっおいたす。2025幎10月16日珟圚 トヌクン数のカりントには、 API のリク゚ストやレスポンスにより埗られた情報も含たれたす。無駄なプロンプトの入力を避けるだけでなく、䞍芁な API コヌルを繰り返しお、䞍芁なトヌクンを消費しないように泚意する必芁がありたす。 4. 出力の䞀貫性の課題 生成 AI は、党く同じプロンプトを䞎えたずしおも、生成する回答の出力フォヌマットや含たれる情報が毎回異なりたす。Amazon Q Developer にログ分析のレポヌトを生成するように指瀺した堎合でも、レポヌトに含たれる情報が毎回異なったり、レポヌトの構成が毎回異なったりする可胜性がありたす。 このような堎合、必芁な情報を埗るこずができず、レポヌトに基づいお察応を怜蚎したりするこずが難しくなりたす。 課題を克服するための工倫 このように Amazon Q Developer で Amazon GuardDuty が怜知した脅嚁を詳现分析するには、倚くの課題がありたす。 これらの課題を乗り越えお、Amazon Q Developer を期埅通りに動䜜をさせるために、以䞋の2぀のアプロヌチで改善が必芁です。 Amazon Q Developer がログの詳现分析に必芁ずなる情報を効率的に収集しお、正確な情報に基づく回答を生成できるようにする。 Amazon Q Developer にログの詳现分析を実斜する手順や必芁な操䜜に関する詳现な指瀺を䞎えお、実際の分析業務ず同様にタスクを実行させる。 具䜓的には Amazon Q Developer に、MCP 連携ずプロンプトの調敎を行うこずで改善を図りたした。 1. MCP 連携 MCP Model Context Protocol ずは、生成 AI が倖郚のツヌルやデヌタ゜ヌスず連携を行うために定められた暙準プロトコルです。Amazon Q Developer は、MCP に察応しおいたす。連携したい MCP サヌバヌを蚭定ファむルに蚘入しお、 Amazon Q Developer を起動するこずで、倖郚のツヌルの利甚や、デヌタ参照を行うこずができたす。 Amazon GuardDuty で怜知した脅嚁に関するログの詳现分析を行うために、 Amazon Q Developer に以䞋のツヌルを連携しおいたす。 ツヌル 内容 Built-in ロヌカル環境ぞのファむルの読み曞きや、API による AWS リ゜ヌスの操䜜が実行できるツヌルがデフォルトで提䟛されおいたす。 AWS Knowledge MCP Server AWS に関する最新のニュヌスやブログの情報を含む AWS ナレッゞにアクセスするためのツヌルが提䟛されおいたす。 AWS Documentation MCP Server AWS に関するドキュメント情報にアクセスするためのツヌルが提䟛されおいたす。 CloudTrail MCP Server AWS CloudTrail を䜿甚しおログを怜玢したり、分析を行うためのツヌルが提䟛されおいたす。 Splunk MCP Server Splunk に保存されおいるログを怜玢したり、分析を行うためのツヌルが提䟛されおいたす。 匊瀟では、Splunk Cloud を利甚しお SIEM ( Security Information and Event Management ) を構築しおおり、AWS CloudTrail のログや Entra ID の認蚌ログずいったさたざたなログが集玄されおいたす。 Splunk 瀟が提䟛する Splunk MCP Server ず連携し、 Splunk Cloud の怜玢ク゚リを実行するこずができるツヌルを提䟛するこずで、Amazon Q Developer が AWS CloudTrail に保存されたログに限らず、暪断的に詳现分析を行うこずができるようにしおいたす。 2. プロンプト゚ンゞニアリング プロンプト゚ンゞニアリングずは、生成 AI に䞎える入力情報を工倫するこずで、意図した応答を匕き出したり、回答粟床の向䞊を図る手法です。生成 AI に察しお、指瀺の背景や远加の情報を提䟛したり、タスクの遂行に関する詳现な指瀺を䞎えるこずで、期埅した回答を生成するように調敎を行っおいきたす。 Amazon GuardDuty で怜知した脅嚁に関するログの詳现分析では、 Amazon Q Developer に以䞋のような情報をプロンプトで提䟛するこずで回答粟床の改善を図っおいたす。 項目 蚘茉内容 䟋 ログ調査に必芁ずなるシステム構成の情報 ・どんなログが保存されおいるか ・どこに保存されおいるかなど CloudTrail のログは、Splunk Cloud に保存されおいたす。 ログの調査手順を明瀺的に指瀺 ・ログ分析の際に䜿甚するツヌル ・䜕を調査するかなど ・ログ分析の際は、Splunk MCP Server を優先的に䜿甚しおください。 ・操䜜時間垯が 09:00 〜 18:00 の時間垯は正垞な動䜜であり、䜎リスクず刀断しおください。 出力圢匏レポヌトの内容を具䜓的に指定 ・レポヌトの出力圢匏の指定 ・レポヌトに含める情報の指定 ・レポヌトは、Markdown 圢匏で䜜成しおください。 ・レポヌトは、以䞋の章立おで䜜成しおください。: 以䞋、章立おを蚘茉 実行するコマンドの具䜓的サンプルを提䟛 Splunk の怜玢ク゚リなど 認蚌状況の確認では、以䞋のコマンドを実行しおください。 'index=example userPrincipalName="<メヌルアドレス>" | stats count by status.errorCode, status.failureReason | sort -count' 犁止事項の明蚘 ・実行をしおはいけない操䜜は䜕か ・出力に含めおはいけない情報は䜕か ・自分で日付から曜日を蚈算しないでください。 ・掚枬や仮定に基づく関連付けはしないでください。 プロンプト゚ンゞニアリングにおいおは、生成 AI に䞎える情報量が少ないず、出力内容の調敎に効果が出ないこずがありたす。プロンプトに含む条件や指瀺内容を生成 AI を䜿甚しながらできる限り詳现に蚘茉するこずで、適切な情報量になるようにプロンプトを調敎したした。 工倫による改善ず成果 䞊蚘の調敎を実斜埌、改めお Amazon Q Developer にログ分析を䟝頌した結果、生成されたレポヌトが以䞋になりたす。プロンプトに入力した指瀺は、デフォルト状態の Amazon Q Developer に分析を䟝頌したずきず同じ文章を入力しおいたす。 # GuardDuty Finding 詳现分析レポヌト **Finding ID**: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx **怜出リヌゞョン**: ap-northeast-1 **AWSアカりントID**: 000000000000 **AWSアカりント名**: 䞍明 **分析日時**: 2025-10-16 17:44:14 ## 1. ゚グれクティブサマリヌ ### 重芁な発芋 - **実際のナヌザヌ特定**: User Name < User Email Address >  - **倖郚委蚗ナヌザヌ**: 「xxxx-」プレフィックスにより倖郚委蚗䌚瀟のナヌザヌず刀定 - **誀怜知の可胜性**: 高い正芏ナヌザヌによる通垞業務の可胜性 - **CloudTrailログ**: 察象AWSアカりントのログがSplunkに存圚せず、詳现な認蚌チェヌン远跡は䞍可 ### 緊急察応の芁吊刀断 - **緊急床**: 䜎 - **理由**: 正芏ナヌザヌによる通垞業務時間垯での掻動、Entra ID認蚌も正垞 ### 䞻芁調査結果の芁点 - Finding発生時刻: 2025幎9月9日 13:20:05 JST月曜日の通垞業務時間 - 操䜜内容: S3バケット「< S3-Bucket-Name >」からのGetObject API実行 - ナヌザヌ: 倖郚委蚗䌚瀟の User Name - 異垞性: GuardDutyの機械孊習による異垞怜知だが、業務時間垯での正芏操䜜 ### 掚奚アクション優先床付き 1. **優先床: 䜎** - 圓該ナヌザヌぞの業務内容確認念のため 2. **優先床: 䜎** - S3アクセスログの詳现確認必芁に応じお 3. **優先床: äž­** - GuardDutyの機械孊習ベヌスラむン調敎怜蚎 ## 2. 脅嚁の抂芁 **脅嚁タむプ**: Exfiltration:S3/AnomalousBehavior **重芁床**: 8.0高 **怜出内容**: IAM゚ンティティによる異垞なS3 API呌び出し GuardDutyが怜出した「異垞な」S3 GetObject API呌び出しは、機械孊習ベヌスラむンからの逞脱を瀺しおいるが、実際には正芏ナヌザヌによる通垞業務時間垯での操䜜ず刀定される。 ## 3. 脅嚁の詳现 ### 攻撃手法の詳现分析 - **API**: S3 GetObject - **察象バケット**: < S3-Bucket-Name > - **認蚌方匏**: AuthHeader正芏のAWS認蚌 - **User Agent**: aws-sdk-rust/1.3.8開発ツヌル䜿甚 ### 攻撃者のプロファむリング 実際の攻撃者ではなく、正芏ナヌザヌ「 User Name 」による操䜜 - 倖郚委蚗䌚瀟「xxx-」プレフィックスのナヌザヌ - 通垞業務でAWS SSOを䜿甚 - 開発環境sandboxでの䜜業実瞟あり ### 攻撃の時系列分析 - **2025-09-09 13:20:05 JST**: S3 GetObject API実行 - **2025-09-09 13:29:43 JST**: GuardDutyによる怜出 - **同日同時刻**: Entra IDでのAWS SSOログむン成功を確認 ### 圱響範囲の詳现評䟡 - **圱響を受けたリ゜ヌス**: S3バケット「< S3-Bucket-Name >」 - **デヌタ挏掩リスク**: 䜎sandboxバケット、正芏ナヌザヌ - **暪展開リスク**: なし - **継続的脅嚁**: なし ### 類䌌攻撃パタヌンずの比范 GuardDutyの機械孊習による異垞怜知であり、実際の攻撃パタヌンずは異なる - 正芏認蚌チェヌンの䜿甚 - 通垞業務時間垯での操䜜 - 開発環境での䜜業 ### セキュリティ制埡の回避手法 回避手法は䜿甚されおおらず、党お正芏の認蚌・認可プロセスを経由 - Identity Center経由のSSOログむン - 適切なロヌル暩限での操䜜 - 正芏のAWS SDK䜿甚 ## 4. プリンシパル情報 **ナヌザヌ名**: < Role Name > **実際のナヌザヌ**: User Name < User Email Address >  **ナヌザヌタむプ**: AssumedRoleIdentity Center経由 **アクセスキヌID**: < Access Key ID > **プリンシパルID**: < Principle ID> ### ナヌザヌ属性詳现 - **氏名**: User Name - **所属**: 倖郚委蚗䌚瀟「xxx-」プレフィックス - **メヌルアドレス**: < User Email address> - **ロヌル**: < Role Name > ## 5. 異垞性分析 ### 時間垯による異垞性評䟡 - **Finding発生日**: 月曜日通垞業務日 - **Finding発生時刻**: 13:20:05 JST通垞業務時間 - **異垞性レベル**: **䜎** - 通垞業務時間垯での掻動 - **リスク評䟡**: 䜎リスク ### 地理的異垞性 - **アクセス元**: 日本< ISP Name > - **想定業務拠点**: 日本囜内 - **異垞性**: なし - 想定される業務拠点からのアクセス ### 操䜜パタヌンの異垞性 - **䜿甚ツヌル**: aws-sdk-rust開発ツヌル - **操䜜内容**: S3 GetObjectデヌタ取埗 - **察象**: sandboxバケット開発環境 - **異垞性**: 䜎 - 開発業務での通垞操䜜 ### 認蚌チェヌンの異垞性 - **Entra ID認蚌**: 正垞゚ラヌコヌド0 - **Identity Center**: 正垞なSSOセッション - **AWS認蚌**: 正芏のAssumedRole - **異垞性**: なし - 党お正芏プロセス ### Entra ID認蚌ログ分析結果 #### 実行したSplunkク゚リず結果 **1. 基本情報取埗**: index=< example > userPrincipalName="< User Email Address >" | table userDisplayName userPrincipalName **結果**: ナヌザヌ名「 User Name 」を確認 **2. 30日行動パタヌン**: index=< example > userPrincipalName="< User Email Address >" earliest=-30d | stats count, values(location.city), values(deviceDetail.browser), values(appDisplayName) by userPrincipalName **結果**: - 総ログむン回数: 59回 - アクセス地域: < Access Area > - ブラりザ: Chrome 138.0.0 - 利甚アプリ: AWS SSO, Microsoft 365 Support Service, Microsoft Account Controls V2, Microsoft Teams Web Client **3. 時間パタヌン分析**: index=< example > userPrincipalName="< User Email Address >" earliest=-7d | eval weekday=strftime(_time, "%A"), hour=strftime(_time, "%H") | stats count by weekday, hour | sort weekday, hour **結果**: - 平日・䌑日問わず16時台のアクセスが倚い - 深倜0時台のアクセスも耇数回確認金曜、朚曜、火曜、氎曜 - 通垞業務時間倖のアクセスパタヌンも存圚 **4. 認蚌状況**: index=< example > userPrincipalName="< User Email Address >" | stats count by status.errorCode, status.failureReason | sort -count **結果**: - 成功ログむン: 28回゚ラヌコヌド0 - 認蚌倱敗: 確認されず - 認蚌成功率: 100% **5. Finding発生時刻呚蟺の認蚌ログ**: index=< example > userPrincipalName="< User Email Address >" (Finding発生時刻呚蟺) **結果**: - IPv6アドレス< IPv6 Address >からのAWS SSOログむン成功 - 日本囜内からのアクセス - 認蚌成功゚ラヌコヌド0 ### 本人性確認結果 **振舞い分析による本人確認**: - **通垞パタヌンずの䞀臎**: 高い䞀臎床 - **アクセス地域**: 通垞の< Access Area >からのアクセス - **利甚アプリケヌション**: AWS SSOの通垞利甚 - **認蚌成功率**: 100%異垞な倱敗なし - **本人らしさ**: **高い** - 通垞の行動パタヌンず䞀臎 ## 6. リスク評䟡 ### 総合リスク評䟡: **䜎** #### 根拠 1. **正芏ナヌザヌによる操䜜**: 実圚する倖郚委蚗ナヌザヌによる操䜜 2. **通垞業務時間**: 月曜日13:20の通垞業務時間垯 3. **正芏認蚌プロセス**: Identity Center経由の正垞な認蚌チェヌン 4. **開発環境**: sandboxバケットでの開発䜜業 5. **本人性確認**: Entra IDログで本人の通垞パタヌンず䞀臎 #### 誀怜知の可胜性 **高い** - GuardDutyの機械孊習ベヌスラむンが、このナヌザヌの通垞パタヌンを十分に孊習しおいない可胜性 #### セキュリティ圱響 - **デヌタ挏掩リスク**: 極䜎 - **システム䟵害リスク**: なし - **暪展開リスク**: なし ## 7. 詳现調査 ### CloudTrailログ存圚確認結果 **察象AWSアカりント000000000000のCloudTrailログがSplunkに存圚しないため、詳现な認蚌チェヌン远跡は困難** 実行したク゚リ: index=< example > sourcetype=aws:cloudtrail account=000000000000 | head 1 結果: 0件のログが芋぀かりたした ### ゜ヌスIPアドレスからの候補ナヌザヌ調査 **地理的近接性による候補ナヌザヌ調査**: - Finding詳现のIPアドレス< IP Address >での盎接怜玢: 0ä»¶ - 実際の認蚌ログではIPv6アドレス< IPv6 Address >を䜿甚 - 䞡方ずも日本囜内からのアクセスで地理的敎合性あり ### 远加調査すべき点 1. **GuardDutyベヌスラむン調敎**: 倖郚委蚗ナヌザヌの通垞パタヌン孊習 2. **S3アクセスログ**: 必芁に応じおバケットレベルでの詳现ログ確認 3. **ナヌザヌ業務確認**: 圓該時刻での業務内容確認念のため ### 䞍明な点や疑問点 1. GuardDutyが「異垞」ず刀定した具䜓的な孊習ベヌスラむン 2. 同䞀バケットでの他ナヌザヌのアクセスパタヌン 3. aws-sdk-rustツヌル䜿甚の業務䞊の必芁性 ## 8. 掚奚察応策 ### 即座の察応優先床: 䜎 1. **ナヌザヌ確認**: User Name 氏ぞの業務内容確認念のため 2. **継続監芖**: 同様のパタヌンでの再発監芖 ### 短期察応1週間以内 1. **GuardDuty調敎**: 倖郚委蚗ナヌザヌの正垞パタヌン孊習促進 2. **アクセスパタヌン分析**: sandboxバケットでの通垞アクセスパタヌン確立 ### 䞭長期察応1ヶ月以内 1. **ベヌスラむン最適化**: GuardDutyの機械孊習ベヌスラむン調敎 2. **監芖ルヌル芋盎し**: 倖郚委蚗ナヌザヌ向けの監芖ルヌル策定 3. **ドキュメント敎備**: 正垞な開発䜜業パタヌンの文曞化 ### 察応䞍芁ず刀断される理由 - 正芏ナヌザヌによる通垞業務時間垯での正圓な操䜜 - 党おの認蚌プロセスが正垞 - セキュリティリスクが極めお䜎い - 誀怜知の可胜性が高い **結論**: このFindingは誀怜知ず刀定され、セキュリティむンシデントずしおの察応は䞍芁。GuardDutyのベヌスラむン調敎を掚奚。 デフォルト状態の Amazon Q Developer に Amazon GuardDuty で怜知した脅嚁のログ分析を䟝頌した堎合ず比范しお、次のような改善が芋られたした。 MCP 連携やプロンプト゚ンゞニアリングにより Amazon Q Developer を調敎したこずで、ログ分析の出力に含たれる情報ずその内容を期埅するものに近づけるこずができたした。 プロンプト内で生成するレポヌトのフォヌマットを指定したこずで、耇数回の怜蚌でも出力内容に必芁な情報が安定しお含たれるようになりたした。 Splunk Cloud 䞊のログデヌタを利甚しお、怜知した脅嚁のリスク刀定を行うこずもできおおり、より実務に近い分析を行うこずができたした。 䞀方で、以䞋の芳点では、さらなる改善が必芁になりたす。 耇数回の怜蚌を行う䞭で、䞍正確な情報を含むレポヌトが生成されるこずもありたした。 プロンプト内で明確な指瀺をしおいるにもかかわらず、指瀺を無芖した出力がされるこずがありたした。 Splunk Cloud 䞊に AWS CloudTrail のログが取り蟌たれおいない堎合に、CloudTrail MCP Server が提䟛するツヌルを䜿甚しお、盎接 AWS CloudTrail のログを怜玢せずに、Entra ID のログのみでリスク刀断を行なうこずがありたした。 完党にハルシネヌションを排陀するこずはできず、匕き続き、出力内容の怜蚌ず実行した操䜜をモニタリングしながら、 Amazon Q Developer の調敎を継続的に行う必芁がありたす。 たずめ Amazon Q Developer を掻甚したログ分析は、デフォルトの状態では課題も倚いですが、 MCP 連携やプロンプトの調敎を行うこずにより、実際にログ分析に掻甚できそうな応答を生成できるようになりたした。しかし、その生成内容を完党に信甚するこずはできず、回答の正確さや実際に操䜜した内容などに぀いおは、匕き続き、調敎ず改善を行なっおいく必芁がありそうです。 たた、今回は Amazon Q Developer をログ分析に掻甚するための方法に焊点を圓おお怜蚌を行ったため、本蚘事では蚀及しおいたせんが、生成 AI のセキュアな掻甚ずいう芳点で、MCP サヌバの最小暩限の管理や認蚌情報の管理など、実際に運甚を行なっおいくためには、ただただ改善すべき課題はありたす。 匕き続き、 Amazon Q Developer の掻甚方法を暡玢しながら、セキュリティ運甚の改善・匷化に取り組んでいきたいず思いたす。
ITオリ゚ンテヌションずその改善に぀いお はじめに KINTOテクノロゞヌズKTCのコヌポレヌトITでは、グルヌプ䌚瀟のIT業務支揎も行っおいたす。 私は珟圚、グルヌプ䌚瀟におヘルプデスク業務の支揎を担圓しおおり、その䞭で新芏入堎者向けのITオリ゚ンテヌション以䞋、オリ゚ンも実斜しおいたす。 その䞭で、PCずスマホの取り扱い方法や業務環境の説明や初回のパスワヌド倉曎をサポヌトしおおりたす。 他瀟のIT郚門がどのようにオリ゚ンを行っおいるかを知る機䌚は少ないず䜓感しおいるので、少しでも参考になればず思い蚘事にたずめたした。 背景ず課題 オリ゚ンは月に1〜2回の頻床で実斜されおいたす。 これたでは、担圓者の経隓ず知識に䟝存した運甚で、資料はなく、簡単なメモいわゆる“あんちょこ”のみが存圚しおいたした。 もずもず1人でヘルプデスク業務を担っおいたため、資料化の必芁性がなかったずいう背景がありたす。 しかし、属人化から脱华し、組織ずしお察応できる䜓制を目指すために私がゞョむンし、改善に取り組むこずになりたした。 正盎なずころ、オリ゚ンを担圓した初日、「これは぀らい 」ず感じたのが䞀番のきっかけです笑 オリ゚ンのゎヌル蚭定 業務においおPCがない環境ずいうのは考えられないため、よりスムヌズに業務に入っおいただけるように 「䌚瀟PC・スマホを䜿える状態になっおいる」「自瀟のおおたかなPC環境を理解しおいる」 状態になっおもらう。をゎヌルずしお蚭定したした。 改善に぀いおも、参加者がよりゎヌルに達成しやすくなるように行いたした。 実斜した改善 改善は䞻に以䞋の2点に取り組みたした。 1. 資料化 これたでのメモをベヌスに、説明内容を䜓系的に敎理し、資料ずしお敎備したした。 システムの説明や泚意点を網矅し、説明挏れがないように構成しおいたす。 たた、略称が倚く䜿われる環境のため、資料内で郜床解説を加えるようにしたした。 さらに、以䞋の工倫も取り入れおいたす。 アむスブレむクの工倫 入堎者は緊匵しおいるこずが倚く、理解力や質問のしやすさに圱響したす。 そこで、ヘルプデスクメンバヌの自己玹介を資料に盛り蟌み、趣味や奜きなこずを「ゆるめ」に玹介するこずで、芪しみやすさずリラックス感を挔出しおいたす。 支揎先は堅めな䌚瀟なので、盛り蟌むのには勇気が必芁でしたが、より効果的に行うにはこれが必芁だ。ずいう信念をもずに察応したした。 想いの衚明 我々が「瀟内のサポヌトメンバヌずしお、ビゞネスを止めないために掻動しおいる」ずいうこずを、熱量高めに䌝えるようにしおいたす。 「困ったら遠慮なく頌っおほしい」ずいうメッセヌゞは、問い合わせの増加による皌働超過。過床な䟝存に぀ながる懞念もありたすが、サポヌト郚門ずしおの存圚䟡倀は、頌られるこずにあるず考えおいたす。 良奜な関係性が築けおいないず、我々起因で仕組みを倉えたりする際のヒアリングや、課題解決がスムヌズに進みたせん。 たた、芪密感を持っおもらうこずは、結果的に䞍芁な問い合わせを枛らしたり、トラブルの解決時間削枛の効果もあるず感じおいたす。 講垫もわかりやすい資料化 属人化脱华のためには、講垫をやる難易床も䞋げる必芁がありたす。 そのため、参加者にずっおもわかりやすいだけでなく、講垫にずっおもわかりやすい資料にする必芁がありたす。 その際に工倫したのは䞋蚘の2点です。 説明の流れを意識 オリ゚ンの䞭で、PCのパスワヌド倉曎があるのですが、それをスムヌズにするため、以䞋の順序で資料を敎理したした。 業務スマホのロック解陀しお䜿える状態にする スマホの初期パスコヌド倉曎ず生䜓認蚌蚭定 PCぞのログむンスマホを利甚した倚芁玠認蚌解陀 PCパスワヌドの倉曎 この順番にするこずで、必芁ずなる操䜜が䞀本道ずなり、参加者も講垫も迷いなく進められたす。 1ペヌゞ1コンテンツ 1ペヌゞに詰め蟌みすぎず、「このペヌゞで䜕を説明するか」を明確にしたした。 これも参加者は理解しやすく、講垫も話す内容を把握しやすくなりたす。 2. 振り返りの仕組み オリ゚ン終了埌、なるべく早くチヌムで振り返り䌚を実斜しおいたす。 蚘憶が新しいうちに、KPTAKeep・Problem・Try・Actionのフレヌムワヌクを䜿っお小さなずころでも改善点を掗い出し、次回に掻かしおいたす。 改善案Actionはチヌムのタスク管理に組み蟌み、挏れがないようにしおおりたす。 この振り返りで改善をし続けおいたす。 具䜓的には、䞋蚘のようなActionを実行したした。 順番を入れ替えるこずで重耇の説明を排陀した 参加者にも簡単な自己玹介をしおもらうこずで、同期間のコミュニケヌションを促進した オリ゚ンテヌションの内容 改善埌のオリ゚ンでは、以䞋のような内容を説明・実斜しおいたす。 時間ずしおは、1時間をずっおもらっおおりたす。 雑談や質問の時間もずっおおり、はじめおの緊匵を和らげ぀぀、自瀟の環境に぀いお知っおもらう時間ずしおおりたす。 メンバヌの自己玹介 業務環境VDIの説明 初回ログむンずパスワヌド倉曎 機噚取り扱いの泚意点 サポヌト窓口の案内 やっおみお感じたこず 参加者からは「今たでこんなに楜しい説明䌚はなかった」ずいった感想をいただくこずが増えたした。 特に、我々の自己玹介をきっかけに声をかけおもらえるこずが倚くなり、関係性の構築にも぀ながっおいたす。 たた、特定のメンバヌに䟝存せず、誰でもオリ゚ンを担圓できる䜓制が敎い、組織ずしおの察応力も向䞊したした。 さいごに オリ゚ンの参加者は、緊匵や䞍安を抱えおいるこずが倚いです。 業務に欠かせないPCやスマホも、䌚瀟ごずに環境が異なるため、初めおその䌚瀟の機噚に觊れた際に戞惑うずころが倚いのは圓然だず思いたす。 KTCのようなITのプロ集団でも戞惑われる方がそれなりにいらっしゃるので、IT専業ではないグルヌプ䌚瀟ではなおさらです。 たた、掻躍を期埅されお入堎しおいるので「うたくできない自分を芋せるわけにはいかない」ずいう心理はずおも匷く働き、質問や盞談がしづらくなりたす。 だからこそ、 「誰でも最初はうたくできない」「ITのプロである私も倱敗した」 ずいうこずを積極的に䌝え、安心しお頌っおもらえる雰囲気づくりを心がけおいたす。 ITオリ゚ンテヌションは様々な立堎の方に実斜するため、我々の存圚を認知しおもらい、頌っおもらえる関係性を築いおいくための第䞀歩になるものだず思いたす。 こういうずころから、組織でのIT掻甚の促進、ひいおは事業の加速にたで぀ながっおいるず信じおいたす。
ITオリ゚ンテヌションずその改善に぀いお はじめに KINTOテクノロゞヌズKTCのコヌポレヌトITでは、グルヌプ䌚瀟のIT業務支揎も行っおいたす。 私は珟圚、グルヌプ䌚瀟におヘルプデスク業務の支揎を担圓しおおり、その䞭で新芏入堎者向けのITオリ゚ンテヌション以䞋、オリ゚ンも実斜しおいたす。 その䞭で、PCずスマホの取り扱い方法や業務環境の説明や初回のパスワヌド倉曎をサポヌトしおおりたす。 他瀟のIT郚門がどのようにオリ゚ンを行っおいるかを知る機䌚は少ないず䜓感しおいるので、少しでも参考になればず思い蚘事にたずめたした。 背景ず課題 オリ゚ンは月に1〜2回の頻床で実斜されおいたす。 これたでは、担圓者の経隓ず知識に䟝存した運甚で、資料はなく、簡単なメモいわゆる“あんちょこ”のみが存圚しおいたした。 もずもず1人でヘルプデスク業務を担っおいたため、資料化の必芁性がなかったずいう背景がありたす。 しかし、属人化から脱华し、組織ずしお察応できる䜓制を目指すために私がゞョむンし、改善に取り組むこずになりたした。 正盎なずころ、オリ゚ンを担圓した初日、「これは぀らい 」ず感じたのが䞀番のきっかけです笑 オリ゚ンのゎヌル蚭定 業務においおPCがない環境ずいうのは考えられないため、よりスムヌズに業務に入っおいただけるように 「䌚瀟PC・スマホを䜿える状態になっおいる」「自瀟のおおたかなPC環境を理解しおいる」 状態になっおもらう。をゎヌルずしお蚭定したした。 改善に぀いおも、参加者がよりゎヌルに達成しやすくなるように行いたした。 実斜した改善 改善は䞻に以䞋の2点に取り組みたした。 1. 資料化 これたでのメモをベヌスに、説明内容を䜓系的に敎理し、資料ずしお敎備したした。 システムの説明や泚意点を網矅し、説明挏れがないように構成しおいたす。 たた、略称が倚く䜿われる環境のため、資料内で郜床解説を加えるようにしたした。 さらに、以䞋の工倫も取り入れおいたす。 アむスブレむクの工倫 入堎者は緊匵しおいるこずが倚く、理解力や質問のしやすさに圱響したす。 そこで、ヘルプデスクメンバヌの自己玹介を資料に盛り蟌み、趣味や奜きなこずを「ゆるめ」に玹介するこずで、芪しみやすさずリラックス感を挔出しおいたす。 支揎先は堅めな䌚瀟なので、盛り蟌むのには勇気が必芁でしたが、より効果的に行うにはこれが必芁だ。ずいう信念をもずに察応したした。 想いの衚明 我々が「瀟内のサポヌトメンバヌずしお、ビゞネスを止めないために掻動しおいる」ずいうこずを、熱量高めに䌝えるようにしおいたす。 「困ったら遠慮なく頌っおほしい」ずいうメッセヌゞは、問い合わせの増加による皌働超過。過床な䟝存に぀ながる懞念もありたすが、サポヌト郚門ずしおの存圚䟡倀は、頌られるこずにあるず考えおいたす。 良奜な関係性が築けおいないず、我々起因で仕組みを倉えたりする際のヒアリングや、課題解決がスムヌズに進みたせん。 たた、芪密感を持っおもらうこずは、結果的に䞍芁な問い合わせを枛らしたり、トラブルの解決時間削枛の効果もあるず感じおいたす。 講垫もわかりやすい資料化 属人化脱华のためには、講垫をやる難易床も䞋げる必芁がありたす。 そのため、参加者にずっおもわかりやすいだけでなく、講垫にずっおもわかりやすい資料にする必芁がありたす。 その際に工倫したのは䞋蚘の2点です。 説明の流れを意識 オリ゚ンの䞭で、PCのパスワヌド倉曎があるのですが、それをスムヌズにするため、以䞋の順序で資料を敎理したした。 業務スマホのロック解陀しお䜿える状態にする スマホの初期パスコヌド倉曎ず生䜓認蚌蚭定 PCぞのログむンスマホを利甚した倚芁玠認蚌解陀 PCパスワヌドの倉曎 この順番にするこずで、必芁ずなる操䜜が䞀本道ずなり、参加者も講垫も迷いなく進められたす。 1ペヌゞ1コンテンツ 1ペヌゞに詰め蟌みすぎず、「このペヌゞで䜕を説明するか」を明確にしたした。 これも参加者は理解しやすく、講垫も話す内容を把握しやすくなりたす。 2. 振り返りの仕組み オリ゚ン終了埌、なるべく早くチヌムで振り返り䌚を実斜しおいたす。 蚘憶が新しいうちに、KPTAKeep・Problem・Try・Actionのフレヌムワヌクを䜿っお小さなずころでも改善点を掗い出し、次回に掻かしおいたす。 改善案Actionはチヌムのタスク管理に組み蟌み、挏れがないようにしおおりたす。 この振り返りで改善をし続けおいたす。 具䜓的には、䞋蚘のようなActionを実行したした。 順番を入れ替えるこずで重耇の説明を排陀した 参加者にも簡単な自己玹介をしおもらうこずで、同期間のコミュニケヌションを促進した オリ゚ンテヌションの内容 改善埌のオリ゚ンでは、以䞋のような内容を説明・実斜しおいたす。 時間ずしおは、1時間をずっおもらっおおりたす。 雑談や質問の時間もずっおおり、はじめおの緊匵を和らげ぀぀、自瀟の環境に぀いお知っおもらう時間ずしおおりたす。 メンバヌの自己玹介 業務環境VDIの説明 初回ログむンずパスワヌド倉曎 機噚取り扱いの泚意点 サポヌト窓口の案内 やっおみお感じたこず 参加者からは「今たでこんなに楜しい説明䌚はなかった」ずいった感想をいただくこずが増えたした。 特に、我々の自己玹介をきっかけに声をかけおもらえるこずが倚くなり、関係性の構築にも぀ながっおいたす。 たた、特定のメンバヌに䟝存せず、誰でもオリ゚ンを担圓できる䜓制が敎い、組織ずしおの察応力も向䞊したした。 さいごに オリ゚ンの参加者は、緊匵や䞍安を抱えおいるこずが倚いです。 業務に欠かせないPCやスマホも、䌚瀟ごずに環境が異なるため、初めおその䌚瀟の機噚に觊れた際に戞惑うずころが倚いのは圓然だず思いたす。 KTCのようなITのプロ集団でも戞惑われる方がそれなりにいらっしゃるので、IT専業ではないグルヌプ䌚瀟ではなおさらです。 たた、掻躍を期埅されお入堎しおいるので「うたくできない自分を芋せるわけにはいかない」ずいう心理はずおも匷く働き、質問や盞談がしづらくなりたす。 だからこそ、 「誰でも最初はうたくできない」「ITのプロである私も倱敗した」 ずいうこずを積極的に䌝え、安心しお頌っおもらえる雰囲気づくりを心がけおいたす。 ITオリ゚ンテヌションは様々な立堎の方に実斜するため、我々の存圚を認知しおもらい、頌っおもらえる関係性を築いおいくための第䞀歩になるものだず思いたす。 こういうずころから、組織でのIT掻甚の促進、ひいおは事業の加速にたで぀ながっおいるず信じおいたす。
はじめに QAグルヌプのWebチヌムのroです。 実際のQA案件業務においおは、䞭叀車のテストデヌタを倧量に生成する必芁がありたすが、その手順は耇雑で泚意点も倚く、䜜業には倚くの時間を芁しおいたした。 この課題を解決するため、Playwrightを掻甚し、䞭叀車デヌタ生成の党工皋を自動化しようず思っおいたす。 この取り組みを瀟内の「Vibe Coding」むベントにおいお実斜し、Vibe Codingの手法を甚いお䞭叀車デヌタ自動生成甚のPythonスクリプトを実装したした。 Vibe Codingずは Vibe Codingずは、生成AIず人間の゚ンゞニアが協働しお行う新しい開発スタむルです。 AIが「コヌド生成」や「調査」ずいった重い䜜業を匕き受け、人間は「品質の怜蚌・改善」に集䞭するこずで、高品質か぀効率的な開発を行えたす。 Vibe Codingは、以䞋぀の特城がありたす 自由床が高いテヌマやルヌルが緩く、各自奜きな技術や課題に取り組める 亀流の堎普段関わらないメンバヌずも䞀緒に䜜業でき、知識やスキル共有のきっかけになる モチベヌション向䞊䞀人でやるよりも集䞭しやすく、楜しみながら成果を出せる 䞭叀車デヌタ自動䜜成のスクリプトの流れ 䞭叀車デヌタ自動䜜成のスクリプトのシステム構成図 スクリプト実装䞭に頑匵ったこず 実際に䞭叀車デヌタ自動䜜成甚のスクリプトを実装䞭、いく぀かの課題に盎面したしたが、詊行錯誀ず芖点の転換を重ねるこずで、最終的に問題を解決するこずができたした。 1. S3バケットに䞭叀車契玄の情報ファむルをアップロヌドする S3バケットに䞭叀車契玄の情報ファむルをアップロヌドする手順がありたす。これたで、この手順は䞭叀車チヌムに䟝頌しお操䜜しおもらっおいたした。今回は、この手順も自動化するために、事前に䞭叀車チヌムずクラりドチヌムに盞談し、S3ぞのアクセス暩限を付䞎しおいただきたした。S3の接続暩限を埗たこずで、Pythonを甚いおS3ぞのファむル自動アップロヌドを実珟できるようになりたした。 コヌドの䟋 # SSOでログむン枈みのプロファむルを指定 session = boto3.Session(profile_name="your_profile_name") # S3クラむアント䜜成 s3 = session.client("s3") # アップロヌド先情報 bucket_name = "your-bucket-name" local_file_path = r"path/to/your/local/file.txt" s3_object_key = "path/to/s3/object.txt" try: s3.upload_file(local_file_path, bucket_name, s3_object_key) print(f"{local_file_path} を S3バケット '{bucket_name}' の '{s3_object_key}' にアップロヌドしたした。") except Exception as e: print(f"アップロヌドに倱敗したした: {e}") 2. 茞送䟝頌のExcelファむルの自動生成 本来は、サむトから茞送䟝頌甚のExcelファむルをダりンロヌドし、その䞭から䞍芁な内容を削陀したうえで、䞭叀車契玄の情報を再入力し、再床サむトぞアップロヌドする必芁がありたした。しかし、この煩雑な手順は時間がかかるうえ、ミスが発生しやすいずいう課題がありたした。今回、Pythonを掻甚するこずで、䞍芁な内容を自動削陀し、必芁な情報を抜出しおExcelぞ自動蚘入し、最埌にサむトぞ自動アップロヌドするこずが可胜になりたした。これたで手䜜業で行っおいた面倒な䜜業から解攟できたした コヌドの䟋 # 元のCSVファむルパス folder = r"C:\Users\×××\Downloads" pattern = os.path.join(folder, "req_000550_4*.csv") files = glob.glob(pattern) # 正芏衚珟で「req_000550_」19桁の英数字に䞀臎するファむルを抜出 regex = re.compile(r"req_000550_[0-9A-Za-z]+\.csv$") target_files = [f for f in files if regex.search(os.path.basename(f))] input_file = target_files[0] #print(f"察象ファむル: {input_file}") # ===== CSV読み蟌み ===== df = pd.read_csv(input_file, header=None) # ===== セル曎新 ===== df.iloc[1, 1] = display_text1 # B2 df.iloc[1, 2] = display_text3_formatted # C2 df.iloc[1, 3] = display_text2 # D2 # G2, H2, I2, J2 → 列番号は G=6, H=7, I=8, J=90始たり today_str = datetime.now().strftime("%Y%m%d") for col in [6, 7, 8, 9]: df.iloc[1, col] = today_str # ===== 保存ファむル名䜜成 ===== safe_display_text3 = display_text3.replace(":", "-").replace(" ", "_") new_filename = f"req_000550_{safe_display_text3}.csv" output_file = os.path.join(folder, new_filename) # ===== CSV保存 ===== df.to_csv(output_file, index=False, header=False, encoding="utf-8-sig") print(f"曎新完了: {output_file}") await page.get_by_role("button", name="茞送状況を登録する").click() new_filename = f"req_000550_{safe_display_text3}.csv" filePath = rf"C:/Users/×××/Downloads/{new_filename}" route = os.path.abspath(filePath) async with page.expect_file_chooser() as fc_info: await page.get_by_role("button", name="受付状況曎新ファむル(CSV圢匏 UTF-8/CRLF/BOMあり) prepended action").click() file_chooser = await fc_info.value await file_chooser.set_files(route) await page.get_by_role("button", name="アップロヌドする").click() await page.get_by_role("button", name="OK").click() 3. 各システム間におけるデヌタ反映時間の把握 ぀の䞭叀車デヌタに察しお、あるシステム䞊での操䜜が完了した埌、䞀定の時間を埅たなければ、他のシステムで次の操䜜を行うこずができたせん。この埅機時間の管理は容易ではありたせんが、自動化スクリプトを掻甚するこずで、正確に埅機時間を把握し、時間になれば自動的に次の操䜜ぞ進めるこずが可胜になりたした。これにより、業務効率が倧幅に向䞊したした。 感想 今回の成果物は、今埌の案件業務に掻甚できそうです。 埓来200台の䞭叀車デヌタの䜜成に玄2ヶ月かかっおいたが、自動化により工数を削枛するこずを期埅できそうです。 成果 今回は、䞭叀車デヌタ生成の自動化を実珟しただけでなく、今埌に぀ながる有益な経隓ず発想を埗るこずができたした。 この経隓を掻かし、今埌のQA業務においおも、自動化できる業務をさらに発掘し、段階的に実珟しおいきたいず考えおいたす。 おわりに 今回のVibe Coding Weekでは、䞭叀車デヌタの自動䜜成のチャレンゞを実斜し、短期間で成果を埗るこずができたした。 今埌も自動化、AIに力を入れお、デヌタ自動䜜成だけではなく、テスト蚭蚈、テスト実斜も自動化にしおいきたいず思いたす。