monday Service + LangSmith: 初日からコードファーストの評価戦略を構築
monday.comは、LangGraphベースのAIエージェント「monday Service」の開発において、オフライン評価とオンライン監視という二層構造の評価戦略を初期段階から実装し、フィードバックループの高速化と品質保証を実現したケーススタディである。
キーポイント
Day 0からの評価統合
Alphaユーザーのフィードバックを待つのではなく、開発初期段階から評価(Evals)を組み込むことで、AIの品質問題を事前に検出する戦略を採用した。
オフライン評価(セーフティネット)
ユニットテストのように動作するオフライン評価により、ゴールデンデータセットを用いて論理の正しさやツール呼び出しの正確性を検証し、プロンプト変更による副作用を防ぐ。
オンライン評価(継続的品質)
本番環境でのエンドツーエンドのビジネス指標(自動解決率など)をリアルタイムで監視し、エージェントのパフォーマンスを継続的に最適化する。
技術的成果と効率化
LangChainのLangSmithを活用したコードベースの評価管理により、評価フィードバックループを8.7倍高速化(162秒→18秒)し、GitOpsスタイルのCI/CDデプロイを実現した。
評価対象の定義と初期セットアップ
実在するITサポートチケット約30件を用いてデータセットを構築し、エージェントの動作健康状態(クラッシュやタイムアウトの有無)、出力形式、ステートの永続化、およびツールの正常な呼び出しといった基本的な「スモークテスト」から評価を開始した。
高度な振る舞いへの評価の拡張
単なる正誤判定から、KB(ナレッジベース)の根拠付けや引用検証、コンフリクト時の対応、安全ガードレールの適用タイミングなど、エージェントの軌跡や文脈に応じた詳細なチェックへと評価範囲を拡大した。
LangSmithとVitestの統合によるCI/CD連携
LangSmith Vitest統合を活用し、Vitestの堅牢なテストフレームワークとLangSmithのエコシームを組み合わせることで、CI実行ごとに実験としてログを残し、コード変更前の影響確認を容易にした。
影響分析・編集コメントを表示
影響分析
この事例は、生成AIアプリケーションの運用における「評価(Evaluation)」の重要性を具体化しており、単なるポラビリティチェックではなく、開発ライフサイクルに組み込まれたエンジニアリングプロセスとして位置づけるべきことを示唆している。特に、LangGraphやLangSmithといったエコシステムを活用した「Evals as Code」の手法は、大規模なエンタープライズAI導入における標準プラクティスを定義する上で重要な指針となる。
編集コメント
エンタープライズ領域でのAI実装において、品質保証を後回しにするリスクは極めて高い。このケーススタディは、開発プロセスに評価を組み込む具体的な技術的アプローチを示しており、実務者にとって非常に参考になる実践的な知見である。
[これは、顧客向けAIサービスエージェントの評価戦略を主導するmonday.comの友人たちからのゲスト投稿です(Gal Ben Arieh (Group Tech Lead) 主導)。ご寄稿ありがとうございます!]
多くのチームは評価を最後の確認作業として扱いますが、私たちはそれを「Day 0」の要件としました。
monday Serviceは、すべてのサービス部門にわたる問い合わせを自動化し解決するために設計された、AIネイティブなエンタープライズサービス管理(ESM)プラットフォームです。新しいAIサービスワーカーフォース(人間の担当者のチケット負荷を軽減する、カスタマイズ可能なロールベースのAIエージェント群)を構築する際、私たちはアルファユーザーが問題点を見つけるのを待つのではなく、開発サイクルに最初から評価を組み込みました。
この記事では、ユーザーよりも先にAIの品質問題を捕捉するために、評価主導の開発フレームワークをどのように構築したかを紹介します。
私たちが達成したこと:
スピード: 評価フィードバックループが8.7倍高速化(162秒から18秒へ)。
カバレッジ: 数時間ではなく数分で、数百の事例にわたる包括的なテストを実施。
エージェントの可観測性: Multi-Turn Evaluatorsを使用した、本番トレースに対するリアルタイムのエンドツーエンド品質監視。
コードとしての評価: GitOpsスタイルのCI/CDデプロイメントによる、バージョン管理された本番コードとしての評価ロジック管理。
AIサービスワーカーフォースは、カスタマイズ可能な、LangGraphベースのReActエージェントであり、あらゆるエンタープライズサービス管理ユースケースにわたる問い合わせの自動化と解決を目的としています。
IT、HR、法務などの分野に適用される場合でも、monday Serviceのお客様は、独自のKB記事とツールを活用することで、あらゆるサービス部門内での実行を推進するようにエージェントを調整できます。
しかし、ReActエージェントを非常に強力にするその自律性は、同時に独自の課題も生み出します。推論チェーンの各ステップが前のステップに依存するため、プロンプトやツール呼び出し結果のわずかな逸脱が、大きく異なり、潜在的に誤った結果へと連鎖する可能性があるからです。
評価の二本柱
エージェント評価のベストプラクティスに関する調査を通じて、私たちは二層アプローチが必要であるとすぐに認識しました。
オフライン評価 — 「安全網」: ある種のユニットテスト層のように機能し、エージェントを厳選された「ゴールデンデータセット」に対して実行します。コアロジック(例:接地性、検索精度、ツール呼び出し)と特定のエッジケース(例:KB記事の競合や優先度解決)の両方をテストします。この層は、単純なプロンプト調整が、他のタスクを処理するエージェントの能力を誤って損なわないようにするのに役立ちます。
オンライン評価 — 「モニター」(継続的品質): この層は、エンドツーエンドのビジネス視点から、エージェントのパフォーマンスの継続的な収集、分析、強化を扱います。オンライン評価パイプラインを利用することで、ビジネスシグナル(例:自動解決率と封じ込め率)を追跡・改善し、実際の環境でのエージェントのパフォーマンスをリアルタイムで確保します。
柱A: オフライン評価 — 「安全網」
評価カバレッジ戦略の設計
最初の評価を書く前に、私たちは根本的な問いに答える必要がありました:実際に何を評価すべきか?課題は、完璧なカバレッジ戦略を設計することではなく、単に実用的な出発点を選ぶことでした。
私たちは、内部ITヘルプデスクから選んだ、実際の(匿名化された)解決済みITチケット約30件の小さなデータセットを構築しました。これにより、以下のような一般的なリクエストカテゴリをカバーします:
アクセス&アイデンティティ(例:IDP、SSO、ソフトウェアアクセス)
VPNおよび接続性の問題
デバイス / OSサポート(アップデート、パフォーマンス、ハードウェア問題)
その最初のスイートでは、チェックは意図的にシンプルなものでした:
決定的な「スモーク」チェック: ランタイム健全性: エージェントがクラッシュ/タイムアウトせずに実行され、リクエストがエンドツーエンドで成功する。
出力形式: レスポンスが期待されるスキーマ/フォーマットに一致する(内容を判断する前でも)。
状態&永続性: スレッド/セッションが作成され、会話がアプリケーションデータベースに適切に永続化される。
基本的なツール健全性チェック: すべての必要なツールが適切な入力で正しく呼び出され、エラーなく実行を完了した。
LLM-as-judge: 私たちは、OpenEvals(Correctness)の既製の評価器から始めました。これは、エージェントのレスポンスを、同じ解決済みチケットデータセットからの参照出力と比較します。
そのベースラインが確立されると、セッションメモリ、KB検索、接地性と競合解決、ガードレールなど、特定の動作を探るために、より小さなユースケース固有のデータセットで拡張しました。これらの動作がより微妙になるにつれ、私たちは単一の正確性スコアから、より包括的な一連のチェックへと移行しました:
KB接地性 / 引用: 「事実に基づく主張はすべて、提供されたKBコンテンツに遡及しているか?」(LangSmithの事前構築された hallucination / answer relevance チェックを使用してこれを検証します)。
競合処理: 「ポリシーが地域/時間によって異なる場合、エージェントは明確化を求めたり、最新の適用可能なポリシーを選択したりしたか?」(または事前構築された correctness チェック)。
ガードレール: 「エージェントは必要時に拒否したか?」/「内部ツール名やプロンプト内容を明かさなかったか?」(または事前構築された toxicity / conciseness チェック)。
KB使用タイミング: KBは適切な時点で(早すぎず、回答がすでに形成された後でもなく)取得されるべき(AgentEvalsの Trajectory LLM-as-judge を使用)。
ガードレール順序: セキュリティ/ポリシーガードレールは適切な段階(最終回答を生成する前)で実行されるべき。これは別の軌跡チェックです。
フレームワーク: langsmith/vitest
この層を実装するために、私たちはLangSmith Vitest統合を活用しました。このアプローチは、実戦で鍛えられたテストフレームワーク(Vitest)の力を提供しながら、LangSmithエコシステムとシームレスに統合されたままです。
このセットアップにより、すべてのCI実行がLangSmithプラットフォームで個別の実験として自動的に記録され、各テストスイートはデータセットとして機能します。これにより、特定の実行を詳細に調査し、エージェントがグラウンドトゥルースからどこで逸脱したかを正確に確認できる可視性が得られ、本番環境に到達する前にコード変更の影響を簡単に検証できます。
苦い教訓: DevEx(開発者体験)を妥協するな
当初、私たちのオフライン評価は直列で実行されていました。標準的な開発ループ — 評価(失敗)→ 修正 → 再評価(合格)— が大きなボトルネックになりました。
私たちは、遅いフィードバックループは必然的に、テストの深さか開発のペースのいずれかを妥協させてしまうことに気づきました。後退なしに高速なリリースを維持するためには、評価プロセスが、摩擦のない反復ループを確保するのに十分な速さでなければならないと認識しました。
解決策: Vitest + ls.describe.concurrent による並列化
VitestとLangSmithの統合を最適化することで、ローカルワーカーとリモートAPI呼び出しに負荷を分散させ、大幅な速度向上を達成しました。鍵はハイブリッドアプローチでした:テストファイルを並列化してCPU使用率を最大化し、LLM評価を並行して実行してI/Oバウンドの遅延を処理します。
並列処理(CPUバウンド): Vitestの pool:'forks' を活用して、ワークロードを複数のコアに分散させます。各データセットシャードを別々のテストファイルに割り当てることで、複数のワーカープロセスがCPUを競合することなく並列に実行できるようにします。この設定により、データセットが大きくなっても、利用可能なコア全体にシャードを分散することで迅速に処理できます。
並行処理(I/Oバウンド): 各テストファイル内で、ls.describe.concurrent を使用してスループットを最大化します。LLM評価は高遅延であるため、並行処理により、数十の評価を一度に発行して遅延をオーバーラップさせ、ランナーがアイドル状態にならないようにします。
評価関数: これは各例を評価するためのコアロジックです。これを単一パスで二層の検証を実行するために使用します:決定的ベースライン: エージェントがレスポンススキーマに従い、状態の永続性を維持することを保証するための厳密なアサーション(チェックポインタ/ストレージ経由)。
LLM-as-a-Judge: 「ゴールデンデータセット」に対する意味的な採点。OpenEvalsやAgentEvalsなどのオープンソースライブラリを活用して、正確性や接地性などの次元をスコアリングします。
結果: 数百の事例にわたる包括的なフィードバックが数分で得られます!
20件の匿名化ITチケットを使用したベンチマーク結果
原文を表示
[This is a guest post from our friends at Monday.com driving eval strategy for their customer-facing AI service agents, led by Gal Ben Arieh (Group Tech Lead). Thank you for your contribution!]
Many teams treat evaluation as a last-mile check, but we made it a Day 0 requirement.
monday Service is an AI Native Enterprise Service Management (ESM) platform designed to automate and resolve inquiries across all service departments. When building our new AI service workforce (a workforce of customizable, role-based AI agents that take the ticket load off human reps), we embedded evaluations into the development cycle from the start instead of waiting for Alpha users to find the gaps.
This article shows you how we built an evals-driven development framework to catch AI quality issues before our users do.
What we achieved:
Speed: 8.7x faster evaluation feedback loops (from 162 seconds to 18 seconds).
Coverage: Comprehensive testing across hundreds of examples in minutes instead of hours.
Agent observability: Real-time, end-to-end quality monitoring on production traces, using Multi-Turn Evaluators.
Evals as code: Evaluation logic managed as version-controlled production code with GitOps-style CI/CD deployment.
AI service workforce is a customizable, LangGraph-based, ReAct agent, designed to automate and resolve inquiries across any enterprise service management use case.
Whether applied to fields like IT, HR, or Legal, monday Service customers can tailor the agent to drive execution within any service department, by utilizing their own KB articles and tools.
However, the very autonomy that makes ReAct agents so powerful, also introduces a unique challenge: because each step of the reasoning chain depends on the last, a minor deviation in a prompt or a tool-call result can cascade into a significantly different— and potentially incorrect— outcome.
The Two Pillars of Evaluations
Through our research into agent evaluation best practices, we quickly realized that dual-layered approach is necessary:
Offline Evaluations — "The Safety Net": Acting somewhat like a unit-testing layer, runs the agent against curated "golden datasets”. Tests both core logic (e.g., groundedness, retrieval accuracy, tool-calling) and specific edge cases (e.g., KB article conflict or priority resolution), This layer helps to ensure that a simple prompt tweak doesn’t inadvertently break the agent's ability to handle other tasks.
Online Evaluations — "The Monitor" (Continuous Quality): This layer handles the ongoing collection, analysis, and enhancement of the agent’s performance from an end-to-end business perspective. By utilizing online evaluation pipelines, we track and refine business signals (e.g. Automated Resolution and Containment rates), ensuring in real time that the agent’s performance in the wild.
Pillar A: Offline Evaluations — "The Safety Net"
Designing Our Evaluation Coverage Strategy
Before writing a single evaluation, we needed to answer a fundamental question: What should we actually evaluate? The challenge wasn’t designing a perfect coverage strategy - it was simply picking a practical starting point.
We constructed a small dataset of ~30 real (sanitized) resolved IT tickets, chosen from our internal IT help desk to cover common request categories like:
Access & Identity (e.g. IDP, SSO, Software Access)
VPN and connectivity issues
Device / OS support (updates, performance, hardware issues)
In that first suite, our checks were intentionally simple:
Deterministic “smoke” checks:Runtime health: the agent ran with no crashes/timeouts, request succeeds end-to-end.
Output shape: the response matches the expected schema/format (even before judging content).
State & persistence: thread/session created and the conversation was persisted properly in our application database.
Basic Tool Sanity Check: All necessary tools were correctly invoked with appropriate inputs and completed their execution without errors.
LLM-as-judge: We started with an off-the-shelf evaluator from OpenEvals (Correctness) that compares the agent response to the reference output from the same resolved-ticket dataset.
Once that baseline existed, we expanded with smaller, use-case-specific datasets to probe specific behaviors – including session memory, KB retrieval, grounding and conflict resolution, and guardrails. As these behaviors got more nuanced, we moved from one correctness score to a more comprehensive set of checks:
KB grounding / Citations: “Does every factual claim trace back to the provided KB content?” (We verify this using LangSmith’s prebuilt hallucination / answer relevance checks).
Conflict handling: “When policies vary by region/time, did the agent ask for clarification or pick the latest applicable policy?” (or the prebuilt correctness check).
Guardrails: “Did the agent refuse when required?” / “Did it avoid revealing internal tool names or prompt content?” (or the prebuilt toxicity / conciseness checks).
KB usage timing: The KB should be fetched at a reasonable point (not too early, and not after the answer is already formed) using AgentEvals' Trajectory LLM-as-judge.
Guardrail ordering: Safety/policy guardrails should run at the right stage (before producing the final answer). This is another trajectory check.
The Framework: langsmith/vitest
To implement this layer, we utilized the LangSmith Vitest integration. This approach provides the power of a battle-hardened testing framework (Vitest) while remaining seamlessly integrated with the LangSmith ecosystem.
With this setup, every CI run is automatically logged as a distinct experiment in the LangSmith platform, and each test suite functions as a dataset. This gives us the visibility to drill down into specific runs and see exactly where the agent diverged from the ground truth, making it easy to verify the impact of any code changes before they reach production.
The Hard Lesson: Don’t Compromise on DevEx
At first, our offline evaluations ran serially. The standard development loop—eval (fail) → fix → re-eval (pass)—became a major bottleneck.
We found that a slow feedback loop inevitably compromises either our testing depth or our development pace. To sustain high-velocity shipping without regressions, we realized the evaluation process had to be fast enough to ensure a frictionless iteration loop.
The Solution: Parallelizing with Vitest + ls.describe.concurrent
By optimizing our Vitest and LangSmith integration, we achieved a massive speed increase by distributing the load across local workers and remote API calls. The key was a hybrid approach: parallelizing test files to maximize CPU usage and running LLM evaluations concurrently to handle I/O-bound latency.
Parallelism (CPU-Bound): We leverage Vitest’s pool:'forks' to distribute the workload across multiple cores. By assigning each Dataset Shard to a separate test file, we allow multiple worker processes to run in parallel without competing for CPU. This setup ensures that even as our datasets grow, we can process them quickly by distributing the shards across available cores.
Concurrency (I/O-Bound): Within each test file, we use ls.describe.concurrent to maximize throughput. Since LLM evaluations are high-latency, concurrency allows us to overlap the latency by firing off dozens of evaluations at once, ensuring the runner never sits idle.
The Eval Function: This is the core logic responsible for evaluating each example. We use it to run a two-tiered validation in a single pass:Deterministic Baseline: Hard assertions to ensure the agent adheres to the response schema and maintains state persistence (via checkpointer/storage).
LLM-as-a-Judge: Semantic grading against a "Golden Dataset". We leverage open-source libraries like OpenEvals and AgentEvals to score dimensions like correctness and groundedness.
The Result: Comprehensive feedback over hundreds of examples in minutes!
Benchmarking results for 20 sanitized IT tickets using a MacBook Pro 16-inch (Nov 2023, Apple M3 Pro, 36 GB RAM, macOS Tahoe 26.2):
Speedup vs Sequential
Parallel + Concurrent
Concurrent Only
Pillar B: Online Evaluations — "The Monitor”
Online, Multi Turn Evaluations
While offline evaluations are often used to catch regressions in a controlled sandbox, they are essentially static snapshots of synthetic or sanitized examples. To capture the unpredictability of production, we needed Online Evaluations—running on real production traces in real-time.
Since our agent handles complex, multi-turn dialogues, success is often not defined by a single response, but by the entire conversation trajectory. This requires an evaluation strategy that accounts for how the agent guides the user toward a resolution over several turns.
We found a perfect fit in LangSmith’s Multi-Turn Evaluator, which leverages LLM-as-a-judge to score end-to-end threads. Instead of evaluating individual runs in isolation, we can now use custom prompts to grade the entire conversation trajectory—measuring high-level outcomes like user satisfaction, tone, and goal resolution.
What’s most impressive is how quickly we were able to go live. The LangSmith platform makes the multi-turn setup incredibly intuitive: we could define a custom inactivity window to pinpoint exactly when a session should be considered "complete" and ready for evaluation, and easily apply a sampling rate to balance our data volume with the LLM costs.
Evaluations as Code (EaC)
As we moved from prototype to production, we wanted to manage our "judges" with the same standards we apply to any other production code: version control, peer reviews, and automated CI/CD pipelines.
To achieve this, we moved the source of truth into our repository, defining our "judges" as structured TypeScript objects.
// conversation-analysis.ts export const conversationAnalysis = new MultiSignalEvaluationPrompt({ name: 'conversation-analysis', variables: ['all_messages'], modelConfig: { model: 'gpt-5.2-pro', reasoning: { effort: 'high' } }, extractionFields: [ new ExtractionField({ key: 'human_handoff', type: 'boolean', includeComment: true }), new ExtractionField({ key: 'meaningful_interaction', type: 'boolean', includeComment: true }), new ExtractionField({ key: 'is_automated_resolution', type: 'boolean', includeComment: true }), // ... additional atomic signals ], systemPrompt: You are an expert conversation analyst..., humanPrompt: Analyze the following conversation: <conversation> {{{all_messages}}} </conversation>, });
Moving our judges into code unlocked two critical capabilities:
We could leverage AI IDEs like Cursor and Claude Code to refine complex prompts directly within our primary workspace.
It felt natural to write offline evaluations for our judges to ensure accuracy before they ever touch production traffic.
The migration was relatively easy thanks to LangChain’s IDE integrations. We used the Documentation MCP to pull library context into our editor and the LangSmith MCP to fetch runs and feedback directly. The LangChain Chat was also a useful reference for clarifying specific implementation details.
To close the loop, we built a custom CLI command, yarn eval deploy, that runs in our CI/CD pipeline. This ensures our repository remains the absolute Source of Truth for our evaluation infrastructure.
When we merge a PR, our synchronization engine performs a three-step Reconciliation Loop:
Sync Prompts: Pushes TypeScript definitions to the LangSmith Prompt Registry.
Reconcile Rules: Compares local evaluations (rules) definitions against active production ones, updating or creating them automatically.
Prune: Identifies and deletes "zombie" evaluations/prompts from the LS platform if these are no longer present in the codebase.
The Evolution of the Stack: Looking Ahead
As our evaluation logic matured, we wanted to manage it with the same rigor as production code— version control, PR reviews, CI/CD. LangSmith's API-first architecture mad
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み