Podcast - Backyard Hatena
TechTalk - Google Cloud Born Digital Summit
ぽ靴な缶
これは はてなエンジニア Advent Calendar 2025 2 日目の記事です。 年の瀬なので振り返りたくなる季節ですね。 今日はそんな「以前から存在していたけど AI によって新しい価値を見出された技術やツールを語ろう」のコーナーです。 いくぞ!! Server-Sent Events (SSE) まず出世頭として思いつくのは Server-Sent Events でしょう。 Server-sent events - Web API | MDN 今やチャット AI のレスポンスはほとんど SSE で送られて来ています。 SSE は HTTP レスポンスとして、以下のような空行区切りの data: から始まるテキストデータを送る方法です。クライアントサイドではレスポンスの送信終了を待たずに受信したデータを逐次使うことで段階的な表示を行います。 data: Yo data: 俺の名前は data: ぽくつなだぜ # 実際には JSON など構造化したデータを送る SSE 自体はずっと前からあって、2004 年の WHATWG の提案に起源があるようですね1。 自分が SSE を認識したのは、WebSocket & socket.io が流行った後ぐらいだったと思います。 Lingr というチャットサービスは HTTP ベースなんだけど Comet という方法で通信していて...みたいな。流行ったから WebSocket 使ってるだけで、その用途なら SSE のほうが簡単なのでは? みたいな実装も見かけたり。 ChatGPT を初めて触った頃、これどうやって作ってるんだろ? と Developer Tool で眺めて Content-Type: text/event-stream を見た時は、なるほど!! と思ったものです。 EventSource が GET しか使えないのもあり、当時はチャットルーム的なエンドポイントに GET で接続して更新を降らせるイメージでしたが、最近のチャット AI ではユーザ入力の POST に対して AI 生成レスポンスを SSE で返す形なのがちょっと新しい感じですね。昔からやってる人は居たとは思うけども。 Pandoc での Markdown 化 Pandoc は様々なドキュメントを変換できるツール。 AI を使って論文やスライド、電子書籍を読みたい。今やチャット AI 側の対応が充実して直接渡せるようになってきているわけですが、2023 年頃は自前でテキストデータに変換したりベクトルインデックス作ったりしていたわけです。今でもフォーマットによってはやる必要がある。 EPUB を Unstructured を使って変換しようとしたところ依存に含まれている Pandoc と再会。 お前とこんなところで会うとは... 昔 Markdown と Redmine の Textile を変換してくれたよね。はてな記法も2変換しちゃったりね、懐かしいじゃん。ああうん、また今度飯でも行こうよ、みたいな。 Pandoc は珍しい Haskell 製のツールとしても知られていますが、リリースは 2006 年なんですね。フォーマット変換が普遍的なタスクであることを考えてもなかなかすごい。 Google Trends - Pandoc の伸び テキスト化というトピックでは、最近の OCR も勢いがありますね。 DeepSeek-OCR が話題になりましたが olmOCR や Mistral OCR も今年出たモデル。LLM/VLM の発展によって色んなモデルが公開されました。日本語では YomiToku が出たり。ちょうどこの記事も話題になっていました。 tech.layerx.co.jp Markdown 自体も AI で再注目されたフォーマットといえるかもしれません。少し前まではウェブエンジニア向けテキストフォーマットという雰囲気だったけど、今や AI と構造化テキストをやり取りする際の標準的な選択肢になっている感じがありますね。 Marp でスライドを作る Markdown つながりで Marp を久々に使いました。 Marp は Markdown でスライドを作るツール。2016 年頃に話題になって流行りました3。今年勉強会の資料をコーディングエージェントを使いつつ Marp で作ったら内容より「懐かしっ」という反応を頂いて、まあ確かにそうだなと。 最近、Markdown から Google スライドを生成するツール k1LoW/deck も話題になりましたね。LLM の支援を受けられるテキストベースのツールが再注目されている流れがあります。 Markdown から何かを生成する方面では、Mermaid で描かれた図を見る頻度も増えた気がします。AI に描かせるだけでなく、テキストで関係性を表現するために Mermaid 記法を使って AI に入力する事例も見ますね。 アクセシビリティツリー 「情報をどうテキスト化して入力するか」という文脈では、Playwright MCP がブラウザ操作にアクセシビリティツリーを使って成功していたのが印象的でした。 この記事のアクセシビリティツリー(Playwright の ariaSnapshot)を見てみるとこんな感じ - generic [active] [ref=e1]: - iframe [ref=e3]: - generic [ref=f24e3]: # ... - generic [ref=e21]: - generic [ref=e22]: - generic [ref=e24]: - article [ref=e25]: - generic [ref=e26]: - generic [ref=e27]: - link "2025-12-02" [ref=e29] [cursor=pointer]: - /url: https://blog.pokutuna.com/archive/2025/12/02 - time [ref=e30]: 2025-12-02 - heading "AI で再注目された技術やツールたち" [level=1] [ref=e31]: - link "AI で再注目された技術やツールたち" [ref=e32] [cursor=pointer]: - /url: https://blog.pokutuna.com/entry/ai-rediscovered-tech-and-tools - generic [ref=e33]: - paragraph [ref=e34]: - text: これは - link "はてなエンジニア Advent Calendar 2025" [ref=e35] [cursor=pointer]: - /url: https://qiita.com/advent-calendar/2025/hatena - text: 2 日目の記事です。 - paragraph [ref=e36]: - text: 年の瀬なので振り返りたくなる季節ですね。 - text: 今年も AI の話題が非常に多く、コーディングエージェントの普及を始めいろんな変化がありました。新しいモデル、高まる精度、飛び交うビッグマネー、跳ね回る驚き達。そういう景気の良い話はさておき、既存の技術が新しい文脈で再注目されたり、思わぬ用途で広く使われるようになったりすることも起きています。 - paragraph [ref=e37]: 今日はそんな「以前から存在していたけど AI によって新しい価値を見出された技術やツールを語ろう」のコーナーです。 生の HTML は巨大でノイズも多く AI に渡すのは厳しいです。そこで Playwright のテストにおいて、ページ構造の比較に使われていた ariaSnapshot が、ページ構造を伝える手段に転用されています。 従来 Playwright や React Testing Library は、テストを書く際に id や class 属性での参照ではなく、role や label での参照を推奨していて、ユーザがアプリケーションを使う時と近い形でテストを書くように促していて、それが結果的に AI にとっても扱いやすいシリアライズ形式になった、というのが面白いですね。 ブラウザ操作の先駆け browser-use によるインタラクティブ要素のハイライト & 可視化 音声入力 再注目? というと違う気もするけど、自分は今年からだいぶ音声入力を使うようになりました。 コーディングエージェント以前は、補完を活用して書きまくっていたわけだけど、今は AI に指示をする際に主語述語目的語の揃った文章を書くことが増えてきた。複数の入力欄を行ったり来たりしつつ、都度文章を整えるのは地味に手間で、音声入力できるとなかなか便利です。 2022 に OpenAI が Whisper を公開し、その高い精度に驚かされたのも昔の話。ここ1年ぐらいで Whisper を使って文字入力するデスクトップアプリがいくつか出ました。今年の3月ぐらいに Superwhisper や Aqua Voice が話題になって流行ったかな? 自分は VoiceInk を使っています。OSS なのでちょっと改造して使っている、こういう選択肢があるのはいいですね。 その他 自分は使っていないけど Obsidian がドキュメントツールとして再注目されたり、RAG の文脈でナレッジグラフを作って retrieval しようという GraphRAG が話題になって久々に Neo4j の話を聞いたり。 コーディングエージェントを走らせるため sandbox 技術にも注目が集まりました。自分は最近まで知らなかったけど、2016 年ごろの Sierra 頃から非推奨の sandbox-exec を、Codex、Claude Code、Gemini CLI、Cursor 全員が開き直って使ってるというのもウケますね。 まとめ 以上、AI で再注目された技術やツールを紹介しました。 Twitter で教えてください。 これは はてなエンジニア Advent Calendar 2025 2 日目の記事でした。 id:mizdra さんの 普段使いできる保護レイヤー「restricted shell」の紹介 - mizdra's blog でした。 id:todays_mitsui さんの予定です。お楽しみに!! { entries.forEach(entry => { if (entry.isIntersecting) { typeText(); } else { clearTimeout(animationId); } }); }); observer.observe(element); https://en.wikipedia.org/wiki/Server-sent_events↩ https://motemen.hatenablog.com/entry/2017/05/pandoc-hatena↩ https://b.hatena.ne.jp/entry/s/yhatt.github.io/marp/↩
ぽ靴な缶
大規模言語モデル講座 応用編 2025 Autumn - 東京大学松尾・岩澤研究室(松尾研)- Matsuo Lab 2025/11/19(水) AM10:00 まで!!! 社会人枠もあります。自分は前年に参加してとても良かったのでおすすめしています。 各社の LLM API を雰囲気で利用していて、理解が足りてないな、もどかしいなと感じて応募したのですが、そういった Web エンジニアの方々は多くいるのではないでしょうか。 前年の講義スライドは公開されている。 LLM 大規模言語モデル講座2024講義スライド - 東京大学松尾・岩澤研究室(松尾研)- Matsuo Lab あ、応募に名刺が要る気がするな、締切2日前に言われても準備できないかもな、まあいいか 2024 年講義の最終課題コンペで優秀賞を頂きました 自分は去年の講義に参加させて頂いて、一般8位、コントリビューション3位の優秀賞を頂きました。この自慢をする機会を逸し続けていた。 枠が NN になってるのが良い 講義の内容も良かったのだが、特に自分で手を動かす機会としてコンペがあったのは良かったです。 コンペの内容は 事前学習済みモデルを訓練し ELYZA-tasks-100 の改変版に対し高いスコアを出す LLM を開発する 2024年9月以降の日本のテレビ番組内容で各タスクのトピックを置き換えて若干難易度を上げたもの 制約として、 利用可能な事前学習済みモデルは LLM-jp-3 または Gemma2 (自分で事前学習しても良い) L4 GPU 1 枚の環境で 1 時間以内に 100 問に回答 モデルが公開可能であること(データとモデルのライセンス遵守) 予選は自動評価、決勝は参加者による評価 というものでした。 自分は、 gemma-2-9b をベースに継続事前学習 → SFT → DPO したものをメインに使う Gemma がことわざ・慣用句などの日本語文化問題に弱かったので、llm-jp-3-13b を SFT したものをサブモデルに用意 という構成で勝負。 問題文からルーティングする分類器を作るつもりだったけど、これ問題文のバリエーション無いなと思ったので正規表現で済ませたり、締め切り直前に苦手な問題の学習データを自分で作ってみたり pokutuna/tasks-ime-and-kakko-jp、人間の目視評価ってことは TeX 記法や Markdown が丸出しなのは見栄え悪いよな...と思って置換してみたり、意味あることもないことも色々試す機会になって楽しかったです。 最初は GPU 代を払うことにケチケチしていたけど、 社会人にあって学生にないもの、それは金... GPU が使える...安すぎる... RunPod に円を注入することを覚えました。 早く来すぎた 個人的に衝撃を受けたのが表彰式 & 懇親会で、めちゃくちゃ色んな人が来ていたことですね。 高校生から60代、寝たきりの方、仕事で LLM 訓練している人、研究者、医師まで居て、属性が多様すぎる。 たった 1 年前の話なのに AI の話題が色々ありすぎてもう懐かしい。 これは当時のな〜〜んにもわからないところからスタートした際のメモ書き、下から上に書いてある。 2024/11 LLM チューニング日記 - pokutuna ちょうど Twitter で盛り上がっている話題として 松尾研発スタートアップ - 東京大学松尾・岩澤研究室(松尾研)- Matsuo Lab 胡散臭いと思われる理由の1つとして、講座を受講しただけで「松尾研卒です!!」みたいなこと言ってる例はたまにあるよな... 毎年 3000-4000 人が参加していてそういうこともある、自分はその間口の広さによって良い経験をさせてもらえたので、不届き者をシバきつつ今の感じで続いてほしいなと思います。

