LLMエージェントを業務システムに組み込むときの設計判断

Design Decisions When Embedding LLM Agents in Business Systems

将LLM智能体集成到业务系统时的设计判断

設計 Engineering 设计

はじめに

業務システムにLLMを組み込むとき、最初から「自律エージェント」を目指すと、たいてい行き詰まります。理由はシンプルで、業務システムの価値は「正しさ」と「説明責任」にあるからです。どれだけ賢くても、なぜその判断をしたのか説明できない仕組みは現場に入りません。

この記事では、産業分野の業務システムにAIを組み込むときに、私たちが最初に決めている設計判断を整理します。

1. いきなりエージェントにしない

まず問うべきは「この処理は毎回同じ手順か」です。

処理の性質適した形
手順が固定通常のプログラム
手順は固定だが入力が多様LLMで前処理・分類
手順自体を選ぶ必要があるエージェント

手順が固定なら、LLMを挟むとかえって遅く、高く、不安定になります。エージェントは「次に何をするかを選ぶ」必要があるときにだけ使います。

2. 副作用のある操作は人間の承認を挟む

エージェントに権限を与えるときは、操作を3つに分類します。

  • 読み取り — 自律実行してよい
  • 提案 — 下書きを作り、人が承認する
  • 実行 — 人が明示的に確定操作をする

自律性は「便利さ」と引き換えに「取り返しのつかなさ」を買う。業務システムでは後者のコストが桁違いに大きい。

3. 出力は構造化して受け取る

自由文をそのまま後続処理に渡すと、例外処理が爆発します。スキーマを定義し、検証を通ったものだけを受け入れます。

from pydantic import BaseModel, ValidationError

class Report(BaseModel):
    site_id: str
    category: str
    severity: int
    summary: str

def parse(raw: str) -> Report | None:
    try:
        # 検証に通らないものは黙って通さない
        return Report.model_validate_json(raw)
    except ValidationError:
        return None

検証に落ちた回数を記録しておくと、そのままプロンプト改善の指標になります。

4. 失敗を前提に、冪等性から設計する

LLMの呼び出しは失敗します。タイムアウト、レート制限、そして「それらしいが間違っている出力」。

大事なのは、同じ処理を二度実行しても壊れないようにすることです。処理ごとに一意なキーを発行し、すでに処理済みなら結果を返すだけにします。

  1. 入力のハッシュから処理キーを作る
  2. 処理済みなら保存済みの結果を返す
  3. 未処理なら実行し、結果をキーと一緒に保存する

5. 評価セットを最初に作る

「良くなった気がする」を卒業するには、評価用の入力と期待出力のペアを20〜30件用意します。

  • 実際の現場データから代表的なケースを選ぶ
  • 期待する出力を人が書く
  • 変更のたびに全件通し、スコアを記録する

これを先にやっておくと、モデルを差し替えたときの判断が一気に楽になります。

おわりに

派手な自動化よりも、壊れたときに壊れ方が穏やかな設計のほうが、現場では長く使われます。

Introduction

When embedding an LLM into a business system, aiming for a fully "autonomous agent" from day one usually stalls. The reason is simple: the value of a business system lies in correctness and accountability. No matter how capable it is, a system that cannot explain why it made a decision will not be adopted in the field.

This article collects the design decisions we make first when bringing AI into industrial business systems.

1. Don't start with an agent

The first question to ask is: "does this process follow the same steps every time?"

Nature of the workSuitable form
Fixed procedureOrdinary code
Fixed procedure, varied inputLLM for pre-processing / classification
The procedure itself must be chosenAgent

If the procedure is fixed, inserting an LLM makes it slower, more expensive, and less stable. Use an agent only when something genuinely has to choose what to do next.

2. Put human approval in front of side effects

When granting an agent authority, classify every operation into three kinds:

  • Read — may run autonomously
  • Propose — produces a draft; a person approves it
  • Execute — requires an explicit confirmation from a person

