AIエージェント組み込みアプリの設計思想:ValuScopeに学ぶ「自動化しすぎない」境界設計

AIエージェントを業務アプリへ組み込む際に、何を自動化し、どこで人に判断を戻すべきか。VC向けValuScopeの実装と開発履歴から、責任境界・状態機械・機密分離の設計原則を学ぶ。

12th July 2026
AIエージェントと人間の承認を分離した業務アプリの設計図

AIエージェント組み込みアプリの設計思想:ValuScopeに学ぶ「自動化しすぎない」境界設計

バージョン注記: 2026年7月12日時点の

valuscope-next
の仕様、ソースコード、Git履歴(2026年4月18日〜7月12日、94コミット、266追跡ファイル)を確認して執筆しています。未公開の運用実績を推測せず、実装から確認できる設計と、今後測定すべき効果を分けて扱います。

私はCVCで投資案件を進めるなかで、AIに期待するほど「誰が最後に決めたのか」が曖昧になる怖さも感じてきました。ValuScopeを作って一番考えたのはモデルの賢さではなく、AIをどこで止め、人に判断を返すかです。

TL;DR:この記事でわかること

最初に、設計の結論を短く置きます。

テーマValuScopeで採った考え方
AIの役割調査・整理・提案・成果物生成まで。投資判断そのものは代行しない
人の役割出力を確認し、承認・却下・再実行を選ぶ
自動化の単位1体の万能AIではなく、責務が異なる6種類のエージェント
状態管理実行状態と判断状態を別モデルで記録する
機密境界Web検索用の公開情報と、資料・ファンド情報を使う内部分析を分離する
連鎖実行承認されたときだけ、前方のステージへ進み、次工程を起動する

これは派手な「完全自動投資AI」ではありません。しかし実務では、この控えめさが信頼性の土台になると私は見ています。


出発点はチャットではなく業務の状態だった

AIアプリというと、まずチャット画面を作りたくなります。私も最初はそうでしたが、投資実務を分解すると、中心にあるのは会話ではなく状態です。

ValuScopeが扱うディールは

SOURCED → SCREENING → DD → IC → CLOSED / MONITORING / PASSED
と進みます。その途中で必要な仕事も、Web調査、ピッチ資料分析、面談準備、DD質問、投資委員会付議と変わります。そこで現行実装は、次の6種類へ責務を分けています。

エージェント主な入力主な出力人が見るポイント
Pipeline ToDo全ディールの状態優先順位付きToDoいま誰が何を確認すべきか
Web Research公開企業情報出典付き調査自称と第三者情報が分かれているか
Deck Analysis保存資料投資仮説・不足情報資料にない推測が混ざっていないか
Meeting Agenda資料・履歴面談論点と質問前進/見送りの判別に効くか
Question List資料・面談メモDD質問20〜30問回答で判断がどう変わるか
IC Proposal資料・参考情報付議骨子リスク、反証条件、未確認事項

ここでの発見は、エージェントの定義がモデル名ではなく、業務上の責務、入力範囲、成果物、次の判断で決まることです。モデルは交換できますが、責務の境界が曖昧だと、どれほど高性能なモデルでも仕事がにじみます。

開発履歴にもこの順序が表れています。2026年4月19日の初期アプリはポートフォリオ、バリュエーション、資料分析が中心でした。5月31日にディール詳細とAIサブエージェント、6月4日にファンド情報と類似企業調査、7月12日に受信箱と承認フローが大きく統合されています。つまり、先に業務データと計算基盤があり、その後にAI、最後に人間との制御面が追加されました。私はこの順番が重要だったと思います。


「実行」と「判断」を別の状態機械にする

最も効いた設計は、AIジョブが成功したことと、人が内容を承認したことを同じ

status
に押し込まなかった点です。

ValuScopeには、AIの処理記録である

DealAgentRun
と、人の判断単位である
ActionItem
があります。前者は
GENERATING / SUCCEEDED / FAILED
、後者は
RUNNING / AWAITING_REVIEW / APPROVED / REJECTED / FAILED / SUPERSEDED / DISMISSED
を持ちます。

状態の種類答える問い代表的な状態
実行状態AI処理は技術的に完了したか
GENERATING
,
SUCCEEDED
,
FAILED
判断状態人は成果物をどう扱ったか
AWAITING_REVIEW
,
APPROVED
,
REJECTED
系譜状態古い依頼との関係は何か
SUPERSEDED