ぽ靴な缶
を作りました @pokutuna/mcp-chrome-tabs デモ AppleScript を使っている都合上 macOS でのみ動きます。 なぜ作ったか 既に LLM にブラウザを操作させる技術は色々ある。browser-use、playwright-mcp、mcp-chrome などなど。 これらの Tool, MCP は便利だけど、様々なツールが入っていてコンテキストへの圧迫が大きく、Chrome の debugging port を開けたり、普段のユーザディレクトリは使えなかったり、ブリッジとなるブラウザ拡張入れたりなど、まあまあめんどく、普段遣いしたいかというと否である。なのでタスクに応じて MCP サーバーのセットを切り替えて暮らしている。 ただ今開いているページを LLM に読ませたい 普段はブラウザ操作をしたいわけではなく、今見ているページを LLM に読ませたいことがほとんどだなと気づいた。 いまや大抵の AI アプリケーションは URL を取得して読んでくれるし、検索エンジンを使えたり便利になっているものの、様々な煩わしさがある。 URL を貼っても読んでくれず「fetch して」と追加で指示 取得し始めるものの robots.txt に阻まれる "代わりに別のページを検索します" やめてくれ〜 検索したら「これは別の話だな...」「古いの参照してるな...」と実行を停める 認証情報がなく見られない、与えるのもひと手間 長大なページを読んで Prompt too long エラーで死ぬ ただ俺が今見てるページ読んでくれ!! という気持ちで作ったのが @pokutuna/mcp-chrome-tabs です。 機能・特徴 Apple Script 経由でタブのコンテンツを取得する 追加の HTTP リクエスト送らず、ページの内容をそのまま参照 本文部分を取得し Markdown に変換 @mozilla/readability の代替を目指す defuddle を使う ツール 3 つのみ、説明も出力も短めで普段遣いできるように list_tabs: 現在開いているタブの一覧を取得する read_tab_content: 指定したタブの本文部分を Markdown で取得する open_in_new_tab: AI 側からユーザのブラウザで URL を開けるように 実験的に MCP Resources に対応 Claude Code の @ 補完にタブの候補が出ます 単純な MCP サーバーで似たものもいくつかあるけど、意外と満足行くものがなく1作ることにしました。 名前に chrome と入れてしまったけどオプションを指定することで Safari でも動く。 使い方 以下のような感じで MCP サーバーとして追加します: { "mcpServers": { "chrome-tabs": { "command": "npx", "args": ["-y", "@pokutuna/mcp-chrome-tabs@latest"] } } } Claude Code の場合は以下のコマンドで: $ claude mcp add -s user chrome-tabs -- npx -y @pokutuna/mcp-chrome-tabs@latest その後、Chrome のメニューから 表示 > 開発 / 管理 > Apple Events からのJavaScript を許可 AppleScript 経由からの Chrome の操作を許可してください。2 実際の使用例 作ってからほぼ毎日使っています。こんな感じで活用中。 議事録開きながら「決定事項を箇条書きにして」 コーディングエージェントが新しすぎて LLM 側に情報がないような作業するときに、公式ドキュメントやリファレンスを開いておいて「タブ一覧から関連する内容を確認してから作業して」 リポジトリにない設計ドキュメントを開いておいて 「現在のタブの内容から重要なものを CLAUDE.md に反映して」 手で丁寧に渡すなどの代替手段でできることではありますが、いきなり指示して読めるのが便利。 defuddle の本文抽出都合でうまく取れないケースもあり改善したいものの、まあ大抵はうまくいきます。本文テキストを取り出すものなので、具体的には GitHub のコードのページなんかはうまくいかないけど、URL を確認してから gh を使ってくれたり / 使うよう促したり。 MCP Resources プロトコルに対応 Tools だけでなく MCP の Resources プロトコルにも対応してみました。 Claude Code では @file で特定のファイルを参照させることができるけど、その補完候補に Resource を登場させることができます。@cur で tab://current の参照を補完させたり、@{ページタイトルやホスト名の一部} など引っかかるワードで補完候補から選べます @ で補完候補に出て選べる タブ集合の差分を検出してリソースリストの再取得を促す listChanged notification を送る実装もしていますが、まだ Claude Code 側が対応しておらず起動時のタブリストから更新されない。まあそのうち対応されるでしょう... まとめ 使ってみてね おまけ情報: playwright-mcp 公式のブリッジ拡張が来そう リポジトリを見ると見つかる。まだ動きはするけど PoC かな? 再接続ができなかったり親切さゼロだったり。 playwright-chrome-extension - pokutuna Chrome コネクタも似たような仕組みではあるものの、実装がいまいちで本文部分の切り出しがなかったり。↩ Chrome が制限厳しくしたのに横穴開けている感はあるので注意は必要↩

