TECH PLAY

Scratch

イベント

マガジン

該当するコンテンツが見つかりませんでした

技術ブログ

はじめに この記事は New Relic Advent Calendar 2025 の24日目の記事です。 こんにちは、SREチームの おさない です。本記事では 先日発表 されたNew Relic MCPサーバーをSlackから利用できるようにする方法について紹介します。 MCPサーバー自体はClaudeなどの対話型AIやCodex, Kiroなどのコーディングエージェントなど、さまざまなインターフェースで利用することができますが、Slackというインターフェースで使えるようにすることで、New Relicのデータ利活用の幅をさらに広げられると感じています。 構成図 今回は以下のような構成でSlackからNew Relic MCPを利用します。 今回作成する構成図 SlackでBotにメンションして質問することで、回答に必要な情報をNew Relic MCPを使って取得してスレッドに返信してくれます。 構築手順 :::message 本記事ではSlackからNew Relicのデータにアクセスできるようにするために最小限の内容を紹介しています。以下のような要素については省略していますので、必要に応じて対応してください。 システムプロンプトのチューニング New Relicのアカウントが複数ある場合、どのアカウントから情報を探しますか?といった返答になりがちなので、システムプロンプトなどで「利用なアカウントから順番に調査してください。」といった文言を入れると動くようになりました。 セキュリティ面の対策 今回紹介する構成はユーザーのインプットをそのまま伝えているため、入力・出力内容のガードレールを設けることをオススメします。 また、IAM Roleの権限も必要最小限の設定にすることをオススメします。 会話履歴の保持 今回の構成では会話履歴を保持しておらず、単発でのやり取りになります。 ::: New Relic APIキーの発行 New Relicの API Keys のページに遷移して、 Create a key ボタンを押下します。 Key Typeは User を選択して作成し、発行されたAPIキーを控えておきます。 Slack Appの作成と設定 - その1 まずはSlack Appを作成します。 Slack Appの作成方法についてはさまざまな記事があるため詳細な説明は省きますが、 こちら から From scratch でSlack Appを作成してください。 作成したら OAuth & Permissions のページに遷移し、Bot Token Scopesに chat:write の権限を追加します。 そして Install App から対象のSlackワークスペースにインストールし、発行された Bot User OAuth Token を控えておきます。 アプリケーションの構築 今回は AWS SAM と Strands Agents を使って構築します。私が構築した際のSAM CLIのバージョンは1.149.0でした。 以下にtemplate.yamlとそれぞれのLambda関数のコード、requirements.txtを記載します。 :::details template.yaml AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Globals: Function: Timeout: 120 Resources: SlackEventHandlerFunction: Type: AWS::Serverless::Function Properties: FunctionName: slack-event-handler-function CodeUri: src/ Handler: slack_event_handler.lambda_handler Runtime: python3.14 Role: !GetAtt SlackEventHandlerFunctionRole.Arn SnapStart: ApplyOn: PublishedVersions AutoPublishAlias: SnapStart Architectures: - x86_64 Events: NewRelicBot: Type: Api Properties: Path: /event Method: post Environment: Variables: SQS_QUEUE_URL: !GetAtt SlackMessageSQS.QueueUrl SlackEventHandlerFunctionPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: !Ref SlackEventHandlerFunction Principal: apigateway.amazonaws.com SlackEventHandlerFunctionRole: Type: AWS::IAM::Role Properties: RoleName: slack-event-handler-function-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AmazonSQSFullAccess SlackAIExecutorFunction: Type: AWS::Serverless::Function Properties: FunctionName: slack-ai-executor-function CodeUri: src/ Handler: slack_ai_executor.lambda_handler Runtime: python3.14 MemorySize: 256 Role: !GetAtt SlackAIExecutorFunctionRole.Arn Architectures: - x86_64 Events: SlackMessageSQS: Type: SQS Properties: Queue: !GetAtt SlackMessageSQS.Arn BatchSize: 1 Enabled: true Environment: Variables: NEW_RELIC_API_KEY: '' # 発行したNew Relic APIキーを設定 SLACK_BOT_TOKEN: '' # 発行したSlack Bot User OAuth Tokenを設定 SlackAIExecutorFunctionRole: Type: AWS::IAM::Role Properties: RoleName: slack-ai-executor-function-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole - arn:aws:iam::aws:policy/AmazonBedrockFullAccess SlackMessageSQS: Type: AWS::SQS::Queue Properties: QueueName: slack-message-sqs.fifo FifoQueue: true VisibilityTimeout: 180 MessageRetentionPeriod: 600 ContentBasedDeduplication: true DeduplicationScope: messageGroup RedrivePolicy: deadLetterTargetArn: !GetAtt SlackMessageDLQ.Arn maxReceiveCount: 2 SlackMessageDLQ: Type: AWS::SQS::Queue Properties: QueueName: slack-message-dlq.fifo FifoQueue: true VisibilityTimeout: 180 MessageRetentionPeriod: 604800 ※ NEW_RELIC_API_KEY, SLACK_BOT_TOKENは必要に応じてパラメータストアから取得するなどの方法で設定してください。 ::: :::details slack_event_handler.py import json import boto3 import hashlib import os sqs = boto3.client('sqs') queue_url = os.environ.get('SQS_QUEUE_URL') def lambda_handler(event, context): body = json.loads(event['body']) if body.get('challenge') is not None: challenge = body['challenge'] return response('200', challenge) if body['event'].get('edited') is not None: return response('200', 'edited event ignored') if body['event']['type'] == 'app_mention': ts = body['event']['ts'] channel = body['event']['channel'] thread_ts = body['event'].get('thread_ts') text = body['event'].get('text') if text is None: return response('200', 'no text field') payload = { 'text': text, 'channel': channel, 'ts': thread_ts if thread_ts is not None else ts, } sqs.send_message( QueueUrl=queue_url, MessageBody=json.dumps(payload), MessageGroupId=channel, MessageDeduplicationId=hashlib.md5(text.encode()).hexdigest() ) return response('200', 'ok') def response(status_code, body): return { 'statusCode': status_code, 'body': body, 'headers': { 'Content-Type': 'text/plain', }, } 多重起動を防ぐために、同じ文言を送信した場合はSQSの重複排除機能によりメッセージが破棄されるようにしています textには <@U12345678> のようにSlack AppのメンバーIDが含まれるため、SQSにメッセージを送信する前に必要に応じてトリミング処理を追加してください。 ::: :::details slack_ai_executor.py import json import os from contextlib import asynccontextmanager from mcp.client.streamable_http import streamable_http_client, create_mcp_http_client from strands.tools.mcp.mcp_client import MCPClient from strands import Agent from strands.models import BedrockModel from slack_sdk import WebClient SYSTEM_PROMPT = """ あなたはNew Relicのデータを駆使して開発者をサポートする優秀なエンジニアです。 """ @asynccontextmanager async def _nr_transport(): async with create_mcp_http_client( headers={ "api-key": os.environ.get('NEW_RELIC_API_KEY'), "include-tags": "discovery,alerting,data-access,incident-response,performance-analytics,advanced-analysis", } ) as http_client: async with streamable_http_client( url="https://mcp.newrelic.com/mcp/", http_client=http_client, terminate_on_close=True, ) as streams: yield streams nr_mcp_client = MCPClient(_nr_transport) slack_client = WebClient(token=os.environ.get('SLACK_BOT_TOKEN')) model_id = "jp.anthropic.claude-sonnet-4-5-20250929-v1:0" def lambda_handler(event, context): body = json.loads(event['Records'][0]['body']) text = body['text'] channel = body['channel'] ts = body['ts'] with nr_mcp_client: tools = nr_mcp_client.list_tools_sync() model = BedrockModel(model_id=model_id, region_name='ap-northeast-1', temperature=0) agent = Agent(system_prompt=SYSTEM_PROMPT, tools=tools, model=model) response = agent(text) post_response = slack_client.chat_postMessage(channel=channel, thread_ts=ts, text=str(response)) if post_response['ok']: return True else: return False ::: :::details requirements.txt annotated-types==0.7.0 anyio==4.12.0 attrs==25.4.0 boto3==1.42.13 botocore==1.42.13 certifi==2025.11.12 cffi==2.0.0 click==8.3.1 cryptography==46.0.3 docstring_parser==0.17.0 h11==0.16.0 httpcore==1.0.9 httpx==0.28.1 httpx-sse==0.4.3 idna==3.11 importlib_metadata==8.7.0 jmespath==1.0.1 jsonschema==4.25.1 jsonschema-specifications==2025.9.1 mcp==1.24.0 opentelemetry-api==1.39.1 opentelemetry-instrumentation==0.60b1 opentelemetry-instrumentation-threading==0.60b1 opentelemetry-sdk==1.39.1 opentelemetry-semantic-conventions==0.60b1 packaging==25.0 pycparser==2.23 pydantic==2.12.5 pydantic-settings==2.12.0 pydantic_core==2.41.5 PyJWT==2.10.1 python-dateutil==2.9.0.post0 python-dotenv==1.2.1 python-multipart==0.0.21 referencing==0.37.0 rpds-py==0.30.0 s3transfer==0.16.0 six==1.17.0 slack_sdk==3.39.0 sse-starlette==3.0.4 starlette==0.50.0 strands-agents==1.20.0 typing-inspection==0.4.2 typing_extensions==4.15.0 urllib3==2.6.2 uvicorn==0.38.0 watchdog==6.0.0 wrapt==1.17.3 zipp==3.23.0 ※仮想環境でslack_sdkとstrands-agentsをインストールしてpip freezeしたもの ::: この内容でsam buildおよびsam deployを実行してデプロイします。 デプロイしたらAWSコンソールから作成されたAPI Gatewayのステージを確認し、作成したエンドポイントのURLを控えておきます。 例: https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/event Slack Appの設定 - その2 先ほど作成したSlack Appの設定画面に戻り、 Event Subscriptions のページに遷移します。 Enable Events をONにして、Request URLに先ほど控えたAPI GatewayのエンドポイントURLを設定 Verifiedと表示されればOKです Subscribe to bot eventsの Add Bot User Event から app_mention を追加して保存 OAuth & Permissions のBot Token Scopesに app_mentions:read の権限が自動で追加されます ※変更を保存したら、再度Slackワークスペースにインストールしてください 動作確認 以上で構築は完了です! Slackの任意のチャンネルに作成したSlack Appを追加してメンションを飛ばしてみましょう。質問内容にもよりますが、1分程度で返信がくるはずです。 Slackでの動作イメージ :::message レスポンスのフォーマットがSlackのフォーマットに最適化されていないため、場合によっては見づらい表示になる可能性があります。 私は以下のような方法でSlackフォーマット(のよう)に変換してからポストしています。 def convert_to_slack_format(text: str) -> str: # 太字 text = text.replace("**", "*") # 取り消し線 text = text.replace("~~", "~") # 冒頭に - が付いている場合 text = re.sub(r'^([ ]*)-', r'\1•', text) # 改行の後に --- が付いている場合は削除 text = re.sub(r'\n---+\n', '\n', text) # 改行の後に - が付いている場合 text = re.sub(r'(\n[ ]*)-', r'\1•', text) return text ::: MCPの機能は New Relic MCP ツールリファレンス で確認できます。ツールを組み合わせることでさまざまな活用ができそうです。 日頃ダッシュボードで確認している項目をSlack Reminderで定期的にBotにメンションして、要約してもらう アラート発生時のメッセージでBotをメンションに含めることで自動で一次調査させる 特定のセッショントレースIDでのユーザーの行動をまとめてレポートを作成させる おわりに New Relic MCPサーバーは本記事執筆時点ではPublic Previewの段階ですが、十分に実用的なレベルで利用でき、今後のアップデートが非常に楽しみです! また、この仕組みはNew RelicのMCPサーバーに限らず、他のMCPサーバーに対しても応用可能なものになっているので、普段活用しているMCPサーバーを使いやすいインターフェースで使えるようにしてみてはいかがでしょうか?
はじめに Turing CTO室に所属している東京科学大学(Institute of Science Tokyo)の藤井です。 本記事では、OpenAIから2025年8月にリリースされたgpt-ossをNVIDIA NeMoフレームワークにて学習するための方法について解説します。 2025年11月4日時点では、NVIDIA公式からは、LoRA finetunigを行う方法についてのみ解説されており、Long Context継続事前学習(Continual Pre-Training)など本格的な学習を行うにはハードルが多数あります。 本記事では、学習を行うために解決する必要があるすべて
メルカリハロで QA Engineering manageをしている @____rina____ です。 昨年2024年11月に開催された Agile Testing Days とそこで参加したワークショップについて紹介します。 Agile Testing Daysとは何か   Agile Testing Days とは、ドイツのポツダムで毎年開催されているカンファレンスです。参加者層はテスター、アジャイルテスター、QAエンジニア、テストリード、テストオートメーションエンジニアといったQAやテストに関するエンジニアに加え、ディベロッパー、ソフトウェアエンジニア、アジャイルコーチ、スクラムマスター、プロダクトオーナーやチームリードなど様々な方が対象のカンファレンスです。今回参加した日本語話者の参加者は数名だったこと、ヨーロッパの参加者が多かったようで、コミュニケーションは英語でおこないました。 Agile Testing Daysでは、1日のワークショップと3日間のカンファレンスで構成されています。カンファレンスでは、キーノートをはじめ、セッション、パネルディスカッション、ワークショップなどが開催されます。また、セッションの合間にはコーヒーブレイクやランチなどもが提供され、朝のジョギングから夜の音楽イベントまで、丸一日イベントを楽しむための仕掛けがたくさん用意されていました。  カンファレンス会場はアジャイルテストの第一人者とも言える Lisa Crispin に会うことができたり、たくさんの有識者に会えたり、同じ悩みを持ったエンジニアと交流できたりし、とても刺激的なイベントでした。  スピーカーはシニアエンジニアに限らす、はじめて登壇される方のセッションなど、幅広い登壇者のたくさんの発表を聞くことができました。 Getting a grip on exploratory testing with test charters  Ewald WassinkSconewile氏とRob van Sttenbergen氏による、探索的テストのワークショップです。探索的テストのワークショップは国内でも時々見かけるようになりました。  このワークショップはいくつかのテーブルに分かれてグループワークをしました。私のグループは4名で、2名はドイツからの参加で、英語でコミュニケーションをしました。 次にワークショップの流れを紹介します。 ワークショップの流れ 以下のような流れでワークショップをデザインしていました。 講師の自己紹介とワークショップの説明 フリースタイルで探索的テストをする 2で見つけた不具合の紹介 テストチャーターを利用した探索的テスト グループディスカッションと発表 登壇者の考案したフレームワークを利用した探索的テスト グループディスカッションと発表 1. 講師の自己紹介とワークショップの説明 講師2人の自己紹介がありました。海外のキーノートなどは国内でも見る機会がありましたが、自己紹介をしない印象があったので、少し意外でした。彼らのバックボーンなどを知ることができました。 2. フリースタイルでテストを実行する 以下のURLにアクセスして、個人でフリースタイルでテストをしました。 https://www.eviltester.com/page/tools/thepulper/ 題材はWebサイトで、個々に不具合を出していきます。テスト設計はせずに、経験ベースでテストを実行します。 HTMLエンコードが行われていないため、入力された値がそのままHTMLとして表示される不具合 HTMLエンコードをしていないために、入力値とinput formの表示が変わってしまう不具合 日付を入力する欄に大きな数字をいれたためにNumber Format Exceptionが発生してしまった。これを不具合とするかどうかは仕様次第 3. 発見された不具合の共有  参加者全員で、探索的テスト中に発見した不具合について発表しました。私は自身が報告しようとしていた不具合が、既に他の参加者によって報告済みであるか確信が持てませんでした。そこで、念のため隣席の方に不具合の画面を見せながら、「このバグについて報告しようと思っているのですが、既に発表された方はいますか?」と確認しました。すると、その方は私の発表をフォローしてくださり、安心して発表に臨むことができました。 4. 探索的テストとテストチャーターの解説 ここでは、探索的テストとは何か、そしてテストチャーターとは何かについて解説がありました。講師からは、著名なソフトウェアテスト研究者である Cem Kaner 氏の言葉を引用しつつ、「テストチャーターは、テストのゴールを明確にするための計画である」という説明がありました。 以下はテストチャーターの例です。 define your goal; charter template   target     where are you exploring?   resources     what resources do you need ?   information     what kind of information do you want to discover 5. テストチャーターを用いた探索的テスト 隣の席の方とペアになり、先ほどのテスト対象のWebアプリケーションに対して、付箋を使ってテストチャーターを作成しました。ペアワーク後、グループ全体でそれぞれのペアがどのような考えでテスト項目を選び、テストチャーターを作成したかを共有し、議論しました。 6. BRIEFフレームワークの提案 講師から、Elizabath Hendricson氏が提唱するテストチャーターについての説明がありました。私はテストチャーターについて、彼女の著書で知ってはいたものの、改めて説明を受けることで、自身の抱いていた違和感が明確になりました。それは、受け入れ条件(Acceptance Criteria)を書く際、つまりテスト設計時に、情報やテスト観点から記述している点でした。 そして、講師らが提唱する新しいフレームワーク「BRIEF」の説明がありました。 BRIEFは、Behavior(行動)、Result(結果)、Impediments(障害)、Expectation(期待)、Feeling(感情) の頭文字を取ったものです。このフレームワークを用いることで、振る舞いを軸としたテストチャーターを作成することができます。最後に、このBRIEFフレームワークを使ってペアワークを行い、その後、他のグループと入れ替わってディスカッションを行いました。 ペアワークで使った付箋 このワークショップで特に素晴らしいと感じたのは、講師自身が考案したフレームワーク「BRIEF」を活用していた点です。探索的テストのワークショップでは、手を動かす演習や参加者同士の意見交換、テストチャーターの作成などはよく行われます。しかし、今回のように新しいチャーターのフレームワークを実際に試す機会は初めてで、非常に有意義でした。個人的にも、BRIEFのフレームワークは普段私がテストを考える際の思考回路に近く、とてもしっくりきました。 Journey From Manual to Automation Pythonic Tester 続いて、Mateusz Adamczak氏とMichal Pilarski氏による、テスト自動化の初学者を対象としたワークショップについてご紹介します。このワークショップはハンズオン形式で行われ、参加者は自身のPCを使って実際に自動テストを作成しました。 ワークショップの流れ ワークショップでは以下のような流れでワークショップをデザインしていました。 必要なツールとリポジトリのダウンロード Scrachを使ってアニメの作成 Pythonのコードにコンバートする テストコードの作成 グループディスカッションと発表 登壇者の考案したフレームワークを利用した探索的テスト グループディスカッションと発表 こちらもひとつずつ紹介します。 1. 必要なツールとリポジトリのダウンロード GitLabのリポジトリ、Python、JetBrainsをダウンロードします。 GitLab –  GitLab.com –  Files · ATD_workshop_manual2auto · Michal Pilarski / python_kids · GitLab Python.org –  Python.org JetBrains –  PyCharm –  https://www.jetbrains.com/pycharm/download/download-thanks.html?platform=macM1&code=PCC 2.Scratchを使ったアニメーション動画作成 Scratchを使ってアニメーション動画を作成しました。最初に講師が画面共有しながら作り方を説明し、参加者はそれに倣って作業を進めました。Scratchは、子供向けのプログラミング学習ツールとして日本でも人気があり、直感的な操作でアニメーションを作成できます。そのため、プログラミング初学者でも問題なく取り組むことができました。講師の指示に従い、キャラクターを前後に動かしたり、音を鳴らしたりといった簡単な動作を作成しました。 3. Pythonコードへの変換 Scratchで作成したアニメーションが完成したので、次はそれをPythonのコードに変換します 変換に必要なコードは事前に用意されていました。 まずターミナルで python -V を実行してPythonのバージョンを確認し、次に pip install -r requirements.txt を実行して必要なライブラリをインストールします。その後、Scratchで作成した kitty.sb3 ファイルを変換することで、Pythonのコードが生成されました。 講師から基本的なPythonコードの説明があり、その後は参加者自身でコードの実装を行いました。私の作成したアニメーションには背景がなかったため、生成されたコードの6行目をコメントアウトする必要がありました。 4. テストコードの作成 いよいよテストコードの作成です。先ほどコンバートしたコードに対してテストコードを実装します。  講師が簡単なテストのサンプルコードを紹介してくれました。このサンプルコードは、Scratchで作成したアニメーションの動きをテストするもので、pytestライブラリを使用していました。例えば、キャラクターが指定された位置に移動することを検証するテストや、特定の音が鳴ることを検証するテストなどがありました。講師がコードを画面共有しながら説明してくれたので、私たちも自身のPCで同じようにコードを書き写しました。エラーが発生した箇所は、エラーメッセージを読みながら修正したり、講師に質問したりして解決しました。その後、ターミナルでpytestコマンドを実行してテストを実行し、テストが成功することを確認しました。詳細なテストコードについては、ぜひGitLabのリポジトリ([GitLabのリポジトリURL])にアクセスして確認してください。ワークショップで使用したすべてのテストコードや関連資料が公開されていますので、テストコードの全体像を把握したり、実際にテストを実行したりすることができます。 このワークショップの特筆すべき点は、まず初学者の参加者が実際に動くプログラムを作成できたことです。Scratchを活用することで、参加者が動くプログラムを自ら作れるようにするというアイデアは非常に素晴らしいと感じました。通常の自動テストに関するハンズオンでは、多くの場合、事前に用意されたプログラムに対してテストコードを書くことが一般的です。しかし、今回のワークショップでは、動くものをゼロから自分で作り、そのテストコードまで書くという一連の流れを、数時間という短い時間で体験できる点が素晴らしいと思いました。ワークショップの時間内ですべてのテストコードを実装することはできませんでしたが、参加者全員が何らかの形でテストコードを実装することができました。初学者向けにScratchでアプリ作成を体験させ、それをPythonコードに変換し、自身が作成したプロダクトコードに対してテストコードを実装するというワークショップのデザインは、本当に素晴らしいと感じました。 おわりに 今回の記事では参加した2つのワークショップについてご紹介しました。どちらのワークショップも、短時間で成果を実感できるような工夫が凝らされており、その内容とともに大変勉強になりました。ワークショップのオーナーの方々には、直接お会いして感謝の気持ちをお伝えし、ぜひこの素晴らしいセッションを日本にいるみんなにも広めたいので、サイトのURLなどを公開しても良いか確認させていただきました。  私自身、長年英語に苦手意識があり、ワークショップへの参加は、他の参加者や講師の方々にご迷惑をかけてしまうのではないかという不安がありました。しかし、同じ志を持つ仲間たちと、互いの伝えたい内容を理解しようとする姿勢に触れ、そのうちの一人とは数週間後に私の住む街へ偶然旅行に来るとのことで、食事の約束までできました。また、参加者の中には第二外国語として英語を学んでいる方もいたようで、みんなが真剣に耳を傾けてくれる姿勢が印象的でした。  結果として、私自身も非常に楽しく学習できる時間を過ごすことができました。同じグループになった参加者の方々も、とても親切で助けられました。私は英語が得意ではありませんが、Agile Testing Daysではキーノートをはじめ、数多くのセッションやワークショップ、パネルディスカッションが開催され、登壇者の経験に基づいた発表が多く、共感できる内容が数多くありました。  セッション以外の時間にも食事が提供され、参加者同士が楽しく交流できる場が設けられており、3日間を通して多くの方々と話すことができました。  今年の Agile Testing Daysの参加受付 も始まりました。このブログをきっかけに、読者のみなさまがワークショップを試してみたり、海外のカンファレンスへの参加に挑戦してみようと思っていただけたら、とてもうれしいです。

動画

該当するコンテンツが見つかりませんでした

書籍