AIが正常に文章を返しても、その内容が投資判断に使えるとは限りません。逆に、内容が却下されてもジョブ自体は正常終了しています。この二つを分けないと、障害分析と業務監査の両方が壊れます。

承認後の遷移も、プロンプトの文章ではなく純粋関数として固定しています。要点を抜き出すと次の形です。

type Plan = {
  proposedStatus: 'SCREENING' | 'DD' | 'IC' | null;
  nextAgentTypes: string[];
};

function nextOnApprove(
  agentType: string,
  currentStage: string,
  hasDocs: boolean
): Plan {
  const plan =
    agentType === 'WEB_RESEARCH'
      ? {
          proposedStatus: 'SCREENING' as const,
          nextAgentTypes: hasDocs ? ['DECK_ANALYSIS'] : ['MEETING_AGENDA'],
        }
      : agentType === 'DECK_ANALYSIS' || agentType === 'MEETING_AGENDA'
        ? { proposedStatus: 'DD' as const, nextAgentTypes: ['QUESTION_LIST'] }
        : agentType === 'QUESTION_LIST'
          ? { proposedStatus: 'IC' as const, nextAgentTypes: ['IC_PROPOSAL'] }
          : { proposedStatus: null, nextAgentTypes: [] };

  return isForwardStage(currentStage, plan.proposedStatus)
    ? plan
    : { ...plan, proposedStatus: null };
}

このコードが守るのは二つです。第一に、AI出力だけで勝手に次へ進まないこと。第二に、承認してもステージを後退させないことです。投資実務では例外もありますが、例外を通常フローへ混ぜず、手動判断として扱う方が履歴を読みやすくできます。


AIは提案するが、データを直接書き換えない

チャットAIにも同じ思想を適用しています。ユーザーが「A社のステージをDDにして」と頼んだとき、AIが直接DBを更新するのではなく、変更提案を構造化データで返します。UIは現在値と新しい値を差分表示し、利用者が選択した項目だけを適用します。

ここで面白かったのは、Human-in-the-loopを「確認ダイアログを1枚出すこと」と考えると足りない点です。確認時点から適用時点までに、別のメンバーが値を変えるかもしれません。そのため適用処理はDBの現在値を取り直し、提案時の

currentValue
と一致しない項目を競合としてスキップします。

設計上の責任分解は次のようになります。

  1. AIは編集可能なホワイトリスト内で変更案を作る。
  2. JSON Schemaで出力形を固定する。
  3. UIが現在値と新値を見せる。
  4. 人が適用対象を選ぶ。
  5. サーバーが認証、型、enum、必須項目を再検証する。
  6. DB最新値との競合がない項目だけ更新する。

AIの自由度を下げる設計に見えますが、私は逆だと考えています。書き込み権限を狭くするほど、ユーザーは安心してAIへ広い相談を投げられます。


Web検索と内部資料を同じ文脈へ入れない

機密性の設計では、暗号化だけでなく「何を外へ送るか」の境界が重要です。ValuScopeの

WEB_RESEARCH
はWeb検索を使う一方、保存資料やファンドプロファイルを入力にしません。ほかの資料分析系エージェントは保存資料やファンド方針を参照しますが、Web検索を使いません。

この分離には明確な意味があります。

経路利用する情報外部ツール主なリスク
公開情報調査企業名、Webサイト、業界、公開説明Web search + OpenAI API検索語への機密混入
内部資料分析ピッチ資料、面談メモ、ファンド方針OpenAI API提供権限、保持方針、個人情報
決定・更新承認結果、ステージ、履歴AppSync / DB誤更新、競合、権限越境

UIでも

web-search
confidential-provider
automation
の3リスクを分け、実行前に送信範囲を確認させています。OpenAI APIのデータはデフォルトで学習に使われない一方、保持やZero Data Retentionの適格性はエンドポイントや機能で異なります。「学習されない」だけを見て機密設計を終えるべきではありません。

私自身、クロスボーダー案件で資料共有範囲の確認に何度も時間を使いました。面倒に見える確認こそ、後から説明できるプロダクトにするための機能です。


設計思想を5つの原則へ落とす

ここまでを、別の業務アプリにも持ち込める原則へまとめます。

