オープンソースの判定サービス

Pointsman が
進路を切り替えます。

システムが質問を送ると、Pointsman がどの線路に進めるかを決めます。確信がないときは、人に判断を任せます。

Cloudflare Workers モデルを差し替えられる REST + MCP OpenAPI MIT
POST /v1/decide/issue-triageリクエスト
{ "state": { "issue": {
  "title": "ログイン画面が真っ白",
  "body": "今朝から表示されません。"
} } }
200 OK判定(一部)
{
  "decision_id": "8c0f…",
  "profile": "issue-triage", "profile_version": 1,
  "answers": {
    "team":   { "value": "backend", "p": 0.9 },
    "urgent": { "value": false, "p": 0.8 },
    "effort": { "value": 0, "p": 0.7 }
  },
  "rule": 0,
  "action": "auto"
}

Pointsman がすること

多くのシステムには、まず誰かが確認すべきものが届きます。住民から通行止めの通報が届く。新しい Issue が届く。デプロイが止まっているように見える。はっきりしていて、すぐに対応できることもあれば、はっきりせず、人が確認したほうがよいこともあります。Pointsman は、この最初の判定をします。そして、すべての判定の記録を残します。

  1. 決まった質問をする

    例として、住民が「倒木で道路がふさがっている」と通報したとします。どんな種類の通行止めか。誰かに危険はあるか。AI が質問ごとに答え、どのくらい確かかも示します。たとえば「危険: あり、85 %」です。

  2. 人が書いたルールで決める

    ルールは人が書きます。たとえば「危険が 70 % 以上なら urgent(緊急)」です。AI だけで決めることはありません。ルールでは、公開データから得た情報も使えます。たとえば、その場所が浸水想定区域にあるかどうかです。

  3. 答えを返し、記録を残す

    答えはアクションです。この例では urgent です。Pointsman は、質問、答え、使ったルールを保存します。あとで人が答えを直すこともできます。そのため、AI がどのくらい正しかったかが分かります。

    publishurgentreview

この例はデモで試せます。review は「人が確認する」という意味です。

確かめられる判定

多くのシステムは、どのチームに回すか、急ぎかどうか、待つか止めるか、といった小さな判断を一日中しています。Pointsman はそれを一か所で、毎回同じやり方で行い、あとで測れる記録を残します。

形式の決まった質問

はい/いいえ、選択、スコアの質問です。どの答えにも確率が付くので、モデルがどれだけ確信しているかが分かります。

プロンプトではなくポリシー

team.p >= 0.85 のようなルールで、答えをアクションに変えます。ポリシーは設定ファイルに書くだけで、読み込むときに検査され、コードとして実行されることはありません。

迷ったら人へ

しきい値に届かなければ、アクションは review です。判定はレビュー待ちの一覧に入ります。リクエストに callback_url があれば、最終的な答えが署名付きでそこに送られます。

バージョン付きのプロファイル

質問とポリシーは YAML のプロファイルに書き、JSON Schema で CI が検証します。判定ごとに、プロファイルのバージョンとモデルが記録されます。

フィードバックと正解率

人が判定を訂正すると、その訂正が答えの横に記録されます。しきい値を上げる前に、プロファイルのバージョンごとの正解率を測れます。

モデルを差し替えられる

モデルはアダプターでつなぎます。いまは Cloudflare Workers AI(clef-flash、clef、AI Gateway 経由も可)、自分たちのモデルサーバー(たとえば手元の Strands Decider)、開発とテスト用のモックモデルが使えます。

公開データから得た情報

指定した場所について、浸水想定区域と最寄りの避難場所(国土地理院のデータ)、通れない道路を車や徒歩で迂回する道のり(OpenStreetMap と Valhalla)を調べられます。AI はこれらの情報を見ません。ルールが使い、判定には出典が残ります。

前の判定をもとにする判定

プロファイルは、同じ対象についての前の判定を requires で指定できます。前の判定は ID でログから読みます。最終判定は AI を使わず、ルールだけで決めることもできます。前の段階に人が答えていれば、その答えが使われます。

判定の流れを図にする

GET /v1/profiles/{id}/graph は、判定のつながりを SVG の図にします。DMN 1.3 として書き出し、dmn-js や Camunda Modeler などの DMN ツールで開くこともできます。DMN の用語を使いますが、決定表は使いません。

仕組み

