Share
Embed
Transcript
44 slides
-
Yuki Hattori Senior Customer Success Architect GitHub Vice President InnerSource
Commons Foundation @yuhattor -
ツールの違いを知る ⾃動補完型 対話型 エージェント型 ⼊⼒ エディタへの⼊⼒ フォームへの⼊⼒ フォームの⼊⼒、ファイルアップロードなど 出⼒内容 コード
/ コメント コード / コメント / 解説⽂ 編集可能なコードを含む成果物 出⼒形式 コードの補完 コードを含む返信 成果物の出⼒ コードサイズ ⼩規模 (1⾏~20⾏程度) 中規模 (1⾏~数百⾏) ⼤規模 (数百⾏~数千⾏) 明⽰的なプロンプト 0⾏ ~ 数⾏程度 数⾏ ~ 数⼗⾏ ⼤量 応答速度 数百ミリ秒 ~ 数秒 数秒 ~ 数⼗秒 数⼗秒 ~ ツールのフォーカス 応答速度、開発時の集中⼒ 精度、プロンプト構築補助 ソリューションとしての完成度 類似体験 ペアプログラミング モブプログラミング Sack や Teams での技術質問 軽量なプルリクエスト受け取り ローコードツールの利⽤ テンプレートエンジンの利⽤ ツール例 GitHub Copilot (Completion) ChatGPT GitHub Copilot Chat Copilot Edits / Agent Mode Copilot Workspace -
プロンプトのReal World Examples 例: Reactのコンポーネント⽣成プロンプト ReactAgentは、Reactアプリケーションの⽣成を ⽀援するオープンソースプロジェクト。 このツールは、⾃然⾔語での指⽰を受け取り、そ れにもとづいてReactコンポーネントを⽣成する。 初期の意欲的な開発⽀援AIツール例として、
開発者コミュニティで⼀定の評価を得ている。 https://github.com/eylonmiz/react-agent -
プロンプト解説: 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 -
論点:AIの出⼒は信頼がおけない AI は出⼒において • 嘘をつく • 命令を無視する • ⽂脈をすっとばす AIモデルの精度によって異なりますがGPT-4の
場合、2,000トークンを超えると精度が低下す る可能性がある。(2024年時点) https://arxiv.org/pdf/2402.14848 -
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が無関⼼な領域 -
論点:⼈間のレビュー能⼒も信頼がおけない 適切なペースでのコードレビュー 1時間あたり500⾏以上のペースでレビューを⾏うと、 ⽋陥の発⾒率が⼤幅に低下します。 適量のコードを、ゆっくりとしたペースで、限られた時間 内でレビューすることが最も効果的です。 ⼀度に少量のコードレビュー ⼀度にレビューする量が400⾏を超えると、⽋陥を ⾒つける能⼒が低下してしまいます。 200〜400
⾏のコードを60〜90分かけてレビューすることで、 70〜90%の⽋陥を発⾒できます https://smartbear.com/learn/code-review/best-practices-for-peer-code-review/ -
標準化されたコード内ドキュメント 付加情報の提供によりAIの理解を助ける 標準的なコメントプラクティス に従ってドキュメントを書く。 ⾔語ごとのドキュメント⽣成 の仕組みを活⽤し、AIとのコ ラボレーションを円滑にする。 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨
⾔語 ⽅式 概要 Python Docstring PEP 257に準拠して詳細なコメ ントを記述し、ドキュメント化 TypeScript JSDoc TypeScriptの型情報とともに、 JSDocを使⽤してドキュメント化 Java Javadoc Javaのクラスやメソッドに対して コメントを記述し、ドキュメント化 C# XML ドキュメント XML形式でドキュメントを記述 し、ドキュメント化 -
作業中に⼈間がコントロールする 先にクラスや関数のグランドデザインをして、ガードレールを作る = どの作業でも「いかにコントロールするか=制限するのか」が重要 補完 Realtime チャット Single Turn エージェント
Multiple Turn AI時代はガードレール設計が重要 作業範囲を狭く・品質重視 = 作業範囲が広くなりすぎるため細かく確認/迅速な修正不可 コンテキスト 作業範囲 アーキ テクチャ AIが探しやすいよう作っておく = ⼈間のコントロールに限界 作業範囲を狭く・素早さ優先 =作業可能範囲が狭くプロンプトにも限界/迅速な修正可 -
先進事例 ゴールドマン・サックスのAIプラットフォーム 「GS AI Platform」は、全ての独⾃AI技術を中央 集約化し、内部での利⽤を制限する形で運⽤さ れている。 企業のデータを⽤いてファインチューニングされた専 ⽤モデルも利⽤。 出典:
“Goldman Sachs Deploys Its First Generative AI Tool Across the Firm” - Wall Street Journal <https://www.wsj.com/articles/goldman-sachs- deploys-its-first-generative-ai-tool-across-the-firm-cd94369b> 出典: コード×AI ーソフトウェア開発者のための⽣成AI実践⼊⾨ -
品質が保証されたコードは⼤量⽣産できない 論点1 品質が保証されたコードはAIを使って⼤量⽣産できない = ⼈間がレビュー不可能 • ⼈間の関与と責任がボトルネックとして残る • 検証済コードを、⼈間およびAIが「読む」「編集する」「使う」ことが増える •
⼈間は、AIと⼀緒に作った適切なコードをメンテナンスし続ける(AIと⼀緒に) 検証済コードをブラックボックス化し、AIと⼈間の両⽅の負担を減らす必要がある。 ⼈間はAIによる⾞輪の再発明を抑⽌する必要がある。 -
AI時代には「AIと協働が容易なコード」が求められる 論点2 コードが記述的かつ ⽂脈が明確で、 初⾒でも理解しやすい 継続的メンテナンスが されており、常に使⽤ 可能な状態である ⽐較的メジャーな バージョンや技術スタック
で書かれている オープンソースのコードの特徴と⼀致 = オープンソースの⽂化を根付かせる必要がある -
組織内コード共有のルール化 AI時代の競争優位性を⾼めるための開発組織戦略 AIによるコードの活⽤には、ソースコードの⾃由 な利⽤が前提となります。 その「⾃由な利⽤の範囲」は、組織全体で はなく、特定の部⾨やプロジェクトかもしれま せんが、少なくともその範囲を明確にすること が⼤切です。 また、フリーソフトウェアの4つの⾃由である「使 ⽤する⾃由」「変更する⾃由」「共有する⾃
由」「変更したソフトウェアを再配布する⾃ 由」を社内に限定して適⽤できるようにライセ ンスに統合することも考えられます。 -
メンテナーの明確化 AI時代の競争優位性を⾼めるための開発組織戦略 社内のリポジトリ管理者を明確にするには 「トラステッドコミッター」という概念が有効。 ⼀般的なメンテナーやコミッターの概念に加え、以下のよ うな社内事情を考慮している点が特徴。 • 組織内のチーム間の貢献を認識するための仕組みや ⾔語を提供する。 •
ビジネスの優先順位の変化に対応するため、メンテナ ーのフォーカスのずれを考慮する。 • 従業員の評価に組み込めるよう、公式な役割として 定義する。 • 従業員でなくなる等による退任プロセスを考慮する。 • 組織内での公式な認定プロセスを設定する。