原則実装上の問い
Agent as proposerAIは提案しているか、それとも不可逆操作を直接実行しているか
State before chat会話履歴より先に、業務状態と遷移が定義されているか
Separate run and decision技術的成功と業務的承認を別々に追跡できるか
Context minimizationエージェントごとに必要最小限の情報だけ渡しているか
Approval-gated chaining次工程の自動起動に人の承認が入っているか

全部を人が確認する設計は、規模が大きくなるとボトルネックになります。だから将来の自動承認を否定する必要はありません。ただし、先に判断状態を記録できる構造を作り、低リスク・高信頼の処理だけを段階的に自動化する方が安全です。ValuScopeの

AUTO_APPROVED
が前方互換としてスキーマに残されているのは、その余地を示していますが、現行Web版は自動承認を生成しません。


落とし穴:思想だけでは守れない

設計思想が正しくても、実装の継ぎ目で破れます。今回コードを追って、特に注意したい点は四つありました。

  • ベストエフォートの連鎖: 承認記録は成功しても次エージェントの起動が失敗する可能性があります。再送キュー、アラート、補償処理が必要です。
  • クライアント側の承認処理: 現行のステージ更新と次工程起動はReact hookが担います。将来はサーバー側コマンドへ寄せ、原子的な監査を強める余地があります。
  • 認可の粒度:
    authenticated read
    と組織分離は同義ではありません。アプリ側のMembership確認だけでなく、データモデルの認可境界を継続監査すべきです。
  • プロンプトとポリシーの混同: 「機密を検索語へ入れない」とプロンプトに書くことは補助策です。入力フィルタ、経路分離、ログ監査も必要です。

AWS Lambdaの非同期実行は重複配信が起こり得るため、公式資料も冪等性を求めています。ValuScopeには

sourceKey
SUPERSEDED
の系譜がありますが、外部副作用まで含めた冪等性は今後も検証対象です。


まとめ:エージェント設計は権限設計である

私には、AIエージェントを組み込む設計は、プロンプト設計より権限設計に近く見えます。誰が、どの情報を読み、どの状態まで提案し、どの操作だけを人が承認するか。そこが決まれば、モデルやUIは交換できます。

ValuScopeの開発履歴は、計算・資料・ディール管理という業務基盤の上にAIを載せ、最後に受信箱と承認フローを足した流れでした。最初から完全自動化を狙わなかったからこそ、6種類のエージェントを一つの業務状態へ接続できたのだと思います。

次編では、この思想をNext.js Route Handler、Amplify Data、Lambda worker、TanStack Queryのポーリングへどう落としたかを、実装単位で分解します。

参考資料


次号の記事案

  • 案1:AIエージェントの評価基盤を作る — 承認率、再実行率、競合率、ステージ滞留時間をイベントとして記録し、プロンプト改善と業務改善を分離して評価します。
  • 案2:SQSとDLQでエージェント実行を堅牢化する — fire-and-forgetのFunction URLをキュー駆動へ移し、重複、再試行、失敗イベント回収を実装します。
  • 案3:組織境界を強める認可設計 — Amplifyのowner認可とorganization membershipをどう組み合わせ、マルチテナントの読み書きを検証するかを掘り下げます。

本記事は情報提供を目的としており、特定の銘柄・サービス・投資行動を推奨するものではありません。執筆には生成AIを利用し、ソースコードと公式資料をもとに内容を確認しています。詳細は免責事項をご覧ください。


Designing Agentic Apps: Human-Controlled Automation Lessons from ValuScope

Version note: This article reflects the

valuscope-next
specification, source code, and Git history as of July 12, 2026. The reviewed history spans April 18 through July 12, with 94 commits and 266 tracked files. I separate what the implementation demonstrably does from outcomes that still require production measurement.

Working on CVC deals has made me optimistic about AI and cautious about blurred accountability at the same time. The hardest ValuScope design question was not which model to use. It was where the agent must stop and return control to a person.

TL;DR: What You'll Learn

Here is the design in compact form.

ThemeValuScope's choice
Agent roleResearch, organize, propose, and generate artifacts; do not make the investment decision
Human roleReview output and approve, reject, or rerun it
Automation unitSix bounded agents instead of one universal assistant
State modelTrack execution state separately from decision state
Confidentiality boundarySeparate public web research from internal document and fund-context analysis
ChainingAdvance stages and launch the next agent only after approval

This is not a dramatic autonomous-investing system. In practice, I think that restraint is the foundation of trust.


Start With Workflow State, Not a Chat Window