リクエスト 1 つに、判定 1 つ。あとで理由を説明するのに必要なものは、すべて判定ログに残ります。

  1. 状態を送る

    システムが持っている情報(Issue、デプロイのイベント、フォームなど)を、JSON かテキストでプロファイルに送ります。

  2. 質問に答える

    プロファイルのモデルが、形式の決まった質問に答えます。失敗したときは予備のモデルが引き継ぎます。

  3. ポリシーを適用する

    ルールが答えと確率を比べます。最初に当てはまったルールがアクションを決めます。

  4. 実行する

    システムがアクションに従うか、人が決めます。

    autoreview独自のアクション

Pointsman の使いみち

エンジンは 1 つで、いろいろな仕事に使えます。使いみちごとに、今動くプロファイルの例、事実、クライアントをまとめました。そのまま使うことも、自分たちのプロファイルの出発点にすることもできます。

防災・災害対応

報告された通行止めを、公開の地図に載せる前に確認します。浸水想定区域と近くの避難場所は日本の公開データから、迂回路はルート検索サーバーから調べます。急ぎの報告とはっきりしない報告は人に回します。歩く人が避難場所へ行けなくなるときは、避難の確認が alert を返し、最終判断でその報告は急ぎ(urgent)になります。ブリッジを通して FIWARE と連携できます。

road-restriction-checkevacuation-access-checkroad-closure-final
examples/disaster-response(英語)→

DevOps

AWS CloudFormation のデプロイが静かになったとき、止まっているのか、遅いだけなのか。GitHub Action は、スタックがしばらく静かになってから Pointsman に聞き、cancel の答えが 2 回続いたときだけデプロイを止めます。Pointsman につながらないときは何も止めません。

deploy-progress
examples/devops(英語)→

開発の流れ

新しい Issue はどのチームが担当するか、今日の作業を止めているか、どのくらいの作業か。GitHub Action は、Pointsman が確かなときはラベルを付け、確かでないときは人に任せます。エージェントも MCP で同じプロファイルに聞けます。

issue-triage
examples/developer-workflow(英語)→

プロファイルは設定です

プロファイルには、何を聞き、答えをどう使うかを書きます。しきい値はプロンプトではなく、プルリクエストで変えます。

  • コードと同じようにレビュー。プロファイルは自分たちの非公開の設定リポジトリに置き、デプロイ時に公開されます。同じバージョンは一度しか書き込めません。
  • 動かす前に検証。JSON Schema と検証ツールが、CI ですべてのプロファイルを確認します。
  • 見せる場所を選べる。MCP でエージェントに見せることも、API だけに限ることもできます。

プロファイルの形式

profiles/issue-triage.yamlYAML
id: issue-triage
version: 1
title: { en: Issue triage, ja: Issue の振り分け }
description:
  en: Route a new issue to the right team.
  ja: 新しい Issue を担当チームに振り分ける。
model: clef-flash
fallback_models: [clef]
questions:
  - name: team
    type: choice
    instructions: Which team should handle this issue?
    criteria:
      - { value: backend,  description: "APIs, databases" }
      - { value: frontend, description: "Web pages, styles" }
      - { value: docs,     description: "Documentation" }
  - name: urgent
    type: noul
    instructions: Does this block someone's work today?
  - name: effort
    type: score
    instructions: How much work does this look like?
    criteria: ["under an hour", "a few hours", "a few days", "more than a week"]
policy:
  rules:
    - when: "team.p >= 0.85"
      action: auto
  default: review

どこからでも使える

誰が聞いても、同じプロファイル、同じポリシー、同じ判定ログです。

REST API

判定、判定の取得、フィードバック、レビュー待ちの処理、プロファイルの判定グラフの取得ができます。OpenAPI で記述されています。クライアントごとに API トークンがあり、必要なプロファイルだけに限れます。

openapi.yaml(英語)→

エージェント向けの MCP

Model Context Protocol(MCP)で Pointsman をコネクターとして追加すると、エージェントは推測する代わりに decide を呼びます。機械は API トークンを、人は GitHub でログインして使い、判定を訂正することもできます。

AI とエージェント →

GitHub の Issue 振り分け

GitHub Action が、判定に基づいて新しい Issue にラベルを付けます。使うのは指定したラベルだけです。確信がないときや Pointsman につながらないときは、代わりに needs-triage ラベル(変更できます)を付けます。

actions/triage(英語)→

デプロイの監視

CloudFormation のデプロイを監視する GitHub Action です。タイムアウトを待たずに、Pointsman が進んでいないと判定した時点で中止します。

actions/deploy-watch(英語)→

FIWARE ブリッジ