ぽ靴な缶
ブログに書きたいと思いつつ書いてない話の供養です Google Open Source Peer Bonus Award 頂きました Dataform へのコントリビュートで貰った、2023 年末の話... Majestouch Xacro M10SP 良い 自作に手を出したくないが分割キーボードは欲しい、このマクロキーの配置は良くめっちゃ使ってる Google Processional Cloud Security Engineer を取得した 本来は資格延長のためのバウチャーぽかったけど新しいことを知りたかったので、正直使わない知識(US の法規制とか)も多かったけど面白かった はてなインターン 2024 で AI に関する講義をした 時流にあわせて AI の話をする、歴史っぽい話から、ベンチマーク鵜呑みにするなよという話 東京大学松尾・岩澤研「大規模言語モデル2024」の公開講義を受講した 最終課題は受講生同士でバトルするコンペ、3000人?中、一般8位&コントリビューション3位になった、これはちゃんと書きたい Modern App Summit '25 基調講演で話した Google Cloud イベントの基調講演中の 10 分枠で発表した、短いし楽かと思いきや自分のトークを聞きに来てない聴衆に話すのは難しい、ふわっとした話になって反省 もっと細かく書きたいとは思っています。思ってはいる。
Checked other resources I added a very descriptive title to this issue. I searched the LangChain.js documentation with the integrated search. I used the GitHub search to find a similar question and didn't find it. I am sure that this is a bug in LangChain.js rather than my code. The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package). Example Code Make the model output long texts containing multibyte characters as a stream. import { VertexAI } from "@langchain/google-vertexai"; // Set your project ID and pass the credentials according to the doc. // https://js.langchain.com/docs/integrations/llms/google_vertex_ai const project = "YOUR_PROJECT_ID"; const langchainModel = new VertexAI({ model: "gemini-1.5-pro-preview-0409", location: "us-central1", authOptions: { projectId: project }, }); // EN: List as many Japanese proverbs as possible. const prompt = "日本のことわざをできるだけたくさん挙げて"; for await (const chunk of await langchainModel.stream(prompt)) { process.stdout.write(chunk); } Error Message and Stack Trace (if applicable) (No errors or stack traces occur) Output Example: Includes Replacement Characters (�) ## ������������:知恵の宝庫 日本のことわざは、長い歴史の中で培われた知恵や教訓が詰まった、短い言葉の宝庫で������いくつかご紹介しますね。 **人生・教訓** * **井の中の蛙大海を知らず** (I no naka no kawazu taikai wo shirazu): 狭い世界しか知らない者のたとえ。 * **石の上にも三年** (Ishi no ue ni mo san nen): ������強く努力すれば成功する。 * **案ずるより産むが易し** (Anzuru yori umu ga yasushi): 心配するよりも行動した方が良い。 * **転�������������** (Korobanu saki no tsue): 前もって準備をすることの大切さ。 * **失敗は成功のもと** (Shippai wa seikou no moto): 失敗から学ぶことで成功�������る。 **人���関係** * **類は友を呼ぶ** (Rui wa tomo wo yobu): 似た者同士が仲良くなる。 * **情けは人の為ならず** (Nasake wa hito no tame narazu): 人に親切にすることは巡り巡��て自分に良いことが返ってくる。 * **人の振り見て我が振り直せ** (Hito no furi mite waga furi naose): 他人の行動を見て自分の行動を反省する。 * **出る杭は打たれる** (Deru kui wa utareru): 他人より目���つ��叩かれる。 * **三人寄れば文殊の知恵** (Sannin yoreba monju no chie): みんなで知恵を出し合えば良い考えが浮かぶ。 ... Description This issue occurs when requesting outputs from the model in languages that include multibyte characters, such as Japanese, Chinese, Russian, Greek, and various other languages, or in texts that include emojis 😎. This issue occurs due to the handling of streams containing multibyte characters and the behavior of buffer.toString() method in Node. langchainjs/libs/langchain-google-gauth/src/auth.ts Line 15 in a1ed4fe data.on("data", (data) => this.appendBuffer(data.toString())); When receiving a stream containing multibyte characters, the point at which a chunk (readable.on('data', ...) is executed) is may be in the middle of a character’s byte sequence. For instance, the emoji "👋" is represented in UTF-8 as 0xF0 0x9F 0x91 0x8B. The callback might be executed after only 0xF0 0x9F has been received. buffer.toString() attempts to decode byte sequences assuming UTF-8 encoding. If the bytes are invalid, it does not throw an error, instead silently outputs a REPLACEMENT CHARACTER (�). https://nodejs.org/api/buffer.html#buffers-and-character-encodings To resolve this, use TextDecoder with the stream option. https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/decode Related Issues The issue has been reported below, but it persists even in the latest version. #4113 The same issue occurred when using Google Cloud's client libraries instead of LangChain, but it has been fixed. googleapis/nodejs-vertexai#78 googleapis/nodejs-vertexai#86 I will send a Pull Request later, but I am not familiar with this codebase, and there are many google-related packages under libs/ which I have not grasped enough. Any advice would be appreciated. System Info macOS node v20.12.2 langchain versions $ npm list --depth=1 | grep langchain ├─┬ @langchain/community@0.0.54 │ ├── @langchain/core@0.1.61 │ ├── @langchain/openai@0.0.28 ├─┬ @langchain/google-vertexai@0.0.12 │ ├── @langchain/core@0.1.61 deduped │ └── @langchain/google-gauth@0.0.12 ├─┬ langchain@0.1.36 │ ├── @langchain/community@0.0.54 deduped │ ├── @langchain/core@0.1.61 deduped │ ├── @langchain/openai@0.0.28 deduped │ ├── @langchain/textsplitters@0.0.0 │ ├── langchainhub@0.0.8
Fixes #6501 I have fixed this issue similarly to #5286. The approach is the same, but we need to use components that work in the Browser environment instead of Node. I previously fixed the same issue for @langchain/google-vertexai in #5285. Although I don't use @langchain/google-vertexai-web myself, I've also fixed this package as it was requested in the issue.
Checked other resources I added a very descriptive title to this issue. I searched the LangChain.js documentation with the integrated search. I used the GitHub search to find a similar question and didn't find it. I am sure that this is a bug in LangChain.js rather than my code. The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package). Example Code Make the model output long texts containing multibyte characters as a stream. import { VertexAI } from "@langchain/google-vertexai-web"; const langchainModel = new VertexAI({ model: "gemini-1.5-pro-001", location: "us-central1", }); // EN: List as many Japanese proverbs as possible. const prompt = "日本のことわざをできるだけたくさん挙げて"; const stream = await langchainModel.stream(prompt); const reader = stream.getReader(); let buf = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buf += value; } console.log(buf); This code can be executed by creating a service account key from the Google Cloud Console and running it with the following command: $ GOOGLE_WEB_CREDENTIALS=$(cat ./key.json) npx tsx sample.ts Error Message and Stack Trace (if applicable) (No errors or stack traces occur) Output Example: Includes Replacement Characters (�) ## ���本の諺 (ことわざ) - できるだけたくさん! **一般的な知������������** * 石の上にも三年 (いしのうえにもさんねん) - Perseverance will pay off. * 七転び八起き (ななころびやおき) - Fall seven times, stand up eight. * 継続は力なり (けいぞくはちからなり) - Persistence is power. * 急がば回れ (い��がばまわれ) - Haste makes waste. * 井の中の蛙大海を知らず (いのなかのかわずたいかいをしらず) - A frog in a well knows nothing of the great ocean. * 良���は���に苦し (りょうやくはくちにくい) - Good medicine tastes bitter. * 猿も木から落ちる (さるもきからおちる) - Even monkeys fall from trees. * 転石苔を生ぜず (てんせきこけをしょうぜず) - A rolling stone gathers no moss. * 覆水盆に返らず (ふくすいぼんにかえらず) - Spilled water will not return to the tray. * 後生の祭り (ごしょうの�����り) - Too late for regrets. * 習うより慣れろ (ならうよりなれろ) - Experience is the best teacher. * 鉄は熱いうちに打て (てつはあついうちにうて) - Strike while the iron is hot. ... Description This is the same issue as #5285. While #5285 is about @langchain/google-vertexai, this issue also occurs in @langchain/google-vertexai-web. The problem occurs when a stream chunk is cut in the middle of a multibyte character. For detailed reasons, please refer to #5285. I will submit a Pull Request with the fix shortly. System Info macOS node v20.12.2 langchain versions $ npm list --depth=1 | grep langchain ├─┬ @langchain/google-vertexai-web@0.0.25 │ ├── @langchain/core@0.2.23 │ └── @langchain/google-webauth@0.0.25 ├─┬ @langchain/google-vertexai@0.0.25 │ ├── @langchain/core@0.2.23 deduped │ └── @langchain/google-gauth@0.0.25 ├─┬ langchain@0.2.15 │ ├── UNMET OPTIONAL DEPENDENCY @langchain/anthropic@* │ ├── UNMET OPTIONAL DEPENDENCY @langchain/aws@* │ ├── UNMET OPTIONAL DEPENDENCY @langchain/cohere@* │ ├── UNMET OPTIONAL DEPENDENCY @langchain/community@* │ ├── @langchain/core@0.2.23 deduped │ ├── UNMET OPTIONAL DEPENDENCY @langchain/google-genai@* │ ├── @langchain/google-vertexai@0.0.25 deduped │ ├── UNMET OPTIONAL DEPENDENCY @langchain/groq@* │ ├── UNMET OPTIONAL DEPENDENCY @langchain/mistralai@* │ ├── UNMET OPTIONAL DEPENDENCY @langchain/ollama@* │ ├── @langchain/openai@0.2.6 │ ├── @langchain/textsplitters@0.0.3
Environment KFP SDK version: kfp==2.0.0b16 All dependencies version: kfp==2.0.0b16 kfp-pipeline-spec==0.2.2 kfp-server-api==2.0.0b1 Steps to reproduce When running the code snippet below the following error is raised: kfp.components.types.type_utils.InconsistentTypeException: Incompatible argument passed to the input 'val_a' of component 'add': Argument type 'STRING' is incompatible with the input type 'NUMBER_INTEGER' @dsl.component() def add(val_a: int, val_b: int) -> int: return val_a + val_b @dsl.pipeline() def model_training_pipeline() -> None: with dsl.ParallelFor( items=[{"a": 1, "b": 10}, {"a": 2, "b": 20}], parallelism=1 ) as item: task = add(val_a=item.a, val_b=item.b) compiler.Compiler().compile( pipeline_func=model_training_pipeline, package_path="/app/pipeline.yaml" ) Expected result According to the ParallelFor documentation, the code sample above should compile without errors. The add component should receive the values of the dictionaries as integer arguments. Materials and Reference The code snippet below is a modification of the code snippet above, changing the add component to accept string arguments. @dsl.component() def add(val_a: str, val_b: str) -> int: return int(val_a) + int(val_b) @dsl.pipeline() def model_training_pipeline() -> None: with dsl.ParallelFor( items=[{"a": 1, "b": 10}, {"a": 2, "b": 20}], parallelism=1 ) as item: task = add(val_a=item.a, val_b=item.b) compiler.Compiler().compile( pipeline_func=model_training_pipeline, package_path="/app/pipeline.yaml" ) The pipeline compiles without errors with this modification, however it fails to run in Google Vertex Pipelines. The add component doesn't even run and throws the following error in the UI: Failed to evaluate the expression with error: INVALID_ARGUMENT: Failed to parseJson from string.; Failed to evaluate the parameter_expression_selector. As the component's code is not even executed, it seems that the problem occurs when executing the DAG. Here is the content of the pipeline.yaml that was compiled. # PIPELINE DEFINITION # Name: model-training-pipeline components: comp-add: executorLabel: exec-add inputDefinitions: parameters: val_a: parameterType: STRING val_b: parameterType: STRING outputDefinitions: parameters: Output: parameterType: NUMBER_INTEGER comp-for-loop-2: dag: tasks: add: cachingOptions: enableCache: true componentRef: name: comp-add inputs: parameters: val_a: componentInputParameter: pipelinechannel--loop-item-param-1 parameterExpressionSelector: parseJson(string_value)["a"] val_b: componentInputParameter: pipelinechannel--loop-item-param-1 parameterExpressionSelector: parseJson(string_value)["b"] taskInfo: name: add inputDefinitions: parameters: pipelinechannel--loop-item-param-1: parameterType: STRUCT deploymentSpec: executors: exec-add: container: args: - --executor_input - '{{$}}' - --function_to_execute - add command: - sh - -c - "\nif ! [ -x \"$(command -v pip)\" ]; then\n python3 -m ensurepip ||\ \ python3 -m ensurepip --user || apt-get install python3-pip\nfi\n\nPIP_DISABLE_PIP_VERSION_CHECK=1\ \ python3 -m pip install --quiet --no-warn-script-location 'kfp==2.0.0-beta.16'\ \ && \"$0\" \"$@\"\n" - sh - -ec - 'program_path=$(mktemp -d) printf "%s" "$0" > "$program_path/ephemeral_component.py" python3 -m kfp.components.executor_main --component_module_path "$program_path/ephemeral_component.py" "$@" ' - "\nimport kfp\nfrom kfp import dsl\nfrom kfp.dsl import *\nfrom typing import\ \ *\n\ndef add(val_a: str, val_b: str) -> int:\n return int(val_a) +\ \ int(val_b)\n\n" image: python:3.7 pipelineInfo: name: model-training-pipeline root: dag: tasks: for-loop-2: componentRef: name: comp-for-loop-2 iteratorPolicy: parallelismLimit: 1 parameterIterator: itemInput: pipelinechannel--loop-item-param-1 items: raw: '[{"a": 1, "b": 10}, {"a": 2, "b": 20}]' taskInfo: name: for-loop-2 schemaVersion: 2.1.0 sdkVersion: kfp-2.0.0-beta.16 Impacted by this bug? Give it a 👍.