The obvious first screen for an AI application is chat. I was tempted by that too. Once I decomposed the investment workflow, however, the center of the product was clearly state rather than conversation.

A ValuScope deal moves through

SOURCED → SCREENING → DD → IC → CLOSED / MONITORING / PASSED
. The required work changes along the way: public research, deck analysis, meeting preparation, diligence questions, and an investment-committee draft. The current implementation therefore assigns six bounded responsibilities.

AgentPrimary inputPrimary outputHuman review question
Pipeline ToDoAll active dealsPrioritized actionsWho should verify what now?
Web ResearchPublic company dataSourced researchAre company claims separated from third-party evidence?
Deck AnalysisStored documentsThesis and missing informationDid the agent invent anything absent from the deck?
Meeting AgendaDocuments and historyIssues and questionsWill answers distinguish advance from pass?
Question ListDocuments and notes20–30 diligence questionsHow would each answer change the decision?
IC ProposalDocuments and referencesCommittee memo outlineAre risks, falsifiers, and unknowns explicit?

The key insight is that an agent is defined by its business responsibility, input boundary, artifact, and next decision, not by its model name. Models are replaceable. Blurred responsibilities remain blurred even after a model upgrade.

The Git history reinforces this sequence. The April 19 application centered on portfolio management, valuation, and document analysis. Deal sub-agents appeared on May 31. Fund context and comparable research followed on June 4. The inbox and approval workflow were integrated in July. Business data and calculations came first, agents came next, and the human control plane came last. In hindsight, that ordering mattered.


Use Separate State Machines for Execution and Judgment

The strongest design choice was refusing to compress “the job returned successfully” and “a person approved the result” into one status field.

ValuScope has a

DealAgentRun
for processing history and an
ActionItem
for a human decision. The former moves through
GENERATING / SUCCEEDED / FAILED
; the latter uses
RUNNING / AWAITING_REVIEW / APPROVED / REJECTED / FAILED / SUPERSEDED / DISMISSED
.

State familyQuestion answeredRepresentative states
ExecutionDid the technical process finish?
GENERATING
,
SUCCEEDED
,
FAILED
DecisionWhat did a person do with the artifact?
AWAITING_REVIEW
,
APPROVED
,
REJECTED
LineageHow does this request relate to an older one?
SUPERSEDED

A model can return valid text that is unusable for an investment decision. A reviewer can reject that text even though the job itself completed normally. Combining those facts damages both incident analysis and auditability.

Approval transitions are also encoded as a deterministic function, not buried in prompt prose. The essential shape is below.

type Plan = {
  proposedStatus: 'SCREENING' | 'DD' | 'IC' | null;
  nextAgentTypes: string[];
};

function nextOnApprove(
  agentType: string,
  currentStage: string,
  hasDocs: boolean
): Plan {
  const plan =
    agentType === 'WEB_RESEARCH'
      ? {
          proposedStatus: 'SCREENING' as const,
          nextAgentTypes: hasDocs ? ['DECK_ANALYSIS'] : ['MEETING_AGENDA'],
        }
      : agentType === 'DECK_ANALYSIS' || agentType === 'MEETING_AGENDA'
        ? { proposedStatus: 'DD' as const, nextAgentTypes: ['QUESTION_LIST'] }
        : agentType === 'QUESTION_LIST'
          ? { proposedStatus: 'IC' as const, nextAgentTypes: ['IC_PROPOSAL'] }
          : { proposedStatus: null, nextAgentTypes: [] };

  return isForwardStage(currentStage, plan.proposedStatus)
    ? plan
    : { ...plan, proposedStatus: null };
}

This function protects two boundaries. An agent result cannot advance a deal by itself, and approval cannot move the workflow backward. Real investment processes do contain exceptions, but treating an exception as an explicit manual decision produces a cleaner history than mixing it into the default path.


Let the Agent Propose Changes, Not Write Them Directly

The chat feature follows the same philosophy. When a user asks to move a company to DD, the model does not update the database. It returns a structured proposal. The interface displays old and new values, and the user selects which fields to apply.

I initially thought a confirmation modal would be enough for a human-in-the-loop system. It is not. Another team member may modify a record between proposal generation and approval. ValuScope therefore reloads the current database value and skips any field whose value no longer matches the proposal's

currentValue
.

