0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

会話メモをAgentに渡す前に、条件付きの納期をPythonで確認する

0
Posted at

会話の検索で「Friday」が見つかっても、それだけで納期を確定扱いにはできません。条件の付いた発言を、次のAgentへどう渡すか。自分の英語の記事で書いた例を、Pythonで動く小さな確認処理にしてみました。

私はMemoketの共同創業者兼CTOです。この記事のコードは説明用の架空データを扱う独立した例で、Memoketの製品APIや実装済みメモリスキーマではありません。標準ライブラリだけで実行でき、録音、MCP、LLMへのアクセスは行いません。

何を取り違えたくないか

月曜日に、次のような発言があったとします。

We can deliver on Friday, if the client approves the revised scope.

残したいのはFridayという文字列だけではなく、対象の顧客、提案の版、承認という条件、元の記録です。さらに、スコープの承認と、納期を確約した記録も分けます。承認が見つからないことを、承認されていない証拠として扱わない点も大切です。

条件付きの金曜日という候補と、承認の記録、週報での扱いを分けた架空の説明図

図は説明用です。アプリ画面や自動抽出の実測ではありません。

入力を決めて、確認を段階に分ける

この例では、会話から必要な項目を正しく構造化できた後を扱います。確認するのは次の順番です。

  1. 依頼対象の顧客が特定され、候補の顧客と一致するか。
  2. 候補の発言に出典が付いているか。
  3. 同じ顧客・提案・スコープ版を対象とする承認記録があるか。
  4. その承認と区別できる納期確認の記録があり、日付も候補と一致するか。

sourceは架空の参照文字列です。文字列があるだけで引用内容の正しさを保証できるわけではなく、実システムでは元の記録を開いて確認する工程が別に必要です。

実行例

以下をconditional_handoff.pyに保存し、python3 conditional_handoff.pyで実行できます。入力例と出力は英語にしています。

"""Fictional, manually structured records; no model, MCP or product API calls."""
import json

proposal = {
    "client_id": "maple",
    "proposal_id": "delivery-1",
    "scope_revision": "v2",
    "candidate_date": "Friday",
    "source": "fictional:monday-conversation",
}


def matches(record, candidate, expected_kind):
    keys = ("client_id", "proposal_id", "scope_revision")
    return bool(record and record.get("source") and
                record.get("kind") == expected_kind and
                all(record.get(k) == candidate[k] for k in keys))


def review(client_id, candidate, approval=None, commitment=None):
    if not client_id or client_id != candidate["client_id"]:
        return "client_unresolved"
    if not candidate.get("source"):
        return "proposal_source_missing"
    if not matches(approval, candidate, "scope_approval"):
        return "approval_evidence_unverified"
    if (not matches(commitment, candidate, "delivery_confirmation") or
            commitment.get("date") != candidate["candidate_date"]):
        return "approval_recorded_commitment_unverified"
    return "matching_approval_and_commitment_records_found"


approval = {**proposal, "kind": "scope_approval",
            "source": "fictional:approval-message"}
commitment = {**proposal, "kind": "delivery_confirmation", "date": "Friday",
              "source": "fictional:delivery-confirmation"}
cases = [
    ("unknown client", None, proposal, None, None),
    ("no approval record", "maple", proposal, None, None),
    ("approval for old scope", "maple", proposal,
     {**approval, "scope_revision": "v1"}, None),
    ("approval only", "maple", proposal, approval, None),
    ("approval reused as commitment", "maple", proposal, approval, approval),
    ("different delivery date", "maple", proposal, approval,
     {**commitment, "date": "Next Monday"}),
    ("both records", "maple", proposal, approval, commitment),
]
for name, client, candidate, approved, committed in cases:
    print(json.dumps({"case": name,
                      "state": review(client, candidate, approved, committed)}))

実行した出力です。

{"case": "unknown client", "state": "client_unresolved"}
{"case": "no approval record", "state": "approval_evidence_unverified"}
{"case": "approval for old scope", "state": "approval_evidence_unverified"}
{"case": "approval only", "state": "approval_recorded_commitment_unverified"}
{"case": "approval reused as commitment", "state": "approval_recorded_commitment_unverified"}
{"case": "different delivery date", "state": "approval_recorded_commitment_unverified"}
{"case": "both records", "state": "matching_approval_and_commitment_records_found"}

承認だけがある場合はapproval_recorded_commitment_unverifiedです。同じ承認レコードを納期確認の代わりに渡しても、kindが違うので通りません。納期確認の記録が別の日付を指している場合も、確認済みの扱いに進めません。

最後のmatching_approval_and_commitment_records_foundは、与えた項目が一致する2種類の記録を見つけた、という意味です。現実の納期が確定していると証明したわけではありません。

このコードで確認していないこと

自然言語からの抽出が正しいか、顧客IDの対応付けが正しいか、記録にアクセスする権限があるか、後から取消や変更があったかは扱っていません。入力を作る処理の評価や、後続の記録との照合は別です。

小さな例ですが、「取り出せた文章」と「いま判断に使える前提」の間に、どの確認が残っているかを明示できます。MCPの接続ができた後も、その境界を残しておきたいと思っています。

英語版のChatGPT例では、複数会議から懸念の候補は拾えましたが、どの顧客かは一意に特定できていませんでした。したがって、この例の最初の確認も省略できません。ここで新たにChatGPTやMemoketの実アカウントを使った検証はしていません。

背景となる原文:You Have Become Your AI Assistant’s Memory

コードの作成、確認、文章の編集にはAIアシスタントを使用しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?