Slide 1

Slide 1 text

変わるモデルと変わらぬ本質 実践知の深掘りと次世代開発アプローチの探求

Slide 2

Slide 2 text

Yuki Hattori Senior Customer Success Architect GitHub Vice President InnerSource Commons Foundation @yuhattor

Slide 3

Slide 3 text

ソフトウェア開発における ⽣成AI活⽤の現在地

Slide 4

Slide 4 text

https://arcprize.org/blog/oai-o3-pub-breakthrough

Slide 5

Slide 5 text

OpenAI’s operator Azure AI Agent Service e2b-dev/awesome-ai-agents AI AGENTS

Slide 6

Slide 6 text

Copilot Edits

Slide 7

Slide 7 text

開発のちょっと先の未来

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

⽣成AI時代に エンジニアに求められる役割と 開発のあり⽅

Slide 10

Slide 10 text

⽅法1 ツールの使い⽅を学ぶ

Slide 11

Slide 11 text

ツールの違いを知る ⾃動補完型 対話型 エージェント型 ⼊⼒ エディタへの⼊⼒ フォームへの⼊⼒ フォームの⼊⼒、ファイルアップロードなど 出⼒内容 コード / コメント コード / コメント / 解説⽂ 編集可能なコードを含む成果物 出⼒形式 コードの補完 コードを含む返信 成果物の出⼒ コードサイズ ⼩規模 (1⾏~20⾏程度) 中規模 (1⾏~数百⾏) ⼤規模 (数百⾏~数千⾏) 明⽰的なプロンプト 0⾏ ~ 数⾏程度 数⾏ ~ 数⼗⾏ ⼤量 応答速度 数百ミリ秒 ~ 数秒 数秒 ~ 数⼗秒 数⼗秒 ~ ツールのフォーカス 応答速度、開発時の集中⼒ 精度、プロンプト構築補助 ソリューションとしての完成度 類似体験 ペアプログラミング モブプログラミング Sack や Teams での技術質問 軽量なプルリクエスト受け取り ローコードツールの利⽤ テンプレートエンジンの利⽤ ツール例 GitHub Copilot (Completion) ChatGPT GitHub Copilot Chat Copilot Edits / Agent Mode Copilot Workspace

Slide 12

Slide 12 text

ツール / 機能は陳腐化する あったらいいな あって普通 意識すらしない 抽象化され、取り込まれる

Slide 13

Slide 13 text

「汎⽤」が「専⾨」に勝つ領域が存在する ⾮⾃律型の エディター機能 ⾃律型 専⾨エージェント ⾃律型 汎⽤エージェント

Slide 14

Slide 14 text

⽅法2 プロンプトエンジニアリングを学ぶ

Slide 15

Slide 15 text

プロンプトのReal World Examples 例: Reactのコンポーネント⽣成プロンプト ReactAgentは、Reactアプリケーションの⽣成を ⽀援するオープンソースプロジェクト。 このツールは、⾃然⾔語での指⽰を受け取り、そ れにもとづいてReactコンポーネントを⽣成する。 初期の意欲的な開発⽀援AIツール例として、 開発者コミュニティで⼀定の評価を得ている。 https://github.com/eylonmiz/react-agent

Slide 16

Slide 16 text

プロンプト解説: ReactAgent フロントエンド開発者として⾏動してください。 説明に基づいて、TypeScriptのReact Functional Componentを作成してください。 美しく使いやすいものにしてください。 すべてのユースケースと状態をカバーするようにしてください。 --- 返却例: ${componentExample} --- 指⽰: 動作するコードであることを確認し、私が何かを変更したり実装したりすることを想定しないでください。 プロジェクトにTypeScriptのReactセットアップがあることを前提としてください。 外部ライブラリは使⽤せず、内部ライブラリの@react-agent/shadcn-uiとグラフ⽤のrechartsのみを使⽤してください。 --- 返却タイプ: Reactコンポーネントを返却し、TypeScript で記述し、Tailwind CSS を使⽤します。 tsx/typescript Markdown ```tsx <あなたのコードをここに> ``` 内にコードを返却してください。 https://github.com/eylonmiz/react-agent

Slide 17

Slide 17 text

プロンプトエンジニアリング プロンプトエンジニアリングは「作⽂部分」が注⽬されがちだが、 実際の広範はかなり広範である 出力の評価 LLM の特性 に則した実装 コンテキスト 取得戦略 UXの組立て プロンプトの 書き方

Slide 18

Slide 18 text