The responsibilities are deliberately layered:

  1. The model proposes changes only for whitelisted fields.
  2. JSON Schema constrains the output shape.
  3. The UI displays current and proposed values.
  4. A person selects fields to apply.
  5. The server revalidates authentication, types, enums, and required fields.
  6. Only conflict-free updates reach the database.

This appears to reduce the agent's freedom. I see the opposite effect: narrow write authority makes users more comfortable giving the assistant broad analytical tasks.


Do Not Put Web Search and Internal Documents in One Context

Confidentiality is not only an encryption question. It is also a routing question. ValuScope's

WEB_RESEARCH
uses web search but does not receive stored deal documents or the fund profile. Document-oriented agents can receive documents and fund strategy, but do not use web search.

That separation creates three distinct paths.

PathInformation usedExternal toolPrimary risk
Public researchCompany name, site, industry, public descriptionWeb search + OpenAI APIConfidential data leaking into a query
Internal analysisDecks, meeting notes, fund strategyOpenAI APISharing authority, retention, personal data
Decision and updateApproval, stage, historyAppSync / databaseIncorrect writes, conflicts, authorization gaps

The UI also distinguishes

web-search
,
confidential-provider
, and
automation
risks and asks for confirmation before execution. OpenAI states that API data is not used for training by default, but retention and Zero Data Retention eligibility differ by endpoint and feature. “Not used for training” is not a complete confidentiality design.

Cross-border projects taught me how much time can disappear into document-sharing decisions. That friction is not accidental overhead. Productizing it makes later explanations possible.


Turn the Philosophy Into Five Design Principles

The ValuScope choices generalize into five questions that apply to other operational applications.

PrincipleImplementation question
Agent as proposerIs the model proposing an action or directly performing an irreversible operation?
State before chatAre workflow states and transitions defined before conversational behavior?
Separate run and decisionCan technical success and business approval be inspected independently?
Context minimizationDoes each agent receive only the information required for its role?
Approval-gated chainingDoes a person approve before the next automated step begins?

Reviewing every output will eventually become a bottleneck. That does not make future auto-approval wrong. A safer sequence is to build decision-state tracking first, collect evidence, and automate only low-risk, high-confidence cases. ValuScope retains

AUTO_APPROVED
in the schema for forward compatibility, while the current web application does not generate that state.


Gotchas: Philosophy Does Not Enforce Itself

Good principles still fail at implementation seams. Four issues stood out during the code review.

  • Best-effort chaining: approval can be recorded even if the next-agent dispatch fails. A durable queue, alert, and compensation path would make this stronger.
  • Client-side approval orchestration: the current stage update and next-step dispatch live in a React hook. A server-side command could provide tighter transactional auditing.
  • Authorization granularity:
    authenticated read
    does not automatically equal tenant isolation. Membership checks and model authorization need continuous testing together.
  • Prompt-policy confusion: telling a model not to put secrets in search queries is only one layer. Input filtering, path separation, and log review are also required.

AWS documents that asynchronous Lambda invocations may be delivered more than once and recommends idempotent handling. ValuScope has

sourceKey
and
SUPERSEDED
lineage, but idempotency across every external side effect remains an area to verify.


Conclusion: Agent Design Is Permission Design

Agent application architecture increasingly looks like permission architecture to me. Who can read which context, propose which transition, and perform which operation after whose approval? Once those boundaries are explicit, models and interfaces can evolve without redefining accountability.

ValuScope's history moved from calculations, documents, and deal management to agents, then to an inbox and approval flow. Avoiding full autonomy at the start made it possible to connect six agents to one understandable workflow.

Part two decomposes how this philosophy maps onto Next.js Route Handlers, Amplify Data, a Lambda worker, and TanStack Query polling. Part three covers the operating procedure and a measurement framework for actual effects.

References


Next Issue Ideas

  • Idea 1: Build an evaluation layer for operational agents — Capture approval rate, rerun rate, conflict rate, and stage dwell time so prompt quality and process quality can be evaluated separately.
  • Idea 2: Harden agent execution with SQS and a DLQ — Replace Function URL fire-and-forget dispatch with a durable queue and implement duplicate handling, retries, and failed-event recovery.
  • Idea 3: Strengthen organization-level authorization — Test how Amplify owner authorization and organization membership should combine in a multi-tenant application.

This article is for informational purposes only and does not recommend any security, product, investment, or securities action. Generative AI assisted the writing, and the content was checked against source code and official documentation. See the disclaimer for details.

Sponsored affiliate banner