Autonomy buys convenience at the price of irreversibility. In business systems the cost of the latter is orders of magnitude larger.

3. Receive output as structured data

Passing free-form text straight into downstream processing makes exception handling explode. Define a schema and accept only what passes validation.

from pydantic import BaseModel, ValidationError

class Report(BaseModel):
    site_id: str
    category: str
    severity: int
    summary: str

def parse(raw: str) -> Report | None:
    try:
        # Never let unvalidated output through silently
        return Report.model_validate_json(raw)
    except ValidationError:
        return None

Recording how often validation fails gives you a direct prompt-improvement metric.

4. Design for failure, starting with idempotency

LLM calls fail. Timeouts, rate limits, and output that looks plausible but is wrong.

What matters is that running the same operation twice does not break anything. Issue a unique key per operation, and if it has already been handled, simply return the stored result.

  1. Derive an operation key from a hash of the input
  2. If already processed, return the stored result
  3. Otherwise run it and store the result alongside the key

5. Build an evaluation set first

To graduate from "it feels better," prepare 20–30 input/expected-output pairs.

  • Pick representative cases from real field data
  • Have a person write the expected output
  • Run the full set on every change and record the score

Doing this early makes the call far easier when you swap models.

Closing

More than flashy automation, a design whose failure mode is gentle is what gets used in the field for years.

引言

在将LLM集成到业务系统时,如果一开始就追求完全「自主的智能体」,往往会陷入僵局。原因很简单:业务系统的价值在于正确性与可追责性。无论多么聪明,如果无法解释为何做出某个判断,这样的机制就无法在现场落地。

本文将梳理我们在把AI引入产业领域业务系统时,最先确定的设计判断。

1. 不要一上来就做智能体

首先应该问的是:「这个处理每次的步骤都一样吗?」

处理的性质合适的形式
步骤固定普通程序
步骤固定但输入多样用LLM做预处理・分类
需要选择步骤本身智能体

如果步骤是固定的,插入LLM反而会更慢、更贵、更不稳定。只有当确实需要「决定下一步做什么」时,才使用智能体。

2. 有副作用的操作必须经过人工批准

在赋予智能体权限时,把操作分为三类:

  • 读取 — 可以自主执行
  • 提议 — 生成草稿,由人批准
  • 执行 — 必须由人明确确认

自主性以「便利」为代价,换来的是「不可挽回」。在业务系统中,后者的代价要大得多。

3. 以结构化方式接收输出

把自由文本直接交给后续处理,异常处理会急剧膨胀。应定义模式,只接受通过验证的结果。

from pydantic import BaseModel, ValidationError

class Report(BaseModel):
    site_id: str
    category: str
    severity: int
    summary: str

def parse(raw: str) -> Report | None:
    try:
        # 验证不通过的内容绝不悄悄放行
        return Report.model_validate_json(raw)
    except ValidationError:
        return None

记录验证失败的次数,可直接作为改进提示词的指标。

4. 以失败为前提,从幂等性开始设计

LLM调用会失败。超时、限流,以及「看似合理但实际错误」的输出。

关键在于:同一处理执行两次也不会被破坏。为每个处理生成唯一键,如果已经处理过,就只返回已保存的结果。

  1. 由输入的哈希生成处理键
  2. 若已处理,返回保存的结果
  3. 若未处理,则执行并与键一同保存结果

5. 先建立评测集

要摆脱「感觉变好了」,需要准备20〜30组输入与期望输出的配对。

  • 从真实的现场数据中挑选有代表性的案例
  • 由人来编写期望输出
  • 每次变更都跑一遍全量,并记录分数

提前做好这件事,在更换模型时判断会轻松得多。

结语

比起华丽的自动化,出错时失败方式足够温和的设计,才能在现场被长期使用。

← ブログ一覧へ戻る ← Back to Blog ← 返回博客列表