⽇々のプログラミングの場合は プロンプトエンジニアリングのテクニックはあまり重要ではない タスクの多様性と⼀回性を考えると、 完璧なプロンプトを作る必要はありません。 むしろ、即興で使い捨てのプロンプトを⽣み出 し、AIとの対話を通じて出⼒を調整する能⼒ が重視されます。 タスクの本質をすばやく⾒抜 き、⾃らの知⾒をAIに的確に伝えることが、創 造的な作業を効率的に進める鍵となります。

Slide 19

Slide 19 text

論点:AIの出⼒は信頼がおけない AI は出⼒において • 嘘をつく • 命令を無視する • ⽂脈をすっとばす AIモデルの精度によって異なりますがGPT-4の 場合、2,000トークンを超えると精度が低下す る可能性がある。(2024年時点) https://arxiv.org/pdf/2402.14848

Slide 20

Slide 20 text

import { useState, useRef, useEffect } from 'react' import { Box, VStack, Input, Button, Container, Text, Flex, Avatar, Spinner, useToast, IconButton, Switch, FormControl, FormLabel, useColorMode, useColorModeValue, } from '@chakra-ui/react' import { FaVolumeUp, FaMicrophone, FaStop, FaSun, FaMoon } from 'react-icons/fa' import AdvisorAvatar from './components/AdvisorAvatar' function App() { const { colorMode, toggleColorMode } = useColorMode(); const bg = useColorModeValue('gray.50', 'gray.900'); const containerBg = useColorModeValue('white', 'gray.800'); const messageBg = useColorModeValue('gray.100', 'gray.700'); const inputBg = useColorModeValue('white', 'gray.700'); const borderColor = useColorModeValue('gray.200', 'gray.600'); const textColor = useColorModeValue('black', 'white'); const initialMessage = { たの旅行プランをお手伝いする旅行アドバイザーです。国内外の旅行について、予算や期間、行きたい場所など、あなたの希望に合わせてアドバイスさせていただきます。気になることを話しかけてください。音声でのやり取りも可能です。", sender: 'ai' }; const [messages, setMessages] = useState([initialMessage]); const [inputMessage, setInputMessage] = useState('') const [isRecording, setIsRecording] = useState(false) const [recorder, setRecorder] = useState(null) const [advisorState, setAdvisorState] = useState('idle') const [autoContinue, setAutoContinue] = useState(false) const toast = useToast() const audioRef = useRef(null) const messagesEndRef = useRef(null) // アドバイザーの状態管理を簡略化 useEffect(() => { const lastMessage = messages[messages.length -1]; if (lastMessage?.sender === 'ai') { setAdvisorState('idle'); } }, [messages]); const scrollToBottom = () => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }; // メッセージが追加されたときに自動スクロール useEffect(() => { scrollToBottom(); }, [messages]); const formatConversationHistory = (messages) => { return messages .map(msg => `${msg.sender === 'user' ? 'クライアント' : 'エージェント'}: ${msg.text}`) .join('\n'); } const playAudio = (base64Audio) => { if (!base64Audio) return; setAdvisorState('talking'); const audio = new Audio(`data:audio/mp3;base64,${base64Audio}`); audio.addEventListener('ended', () => { setAdvisorState('idle'); // アドバイザーの発言が終わったら自動的に録音を開始 if (autoContinue) { startRecording(); } }); audio.play().catch(error => { console.error('Error playing audio:', error); setAdvisorState('idle'); toast({ title: 'Error', description: '音声の再生に失敗しました', status: 'error', duration: 3000, isClosable: true, }); }); } const startRecording = async () => { // すでに録音中の場合は開始しない if (isRecording) return; try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const mediaRecorder = new MediaRecorder(stream); const audioChunks = []; mediaRecorder.addEventListener("dataavailable", event => { audioChunks.push(event.data); }); mediaRecorder.addEventListener("stop", async () => { const audioBlob = new Blob(audioChunks, { type: 'audio/mp3' }); await handleAudioUpload(audioBlob); }); mediaRecorder.start(); setRecorder(mediaRecorder); setIsRecording(true); toast({ title: '録音中', description: '話し終わったら停止ボタンを押してください', status: 'info', duration: null, isClosable: true, }); } catch (error) { console.error('Error starting recording:', error); toast({ title: 'Error', description: '録音の開始に失敗しました', status: 'error', duration: 3000, isClosable: true, }); } }; const stopRecording = () => { if (recorder && recorder.state === "recording") { recorder.stop(); recorder.stream.getTracks().forEach(track => track.stop()); setIsRecording(false); toast.closeAll(); // Close the recording toast } }; const handleAudioUpload = async (audioBlob) => { try { const formData = new FormData(); formData.append('audio', audioBlob); const response = await fetch('http://localhost:8000/api/speech-to-text', { method: 'POST', body: formData, }); if (!response.ok) { throw new Error('Failed to transcribe audio'); } const data = await response.json(); if (data.text.trim()) { // 音声認識結果をメッセージとして追加 const userMessage = { text: data.text, sender: 'user' }; const updatedMessages = [...messages, userMessage]; setMessages(updatedMessages); try { // バックエンドにメッセージを送信 const response = await fetch('http://localhost:8000/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message 無関⼼の⾕ (The Valley of Meh) 無関心の谷 AIは最初と最後に関⼼がある傾向をしめし、 ⾕に落ちた中盤の情報は無視する傾向がある AIが関⼼を⽰す領域 AIが無関⼼な領域

Slide 21

Slide 21 text

論点:⼈間のレビュー能⼒も信頼がおけない 適切なペースでのコードレビュー 1時間あたり500⾏以上のペースでレビューを⾏うと、 ⽋陥の発⾒率が⼤幅に低下します。 適量のコードを、ゆっくりとしたペースで、限られた時間 内でレビューすることが最も効果的です。 ⼀度に少量のコードレビュー ⼀度にレビューする量が400⾏を超えると、⽋陥を ⾒つける能⼒が低下してしまいます。 200〜400 ⾏のコードを60〜90分かけてレビューすることで、 70〜90%の⽋陥を発⾒できます https://smartbear.com/learn/code-review/best-practices-for-peer-code-review/

Slide 22

Slide 22 text

⽅法3 AI との協働⼒を⾝につける

Slide 23

Slide 23 text

AIエージェント時代のコーディング 2025年版

Slide 24

Slide 24 text

エージェント時代になにか変わるのか?

Slide 25

Slide 25 text

出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨ ⼩さなコードチャンクによる段階的作業 AIによる作業単位の最適化 ⼤きな機能を⼩さな部分に分けて実装する。 使い捨てのコード、実験的なコードなど、設計 レベルでクラスを分割しないようなケースでも、 作業単位を⼩さくするように⼼がけることで、 AIとの協働を効率化する。

Slide 26

Slide 26 text

関心の分離によるコード最適化 コードを適切に分割し、AIに与える情報を 最適化する。 クラスを関⼼ごとに分割し、シンプルな構造 にすることで、⽣成されるコードの品質向上 を図る。 AIによる作業単位の最適化 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨

Slide 27

Slide 27 text

AIとの協働を意識した命名 コードのAI可読性向上 変数や関数に具体的で説明的な名前を採 ⽤する。 適切な命名により、AIが提案するコードの品 質を向上させ、⼈間の開発者とAIの両⽅が 理解しやすいコードを作る。 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨

Slide 28

Slide 28 text

スタイルガイドの明⽰的提供とカスタマイズ AIと協働する際のコーディングスタイル AIによるコード⽣成時に標準的なスタイル ガイドに従うよう指⽰する。 標準的なスタイルガイドをベースに、必要に 応じて最低限のカスタム規約セットを作成 する。 AIへのコーディング時の規約伝達を最⼩限 に抑え、効率的な連携を実現する。 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨

Slide 29

Slide 29 text

標準化されたコード内ドキュメント 付加情報の提供によりAIの理解を助ける 標準的なコメントプラクティス に従ってドキュメントを書く。 ⾔語ごとのドキュメント⽣成 の仕組みを活⽤し、AIとのコ ラボレーションを円滑にする。 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨ ⾔語 ⽅式 概要 Python Docstring PEP 257に準拠して詳細なコメ ントを記述し、ドキュメント化 TypeScript JSDoc TypeScriptの型情報とともに、 JSDocを使⽤してドキュメント化 Java Javadoc Javaのクラスやメソッドに対して コメントを記述し、ドキュメント化 C# XML ドキュメント XML形式でドキュメントを記述 し、ドキュメント化

Slide 30

Slide 30 text

AIに触れさせないコードの分離 AIに適したコードアーキテクチャ 重要な計算ロジックを独⽴させ、AIに よるコード変更から保護する。 コードの保守性と可読性が向上し、リフ ァクタリング時のリスクを軽減する。 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨

Slide 31

Slide 31 text

将来の拡張を考慮したコード設計 AIに適したコードアーキテクチャ 既存コードを改変せずに新しいコードを追 加できるよう設計する。 コードの保守性や拡張性が向上し、AIに よる開発スピードを妨げない。 (OCP原則) 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨

Slide 32

Slide 32 text

作業中に⼈間がコントロールする 先にクラスや関数のグランドデザインをして、ガードレールを作る = どの作業でも「いかにコントロールするか=制限するのか」が重要 補完 Realtime チャット Single Turn エージェント Multiple Turn AI時代はガードレール設計が重要 作業範囲を狭く・品質重視 = 作業範囲が広くなりすぎるため細かく確認/迅速な修正不可 コンテキスト 作業範囲 アーキ テクチャ AIが探しやすいよう作っておく = ⼈間のコントロールに限界 作業範囲を狭く・素早さ優先 =作業可能範囲が狭くプロンプトにも限界/迅速な修正可

Slide 33

Slide 33 text

⽅法4 チームとして協働⼒を備える

Slide 34

Slide 34 text

先進事例 ゴールドマン・サックスのAIプラットフォーム 「GS AI Platform」は、全ての独⾃AI技術を中央 集約化し、内部での利⽤を制限する形で運⽤さ れている。 企業のデータを⽤いてファインチューニングされた専 ⽤モデルも利⽤。 出典: “Goldman Sachs Deploys Its First Generative AI Tool Across the Firm” - Wall Street Journal 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨

Slide 35

Slide 35 text

健全なリポジトリを組織として育てる

Slide 36

Slide 36 text

⽣成AI時代にもコードは必要か?

Slide 37

Slide 37 text

品質が保証されたコードは⼤量⽣産できない 論点1 品質が保証されたコードはAIを使って⼤量⽣産できない = ⼈間がレビュー不可能 • ⼈間の関与と責任がボトルネックとして残る • 検証済コードを、⼈間およびAIが「読む」「編集する」「使う」ことが増える • ⼈間は、AIと⼀緒に作った適切なコードをメンテナンスし続ける(AIと⼀緒に) 検証済コードをブラックボックス化し、AIと⼈間の両⽅の負担を減らす必要がある。 ⼈間はAIによる⾞輪の再発明を抑⽌する必要がある。

Slide 38

Slide 38 text

AI時代には「AIと協働が容易なコード」が求められる 論点2 コードが記述的かつ ⽂脈が明確で、 初⾒でも理解しやすい 継続的メンテナンスが されており、常に使⽤ 可能な状態である ⽐較的メジャーな バージョンや技術スタック で書かれている オープンソースのコードの特徴と⼀致 = オープンソースの⽂化を根付かせる必要がある

Slide 39

Slide 39 text

コードの価値のシフト 論点3 今後はAIが簡単に⽣み出せないコードにさらなる価値が宿る • ⾼品質なレビュー済みコードが必要な領域 • メンテナンスコストが⾼い領域、失敗時の影響が⼤きい領域 • AIがインターネットから学んでいないプロプライエタリ領域 企業としてこうした価値を⾒極めていく必要がある。

Slide 40

Slide 40 text

インナーソースの原則 AI時代の競争優位性を⾼めるための開発組織戦略

Slide 41

Slide 41 text

インナーソースの運⽤ AI時代の競争優位性を⾼めるための開発組織戦略 インナーソースは単なる「社内公開すること」ではな ありません。 オープンソースのような貢献と共有の⽂化を組織 内に作り出すことにあります。 インナーソースの導⼊とは、この⽂化を醸成してい く旅なのです。 https://patterns.innersourcecommons.org/v/ja

Slide 42

Slide 42 text

組織内コード共有のルール化 AI時代の競争優位性を⾼めるための開発組織戦略 AIによるコードの活⽤には、ソースコードの⾃由 な利⽤が前提となります。 その「⾃由な利⽤の範囲」は、組織全体で はなく、特定の部⾨やプロジェクトかもしれま せんが、少なくともその範囲を明確にすること が⼤切です。 また、フリーソフトウェアの4つの⾃由である「使 ⽤する⾃由」「変更する⾃由」「共有する⾃ 由」「変更したソフトウェアを再配布する⾃ 由」を社内に限定して適⽤できるようにライセ ンスに統合することも考えられます。

Slide 43

Slide 43 text

メンテナーの明確化 AI時代の競争優位性を⾼めるための開発組織戦略 社内のリポジトリ管理者を明確にするには 「トラステッドコミッター」という概念が有効。 ⼀般的なメンテナーやコミッターの概念に加え、以下のよ うな社内事情を考慮している点が特徴。 • 組織内のチーム間の貢献を認識するための仕組みや ⾔語を提供する。 • ビジネスの優先順位の変化に対応するため、メンテナ ーのフォーカスのずれを考慮する。 • 従業員の評価に組み込めるよう、公式な役割として 定義する。 • 従業員でなくなる等による退任プロセスを考慮する。 • 組織内での公式な認定プロセスを設定する。

Slide 44

Slide 44 text

AIエージェント時代 本来の “エンジニア” の役割や “開発プロセス” の⼤枠は変わらない 今まで通り良いコードを書き、育て、AIと協働できるようにする