FIWARE は、スマートシティのデータ基盤のためのオープンソースのソフトウェア群です。データには NGSI-LD というオープンな標準を使います。ブリッジは、こうしたデータ基盤と Pointsman をつなぎます。データが変わるとブリッジが Pointsman に聞き、その判定をデータ基盤に書き戻します。ほかのアプリもその判定を使えます。Decision や Task のエンティティ(datamodels.jp のモデル)も作れます。データ基盤で人が答えると、レビューが完了します。

bridge(英語)→

はじめる

サンプルのプロファイルとモックモデルを使えば、数分で手元で動かせます。Cloudflare のアカウントは要りません。モックモデルは決まった答えを返します。手元で実際のモデルの答えを得る方法は docs/models.md(英語)にあります。

  1. インストール

    Node.js 24 と pnpm 12 が必要です。

  2. Worker を起動

    手元の判定ログを作り、ポート 8787 で Worker を起動します。

  3. 判定を頼む

    手元用の API トークンを作り、プロファイルに状態を送ります。

  4. 自分たちの環境にデプロイ

    設定リポジトリのテンプレートをコピーします。プロファイルも Cloudflare アカウントも自分たちのもので、非公開のままです。

    Pointsman のデプロイ→
ターミナルsh
# 1. インストール
git clone https://github.com/geolonia/pointsman
cd pointsman
pnpm install

# 2. 起動
pnpm db:migrate:local
pnpm dev

# 3. 判定を頼む(別のターミナルで)
node scripts/tokens.mjs create \
  --client demo --profiles issue-triage --local
export POINTSMAN_TOKEN=pm_…
curl -s localhost:8787/v1/decide/issue-triage \
  -H "authorization: Bearer $POINTSMAN_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"state": {"issue": {"title": "ログイン画面が真っ白"}}}'

Pointsman はまだ 1.0 ではないため、API やプロファイルの形式は 0.x の間に変わることがあります。リリースノート(英語)をご覧ください。試したら、ぜひ Issue で教えてください。ドキュメントは英語です。

よくある質問

Pointsman について実際に受けた質問に、短く答えます。

大きな AI モデルが必要ですか?

いいえ。Pointsman が AI に聞くのは、答えの形が決まったいくつかの質問だけです。答えは「はい/いいえ」、選択肢、点数のどれかです。そのため、小さく安価なモデルで十分です。標準では Cloudflare Workers AI の clef モデルを使います。自分のサーバーで動かすモデルにつなぐこともできます。

先にモデルを学習させる必要がありますか?

いいえ。書くのは質問とルールだけで、モデルはその質問にそのまま答えます。Pointsman にモデルを学習させる機能はありません。自分のデータで学習させたモデルがすでにあれば、モデルサーバー経由でつなげます。ただし、同じ形で答えられるモデルに限ります(はい/いいえ、選択肢、点数と、それぞれの確率)。判定ごとに AI の答えと人による訂正が並べて記録されるので、モデルにどこまで任せられるかを確かめてから広げられます。

モデルの確信度を見て動くスクリプトと同じではありませんか?

考え方は同じです。Pointsman は、そのスクリプトの部分を、人が読んで確かめられる形にしたものです。

  • ルールはコードではなく、市やチームが書く設定です。
  • プロファイルで指定すれば、ルールを使う前に、公開データから得た場所の情報を加えます。
  • どのルールにも当てはまらなければ、プロファイルの既定のアクションになります。多くの場合は人の確認です。
  • 判定ごとに、答え、事実、使ったルール、プロファイルのバージョンを記録します。
  • 前の判定を受けて、次の判定をすることもできます。
空間データでモデルを学習させる GIS ツールとは何が違いますか?

そうしたツールは、モデルを作るためのものです。たとえば、航空写真から建物を見つけるモデルを作れます。Pointsman はモデルを作りません。モデルの答えに公開データから得た場所の情報を加え、何をするかは、人が書いたルールで決めます。両方を組み合わせることもできます。ほかの環境で学習させたモデルでも、同じ形で答えられるもの(はい/いいえ、選択肢、点数と、それぞれの確率)なら、モデルサーバー経由で Pointsman の質問に答えられます。

AI に確信がないときはどうなりますか?

答えにはそれぞれ確率が付き、ルールはそれを、設定したしきい値と比べます。どのルールにも当てはまらなければ、プロファイルの既定のアクションになります。ふつうは review で、判定は人の確認を待ちます。人の答えは記録され、後の判定でも使われます。