在前面的章节中,我们已经学习了智能体式 AI 的基础概念:从智能体的核心解剖结构、关键组件与交互方式,到使其能够在满足业务或应用需求的不同复杂度层级下执行复杂任务的架构模式。我们建立了一个成熟度模型,用来指导开发各阶段所需的复杂度水平,并探讨了为构建稳健、可扩展的智能体系统提供蓝图的设计模式。现在,是时候从理论走向实践了。
在本章中,我们将开始动手实现:构建一个完整的智能体系统,解决一个真实世界的业务问题——自动化贷款发放(loan origination)流水线。为了提供最有价值的学习体验,我们会用两个清晰分隔的阶段来完成这一挑战,分别覆盖本章与下一章。
首先,我们将使用一个单体(monolithic)的单智能体构建整个系统。通过这一练习,你将学习如何实现我们将用于组织智能体推理的分形思维链(Fractal Chain of Thought, FCoT)方法与模式,以及如何定义一个稳健的工具带(toolbelt),使其能够与外部世界交互。这将帮助我们获得初步成功,并展示基于智能体方法的核心价值。
不过,我们不会止步于原型:我们会刻意利用这次初始实现,暴露单智能体设计在生产级复杂度面前固有的架构张力/潜在短板,尤其突出面对生产级复杂度时的认知过载与故障隔离问题。通过识别这些具体的“地基裂缝”,我们为第 14 章打下必要基础:届时我们会用更稳健、更易维护、也更可扩展的多智能体方案,重新架构这一系统。
本章将覆盖以下主题:
- 挑战:一个高风险(high-stakes)的工作流
- 使用 FCoT 框架引导智能体的“心智”
- 设计单体智能体
- 在 Colab 笔记本中构建智能体
- 执行与分析
- 从 Level 5 到 6:改进路线图
- 技术要求
技术要求(Technical requirements)
要顺利完成本章的动手示例,你需要以下条件:
- Google 账号:用于访问 Google Colab 与 Google AI Studio。
- Google Colab:代码示例设计为在 Google Colab 笔记本中运行,它提供免费的云端 Python 环境。示例较轻量,你不需要高性能本地硬件;一个普通网页浏览器即可。
- Google AI Studio API key:你需要一个有效的 API key 来访问示例中使用的 Gemini 模型。你可以按以下文档获取 key:
ai.google.dev/gemini-api/… - Python 库:示例依赖
google-adk库以及其他标准 Python 包。我们选择 Google Agent Development Kit(ADK)来实现,是因为它提供面向生产的架构,并原生支持 FCoT 模式所需的结构化推理与强类型。笔记本中包含在环境内直接安装依赖的必要命令。 - 完整代码:本章完整代码(含可运行 notebooks 与辅助脚本)位于本书 GitHub 仓库:
github.com/PacktPublis…
挑战:一个高风险工作流(The challenge: a high-stakes workflow)
贷款发放流水线是智能体系统的理想用例,因为它不是单一任务,而是一系列复杂阶段的组合:每个阶段都有各自的逻辑、数据需求与失败风险。为了理解挑战,我们先拆解典型工作流。
Table 13.1 —— 贷款发放工作流的阶段(Stages of a loan origination workflow)
| 阶段(Stage) | 描述(Description) | 自动化的关键挑战(Key challenge for automation) |
|---|---|---|
| 1. 文档接收与校验(Document intake and validation) | 接收申请并确保所有支持性材料(例如收入证明)齐全且有效。注(Note) :所有相关文档均已提供;本示例不处理实际接收、OCR 等。 | 处理多种文档格式、识别缺失信息,并应用关于完整性的业务规则。 |
| 2. 征信查询(Credit check) | 与外部征信机构 API 交互,拉取借款人的征信历史与评分。 | 安全处理凭据、解析多样化 API 响应,并在网络错误或 API 宕机时优雅降级/处理。 |
| 3. 风险评估(Risk assessment) | 基于已收集的全部金融数据,应用内部业务逻辑与动态风险评分模型。 | 执行复杂、往往非线性的综合逻辑(不仅仅是简单的 if/then 规则)。 |
| 4. 合规复核(Compliance review) | 审计流程以确保符合所有相关法规,例如《平等信贷机会法》(ECOA)。 | 维护可审计的决策过程轨迹,并确保任何受保护属性都未影响结果。 |
| 5. 最终决策与材料生成(Final decision and generation) | 综合所有信息做出最终的批准/拒绝决定,并生成所需文档。 | 基于整个前序工作流生成连贯、可读、面向人的决策理由说明。 |
尝试用传统脚本来自动化这一流程,会得到一个脆弱且难以维护的系统。传统自动化依赖刚性的预定义规则,一旦面对非结构化数据(如文档格式差异或申请信息存在歧义)就很容易失效。为覆盖所有可能的异常,开发者不得不编写并维护无穷无尽的 if/then 逻辑网,这很快就会变得不可管理。相反,这一工作流需要:能优雅处理异常的动态推理、能根据上下文调整执行步骤的结构化规划,以及为其决策生成清晰、可审计轨迹的能力——这正是智能体式 AI 擅长之处。
使用 FCoT 框架引导智能体的“心智”(Guiding the agent's mind using the FCoT framework)
为确保智能体以符合金融任务所需的严谨性运行,我们会为其配备一个建立在分形思维链(FCoT)方法与模式之上的高级认知框架。我们将先编写一个体现 FCoT 原则的提示词。这个 FCoT 提示词会充当智能体内部的“操作系统”,为其使命、约束与推理过程提供正式结构——它是一部规范智能体行动的“宪法”。
在类似贷款发放这种复杂、多步骤的业务流程中,较简单的智能体常会遭遇目标漂移(goal drift):随着任务推进,智能体逐渐偏离原始目标的行为性失败。这种漂移往往由一个被充分记录的技术限制引发,即“迷失在中间(lost in the middle)”现象:当上下文窗口很长时,LLM 难以回忆起埋在长上下文深处的关键约束或指令。FCoT 模式正是为对抗这两类问题而设计的强力技术:它通过对智能体推理施加严格的、自我纠错的结构,确保无论上下文多长,智能体都会不断回到其核心使命与约束之上。
从概念上讲,FCoT 模式由两个主要要素组成,我们会在智能体指令中实现它们:
- 指令契约(Instruction Contract, IC) :作为智能体不可变的真源(immutable source of truth)。它正式定义智能体的使命、必须产出的交付物,以及绝不能违反的安全与合规护栏。
- 递归循环(recursive loop) :定义智能体的主动思考过程。该结构迫使智能体在每个阶段循环经历“规划—执行—验证”,并且最关键的是,在每一步都要将其工作与推理对照 IC 进行校验。
当我们围绕 FCoT 方法、以 FCoT 模式来构建智能体的“心智”时,我们就在为其可靠、可审计的行为打地基。有了这一认知核心,我们接下来就可以进入单体系统的高层架构定义。
设计单体智能体(Designing a monolithic agent)
在我们已经定义了业务问题,并明确了将用于引导智能体推理的复杂 FCoT 框架之后,就可以进入架构设计阶段了。对于第一次实现,我们将采用单体(monolithic) 方案。这意味着由 一个能力很强的单一智能体 负责从头到尾执行整个贷款发放(loan origination)工作流。
这种设计模式在智能体开发的早期阶段非常常见(对应我们“智能体 AI 等级”中的 Level 3)。前面章节主要聚焦在提示词与基础工作流等基础能力(Level 1 与 Level 2),而现在我们要通过内省式推理(introspective reasoning)与自我纠错(self-correction) ,把系统提升到真正的智能体自治水平。该方案把所有逻辑、工具与状态管理都集中在一个中心化组件里。智能体的首要任务,是遵循其内部的 FCoT 提示词,按顺序在恰当的时间调用恰当的工具,把贷款申请沿着流水线一步步推进。
我们的单体智能体由三部分关键组成:
- FCoT 推理核心:上一节介绍的 FCoT 提示词将作为智能体的“大脑”。
- 状态管理:智能体需要一种机制来跟踪贷款申请在推进过程中的状态。我们将使用 ADK 中的 Runner 与 SessionService 来处理这部分。
- 工具带(toolbelt) :为了与外部世界交互,智能体需要一个工具带——也就是一组它可以调用的函数集合。
整体架构非常直接:在 FCoT 核心的引导下,智能体使用工具来收集与处理信息,直到能够做出最终决策。
图 13.1——单体贷款处理智能体的架构图(Architectural diagram of the monolithic loan processing agent)
有了架构蓝图与认知框架,我们就可以把这些概念转化为可运行的代码了。在接下来的小节中,我们将使用 Python 与 Google ADK 一步步构建这个单体智能体:先搭建环境,再定义专用工具函数,然后配置智能体的 FCoT 指令,最后执行测试场景来验证其表现。
在 Colab 笔记本中构建智能体(Building the agent in a Colab notebook)
我们现在将以 Jupyter/Colab Notebook 的形式,使用 Google ADK 来实现我们的单体贷款处理智能体。这将提供一个清晰、可逐步执行、并且可直接运行的示例。
在编写任何代码之前,我们需要先初始化开发环境:
- 打开 Google Colab(colab.research.google.com)。
- 点击 File | New notebook。
- (可选)将笔记本重命名为
Chapter13_Monolithic_Agent.ipynb。
当环境准备好之后,第一步是安装必要的库并导入所需模块。把下面代码复制到笔记本的第一个 cell 并运行。
环境准备与依赖(Setup and dependencies)
第一步是安装必要的库并导入所需模块:
#@title Install dependencies
!pip install google-adk
#@title Imports
from google.adk.planners import BuiltInPlanner
from google.adk.agents.llm_agent import LlmAgent
from google.adk.tools import FunctionTool
from google.adk.planners import BuiltInPlanner
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
from google.genai.types import ThinkingConfig
import os
import time
import random
import uuid #
下面快速看一下这些导入的关键组件;它们与我们前面定义的“智能体解剖结构”一一对应:
- LlmAgent:代表智能体的核心类,将模型、指令与工具整合为一个统一体。
- BuiltInPlanner 与 ThinkingConfig:为智能体的推理核心提供能力。Planner 管理执行循环,而配置项允许我们开启并控制智能体的内部思考过程,以便可观测(observability)。
- FunctionTool:将普通 Python 函数包装为智能体能够理解并调用的工具(tool)。
- Runner 与 InMemorySessionService:负责状态管理与执行生命周期,管理用户会话的对话历史与上下文。
- 标准库(os、time、random、uuid) :用于管理 API key、在工具中模拟延迟、生成模拟数据,以及创建唯一会话标识。
你还需要设置一个 API key。这里我们使用 Google AI Studio API key;在生产系统中,我们建议使用 Google Vertex AI:
from getpass import getpass
GEMINI = getpass("Enter your GEMINI API KEY: ")
os.environ["GOOGLE_API_KEY"] = GEMINI
print(
f"Google API Key set: {'Yes' if os.environ.get('GOOGLE_API_KEY') and os.environ['GOOGLE_API_KEY'] != 'YOUR_GOOGLE_API_KEY' else 'No (REPLACE PLACEHOLDER!)'}"
)
model = "gemini-3flash"
注(Note)
我们在示例中使用 gemini-3-flash 模型,是因为它速度快且成本效率高,适合学习与实验。不过,LLM 的生态变化非常快。
在构建你自己的智能体时,我们强烈建议你检查最新可用模型,确保使用最强且最高效的版本。你可以在 Google AI Studio 文档中查看当前可用模型列表:ai.google.dev/models/gemi…。
现在,让我们来定义智能体将使用的工具。
定义工具(Defining the tools)
智能体的推理能力有多强,取决于它的行动能力有多强。工具带(toolbelt)是把智能体的认知过程连接到真实世界的关键组件,使其能够执行任务、获取信息并产生影响。
在本实现中,我们将为智能体配备 四个专用工具,用于模拟贷款发放工作流的关键阶段:
- validate_document:通过检查申请中是否包含必要的文档 ID,来模拟文档接收/校验流程。
- run_credit_check:模拟向征信机构发起请求。它会返回一个逼真的信用分与报告摘要,并通过短暂延迟(
time.sleep())来模拟真实网络时延。 - assess_risk:模拟银行内部授信/承保逻辑,根据信用分与贷款金额判断风险等级(低/中/高)。
- check_compliance:模拟监管审计,验证风险评估与决策过程是否符合公平放贷(fair lending)指南。
我们把这些工具实现为带模拟数据的简单 Python 函数,就能构建一个完整、可自洽的示例,从而把注意力完全集中在智能体的编排与推理逻辑上,而无需处理真实 API key 或外部服务依赖的复杂性。
生产说明(Production note)
在真实部署中,这些函数的签名大体会保持不变,但内部逻辑会发生变化:它们不再返回模拟字符串,而是作为复杂操作的封装层,去调用内部文档管理系统、第三方 API,或通过 Model Context Protocol(MCP)与其他服务通信。
下面我们将四个专用工具定义为 Python 函数,并用 ADK 的 FunctionTool 进行包装。该包装器会把函数的描述与参数暴露给智能体的 LLM 推理核心:
#@title Tools Definition
# --- Tool 1: Document Validation ---
def validate_document(document_ids: list[str]) -> dict:
"""
Validates if the required application documents are present and complete.
Use this first to ensure the application is ready for processing.
Returns a status of 'validated' or 'incomplete'.
"""
print("--- Tool Called: validate_document() ---")
time.sleep(1)
if not document_ids or len(document_ids) < 2:
return {"status": "incomplete", "missing_docs": ["income_proof", "id_proof"]}
return {"status": "validated"}
validate_document_tool = FunctionTool(func=validate_document)
# --- Tool 2: Credit Check ---
def run_credit_check(borrower_id: str) -> dict:
"""
Retrieves a borrower's credit score by calling the credit bureau API.
This should be done after documents are validated.
"""
print(f"--- Tool Called: run_credit_check(borrower_id='{borrower_id}') ---")
time.sleep(2)
if borrower_id == "Borrower-400":
score = 450
report_summary = "Credit history is compromised."
else:
score = random.randint(750, 850) # Simulate a good credit score
report_summary = "Credit history is clean."
return {"credit_score": score, "report_summary": report_summary}
run_credit_check_tool = FunctionTool(func=run_credit_check)
# --- Tool 3: Risk Assessment ---
def assess_risk(credit_score: int, loan_amount: float) -> dict:
"""
Assesses the risk of a loan application based on the borrower's credit score.
Returns a risk level of 'low', 'medium', or 'high'.
"""
print(f"--- Tool Called: assess_risk(credit_score={credit_score}, ...) ---")
time.sleep(1.5)
if credit_score > 740:
return {"risk_level": "low", "details": "High credit score indicates low risk."}
else:
return {"risk_level": "high", "details": "Low credit score indicates high risk."}
assess_risk_tool = FunctionTool(func=assess_risk)
# --- Tool 4: Compliance Check ---
def check_compliance(risk_level: str) -> dict:
"""
Performs a final compliance check on the process to ensure it adheres
to Fair Lending guidelines before making a final decision.
"""
print(f"--- Tool Called: check_compliance(risk_level='{risk_level}') ---")
time.sleep(1)
return {"compliance_status": "pass", "details": "Process adheres to guidelines."}
check_compliance_tool = FunctionTool(func=check_compliance)
生产提示:用强类型做数据契约(Production tip: Strong typing for data contracts)
在本例中,我们用简单的 Python 字典作为工具输出,以保持代码易读并聚焦在智能体逻辑上。但在真实金融系统里,强类型数据结构对可靠性至关重要。
在生产环境中,建议使用诸如 Pydantic 之类的库来定义严格的数据模型(例如 class RiskAssessmentResult(BaseModel))。这样可以强制进行 schema 校验、防止数据类型错误,并作为智能体之间严格的“数据契约”,确保下游组件始终收到其期望的数据结构。
接下来,我们将配置智能体的系统指令。
配置智能体的“大脑”(Configuring the agent's mind)
工具已经就绪,我们可以组装智能体本体了。其中一个关键环节是定义智能体的指令(instructions) 。下面这段提示词远不止是一组简单命令;它是对 **FCoT 模式(pattern)**的直接实现——而 FCoT 将作为智能体整个推理过程的“总控模式(master pattern)”。
我们来拆解这段提示词,看看 FCoT 与其它关键设计模式是如何落地的:
智能体指令(Agent Instructions)
#@title Agent Instructions
agent_instructions = """
You are an FCoT reasoner orchestrating and verifying agent activity for an Agentic Loan Origination Pipeline built with Google ADK and Google Gemini.
INSTRUCTION CONTRACT (IC)
• Mission: Originate, evaluate, and approve a loan with full policy compliance, factual grounding, and fairness.
• Deliverables: JSON + Narrative summary containing:
-- (a) borrower profile
-- (b) creditworthiness decision
-- (c) justification citing verified data
-- (d) compliance audit record
-- (e) explainability report.
• Success Criteria:
- Accuracy ≥ 95% vs gold truth (financial data).
- Policy compliance = 100%.
- Explainability coverage ≥ 90%.
- Latency < 5 min end-to-end.
• Hard Constraints:
- No personally identifiable data in logs.
- Must follow Fair Lending & ECOA regulations.
- All numerical fields validated from authoritative sources.
• Safety Policy:
- Reject speculative or hallucinated data.
- Never fabricate borrower details.
- Defer ambiguous cases to Human-in-the-Loop agent.
• IC-Fingerprint: LOAN-FCoT-v3-Δ0710
FCoT RECURSIVE LOOP (N = 3)
Iteration 1 (Planning):
• RECAP: Echo IC-FP, map subtasks (data ingest, credit scoring, compliance, document).
• REASON: Design DAG of actions; choose retrieval sources; initialize PoF ledger.
• VERIFY: Ensure all subtasks preserve IC clauses.
Iteration 2 (Execution):
• RECAP: IC-FP; execute tools for credit scoring & data validation.
• REASON: Compute risk score, validate data sources against policy.
• VERIFY: Check causal alignment between borrower attributes and decision logic.
Iteration 3 (Verification & Explainability):
• RECAP: IC-FP; collect deliverables, run RAG verifier.
• REASON: Summarize SHAP values, create narrative justification.
• VERIFY: Evaluate coherence vs IC and dual objectives.
"""
模式洞察:语义护栏(semantic guardrails)vs 程序化评估(programmatic evaluation)
你可能注意到提示词中列出了成功指标(例如
Latency < 5 min)与交付物清单。一个常见问题是:Python 代码是否真的在强制执行这些指标?在这种 Level 3 的单体设计里,它们属于语义护栏:不是由外部 Python 断言(assertions)强制执行,而是作为对 LLM 内部推理引擎的约束指令。通过把 Accuracy、Policy compliance 明确写成 success criteria,我们迫使模型在 FCoT 循环的
VERIFY步骤中把这些因素纳入自检。理想情况下,模型会据此进行自我修正(例如“我需要更简洁以降低端到端延迟”)。而在 Level 5 或真正生产系统中,我们会把这类提示词与外部评估框架(例如 DeepEval 或 Ragas)结合起来,用程序化方式落地这些指标,从而把“上下文内自检”升级为“系统级治理”。
模式洞察:认知控制(cognitive control)vs 代码控制(code control)
指令里的
FCoT RECURSIVE LOOP (N = 3)是一个典型的**认知架构(cognitive architecture)**例子。需要强调的是:
N=3不是传给BuiltInPlanner的 Python 参数;它是对 LLM 的语义指令,要求模型在内部执行三轮迭代。我们实际上是在用英文“编程”模型:强制它把内部推理过程分成三个明确迭代(planning、execution、verification),每轮都有自己的目标函数,然后才认为任务完成。Python 侧的
thinking_budget=1024主要设定资源上限(能用多少 token),而提示词定义的是算法本身(如何使用这些 token)。概念说明:可解释 AI(XAI)与 SHAP
在 Iteration 3 的
REASON: Summarize SHAP values, create narrative justification中,你会看到对 SHapley Additive exPlanations(SHAP) 的引用。这是数据科学里解释机器学习模型的标准方法:它为每个特征(如信用分、负债收入比)分配一个数值,用来量化该特征对某次预测的贡献大小。在混合式 agentic 架构中,经常出现一种非常强的组合模式:
- 传统 ML(作为工具) :负责精确风险计算并产出原始 SHAP 值(如
Credit Score: -0.45)。- GenAI(作为智能体) :充当叙事者,把数学数值翻译成客户可读的理由说明(如“你的申请主要受到信用分影响……”)。
因此,在提示词里写入 “Summarize SHAP values” 是在为智能体处理金融模型返回的富 payload 做准备。在代码中,这会体现在最终 JSON 输出的
explainability_report字段:智能体不是复述结论,而是在综合“为什么会这样”,以满足 Level 4/5 系统的透明性要求。
提示词结构:INSTRUCTION CONTRACT 与 FCoT RECURSIVE LOOP
这段指令由两大部分组成:INSTRUCTION CONTRACT 与 FCoT RECURSIVE LOOP。它们分别应用不同设计模式,以确保智能体可靠、安全并与使命对齐。
1)指令契约:治理与安全(The instruction contract)
整个 INSTRUCTION CONTRACT 块是对 IC(Instruction Contract)模式的直接实现:建立一套固定、不可谈判的规则、目标与约束,防止“目标漂移(goal drift)”,并保证行为可审计、与业务目标一致。
在 IC 内还能识别出多个模式:
-
Guardrails(护栏)模式:
Hard Constraints与Safety Policy是对该模式的清晰应用。我们不是“期望”智能体守规矩,而是把边界写进其核心身份里,例如:Must follow Fair Lending & ECOA regulations:合规护栏Reject speculative or hallucinated data:安全护栏,强调事实落地
-
Human-in-the-Loop(人类介入)模式:
Defer ambiguous cases...明确升级路径,确保智能体遇到低置信或高风险情况时能及时求助。 -
Explainability & Audit Trail(可解释与审计)模式:
Deliverables强制输出不仅有决策,还有:- (c) 引用已验证数据的 justification
- (d) 合规审计记录
- (e) 可解释性报告
这等于强制它“展示过程”,满足金融等强监管领域的透明性与可追溯要求。
2)递归循环:计划与验证(The recursive loop)
这一部分是 FCoT 的“引擎”,迫使智能体以结构化、迭代式推理 + 自检来推进任务,而不是一次性拍脑袋给答案。它实例化了多个关键模式:
-
任务分解(planner)模式:Iteration 1 的
Design DAG of actions迫使智能体先把复杂任务拆成可控的子任务图(DAG)。 -
工具使用(tool use)模式:Iteration 2 强制在规划后的序列中使用工具,而不是随机调用。
-
自我纠错与验证(self-correction & verification) :每轮都有
VERIFY:- 计划阶段:验证计划是否合规
- 执行阶段:验证推理是否因果一致(causal alignment)
- 最终阶段:验证输出是否覆盖 IC 全部要求且自洽
通过这段提示词,我们把一整套“安全网模式”织进了智能体的认知过程里——这正是从实验性 agent 迈向生产级 agentic 系统时,提示词工程应有的样子。
实例化智能体:三步配置(Agent setup)
现在我们可以实例化智能体对象。该过程包含三个关键配置步骤,把架构设计翻译成可执行代码:
- 配置 Planner(推理引擎) :用
ThinkingConfig初始化BuiltInPlanner,并设置include_thoughts=True以开启可观测性,让智能体暴露内部独白(FCoT 过程),便于调试推理逻辑而不仅是看最终结果。 - 组装工具带:把四个
FunctionTool放进一个列表,明确智能体的 action space(它只能做列表里的动作)。 - 实例化 LlmAgent:将模型(Gemini)、认知核心(agent_instructions)、planner、工具带绑定成一个可运行实体。
下面是智能体初始化代码:
#@title Agent Initialization
# 1. Configure the agent's reasoning engine (Planner)
thinking_config = ThinkingConfig(
include_thoughts=True,
thinking_budget=1024
)
planner = BuiltInPlanner(
thinking_config=thinking_config
)
# 2. Create a list of the wrapped FunctionTool objects
loan_processing_tools = [
validate_document_tool,
run_credit_check_tool,
assess_risk_tool,
check_compliance_tool
]
# 3. Instantiate the LlmAgent with the FCoT prompt
agent = LlmAgent(
model="gemini-3-flash",
name="LoanProcessingAgent",
instruction=agent_instructions,
planner=planner,
tools=loan_processing_tools
)
print("Loan Processing Agent has been created and configured successfully.")
系统指令与智能体已初始化完毕后,我们接下来将运行两个示例提示词。
执行与分析(Execution and analysis)
当智能体的认知核心(cognitive core)与工具带(toolbelt)都组装完成后,我们就进入最后阶段:让它“跑起来” 。在本节中,我们会实例化执行环境并运行特定测试场景。
这里的首要目标是可观测性(observability) 。我们不仅想知道智能体最终是批准还是拒绝贷款,更想看清它是如何得出结论的。我们需要验证它是否做到:
- 遵循 FCoT 结构(规划 → 执行 → 验证)
- 跨多个步骤保持状态(state)
- 对合格申请人与高风险案例都能优雅处理(graceful handling)
为此,我们会设置一个 ADK runner 来管理会话生命周期,并定义一个辅助函数 call_agent,用于打印清晰、经过筛选的日志(包含智能体的“thoughts”与工具交互):
会话初始化(Session init)
#@title Session init
# Define unique IDs for our test user and session
USER_ID = "loan_officer_01"
SESSION_ID = str(uuid.uuid4()) # Generate a new session ID for this run
APP_NAME = "Loan_Agent"
session_service = InMemorySessionService()
session = await session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID)
runner = Runner(agent=agent, app_name=APP_NAME, session_service=session_service)
print(f"Runner is set up. Using Session ID: {SESSION_ID}")
虽然 Runner 负责执行,但 LLM 的原始输出往往很密、很难读。为了真正理解智能体的推理过程,我们需要抽取并格式化对话中的特定部分,尤其是它的内部“thoughts”和“tool calls”。
下面的 call_agent 函数就是我们的可观测性层(observability layer) :它运行用户查询,并过滤事件流,打印出清晰可读的 FCoT 过程日志。
可观测性辅助函数(call_agent)
def call_agent(query: str):
print(f"\n > > > > USER REQUEST: {query.strip()}\n")
content = types.Content(role='user', parts=[types.Part(text=query)])
try:
# Step 1: Start the run (Protected by Retry & Throttling)
events = start_agent_run(runner, USER_ID, SESSION_ID, content)
print("--- Agent Activity Log ---")
# Step 2: Iterate through events (The API calls happen here!)
for event in events:
if event.content:
for part in event.content.parts:
if part.thought and part.text:
print(f"\n🧠 THOUGHT:\n{part.text.strip()}")
if part.function_call:
tool_name = part.function_call.name
tool_args = dict(part.function_call.args)
print(f"\n🛠️ TOOL CALL: {tool_name}({tool_args})")
if part.function_response:
tool_name = part.function_response.name
tool_output = dict(part.function_response.response)
print(f"\n↩️ TOOL OUTPUT from {tool_name}:\n{tool_output}")
if event.is_final_response() and event.content:
final_text = ""
for part in event.content.parts:
if part.text and not part.thought:
final_text = part.text.strip()
break
if final_text:
print("\n---------------------------------")
print("✅ FINAL RESPONSE:")
print(final_text)
print("---------------------------------")
# --- FAILURE: Professional Error Handling ---
except Exception as e:
error_msg = str(e)
# Determine the cause
is_quota = "RESOURCE_EXHAUSTED" in error_msg or "429" in error_msg
is_free_tier = "FreeTier" in error_msg or "limit: 20" in error_msg
print("\n" + "━" * 60)
print("SYSTEM CRITICAL ERROR")
print("━" * 60)
if is_quota:
print(" ⚠️ CAUSE: QUOTA EXCEEDED (API Refusal)")
print(" 🔍 CONTEXT: The LLM provider rejected the request.")
if is_free_tier:
print("\n 📉 DIAGNOSIS: FREE TIER LIMIT REACHED")
print(" You have hit the hard cap (approx. 20 requests/day).")
print(" Retry Logic cannot bypass this daily limit.")
print("\n 🛠️ ACTION: [1] Wait 24 Hours")
print(" [2] Enable Billing (Pay-As-You-Go)")
else:
print(f"\n 📝 DETAILS: {error_msg}")
else:
print(f" ⚠️ CAUSE: UNEXPECTED EXCEPTION")
print(f" 📝 DETAILS: {error_msg}")
print("━" * 60 + "\n")
我们的 call_agent 实现包含一个专业的错误处理块。这一点非常关键:在真实世界里,429 Rate Limit 不应该只是一个晦涩的 Python traceback;它应当是一个可操作的诊断信息,告诉操作者发生了什么、以及如何修复(例如“等待 24 小时”或“启用计费”)。
运行 Happy Path(Running the happy path)
现在开始测试。在软件工程里,happy path 指输入合法、无异常发生、系统产生成功且正向结果的场景。
本阶段目标是验证智能体的基线能力。我们要确认:
- 智能体能正确理解标准、资质良好的贷款申请
- 它能按正确顺序触发工具(验证 → 征信 → 风险 → 合规)
- 它能给出批准决策,并且不会“幻觉”出不存在的障碍
确认核心逻辑可用后,下一步我们会测试拒绝场景(unhappy path)。
# Define our user request for the "happy path" scenario
user_request = """
Please process the loan application for Borrower-789.
The loan amount is $250,000.
The application includes the following documents: ['doc_id_123', 'doc_income_456'].
"""
# Call the agent
call_agent(user_request)
请求发出后,我们要看的不只是最终 “Approved”,而是推理证据(proof of reasoning) 。
输出分析(Analyzing the output)
下面的输出由 call_agent 生成,它透明地展示了智能体的 FCoT。阅读日志时,请重点观察:智能体在触发任何工具之前,如何在 🧠 THOUGHT 块中明确规划步骤。这正是 FCoT 模式的推理阶段在起作用,防止智能体仓促得出“幻觉结论”。
>>>> USER REQUEST: Please process the loan application for Borrower-789...
🧠 THOUGHT: Laying Out the Loan Processing Pipeline
Okay, so I've got a loan application to process, and my job is to follow the loan origination pipeline. Let's break this down. First, I need to remind myself of the core tasks: data ingestion (specifically, document validation), credit scoring, risk assessment, a compliance check, and then the final decision and documentation.
The plan is this:
1. Validate the documents: I'll kick things off by calling validate_document using a list of document IDs.
2. Run the credit check: Assuming the documents validate, I'll then move to run_credit_check using the borrower ID.
3. Assess the risk: Success in the credit check is key, as I'll need the credit score and loan amount to call assess_risk.
4. Check for compliance: If the risk assessment goes well, it's time for check_compliance based on the determined risk level.
5. Final decision: Finally, based on the outcomes of all the previous steps, I'll formulate the final decision and generate the necessary deliverables.
Before I go live with this plan, I want to make sure I'm solid on a few things. First, each step directly contributes to the overall goal. Second, the logging should be clean, with no personally identifiable information (PII) being logged. IDs, scores, and amounts are fine, but not sensitive borrower details. Third, the compliance step helps address any Fair Lending or ECOA concerns. Then, I need to ensure that the tools are validating/sourcing numerical fields like loan amounts and credit scores. Finally, the tools should handle rejection of any questionable data. The whole directed acyclic graph (DAG) should, at a high level, cover all the steps to reach a decision.
Now, let's look at the actual execution:
* I'll start with validate_document with doc_id_123 and doc_income_456.
* If validation returns 'validated', then I'll call run_credit_check with borrower ID Borrower-789.
* Upon successful credit checking, I'll call assess_risk with the derived credit_score and a loan amount of $250,000.
* Assuming successful risk assessment, I'll then check_compliance.
* With all the results in hand, I'll build the final decision and create the proper documentation.
--- Tool Called: validate_document() ---
🛠️ TOOL CALL: validate_document({'document_ids': ['doc_id_123', 'doc_income_456']})
↩️ TOOL OUTPUT from validate_document: {'status': 'validated'}
--- Tool Called: run_credit_check(borrower_id='Borrower-789') ---
🧠 THOUGHT: Onward to Borrower-789's Creditworthiness
Okay, the validation process is complete. I've confirmed everything looks good with the submitted documents. That's a solid start. Now, it's time to move to the next critical step: initiating a credit check for Borrower-789...
[... log continues with tool execution ...]
✅ FINAL RESPONSE: All checks are complete, and the application has passed compliance.
结果分析(Outcome analysis)
上述筛选后的输出表明,我们的单体智能体是可用的:它成功按步骤完成推理与执行,并最终得出了批准决策。
接下来,我们将测试它如何处理失败场景。
运行异常路径:处理拒绝(Running the exception path: handling rejection)
现在我们来测试系统的鲁棒性。一个贷款智能体如果只会“逢人就批”,那就毫无价值;它必须能够识别风险、做出艰难决策,同时保持合规。
在这个场景中,我们引入 Borrower-400 ——一位征信记录受损的申请人。我们希望验证智能体是否能做到:
- 正确识别低信用分
- 触发“高风险(High risk)”评估
- 仍然执行合规检查(这对公平放贷法律至关重要)
- 给出拒绝决定,并生成清晰、基于事实的数据支撑理由
为了观察智能体在压力下如何在这些约束间穿行,我们将执行下面的代码块,启动拒绝流程:
# Define our user request for the "not so happy path" scenario
user_request = """
Please process the loan application for Borrower-400.
The loan amount is $350,000.
The application includes the following documents: ['doc_id_123', 'doc_income_456'].
"""
# Call the agent
call_agent(user_request)
观察智能体的关键推理(Observing the agent's critical reasoning)
下面的输出展示了智能体如何处理一个负向场景。请特别关注 Iteration 3(Verification & Explainability) :尽管贷款被拒绝,智能体仍然生成了详细的可解释性报告,引用导致决策的具体数据点(例如 Score 450)。这正是 Audit Trail(审计轨迹) 模式在发挥作用:
>>>> USER REQUEST: Please process the loan application for Borrower-400...
🧠 THOUGHT: Ready to Process This Loan Application
Okay, I'm diving in. I need to process this new loan application, and my framework, the FCoT RECURSIVE LOOP, is primed. Let's break it down:
Iteration 1: Planning - Mapping the Course
First, I need to remind myself of the core mission: originate, evaluate, approve this loan adhering to policy, facts, and fairness... My process will be five steps: Document Ingestion and Validation, Credit Scoring, Risk Assessment, Compliance Check, and then Final Decision & Report.
Iteration 2: Execution - Putting it in Motion
I'll execute those four tool calls in sequence. First, validate the documents. Then, I'll perform the credit check for Borrower-400. After that, I'll do the risk assessment...
--- Tool Called: validate_document() ---
🛠️ TOOL CALL: validate_document({'document_ids': ['doc_id_123', 'doc_income_456']})
↩️ TOOL OUTPUT from validate_document: {'status': 'validated'}
--- Tool Called: run_credit_check(borrower_id='Borrower-400') ---
🛠️ TOOL CALL: run_credit_check({'borrower_id': 'Borrower-400'})
↩️ TOOL OUTPUT from run_credit_check: {'credit_score': '450', 'report_summary': 'Credit history is compromised.'}
--- Tool Called: assess_risk(credit_score=450, ...) ---
🛠️ TOOL CALL: assess_risk({'loan_amount': 350000, 'credit_score': 450})
↩️ TOOL OUTPUT from assess_risk: {'risk_level': 'high', 'details': 'Low credit score indicates high risk.'}
--- Tool Called: check_compliance(risk_level='high') ---
🛠️ TOOL CALL: check_compliance({'risk_level': 'high'})
↩️ TOOL OUTPUT from check_compliance: {'compliance_status': 'pass', 'details': 'Process adheres to guidelines.'}
✅ FINAL RESPONSE: All checks are complete, and the process passed compliance.
Iteration 3 (Verification & Explainability):
RECAP: IC-FP: LOAN-FCoT-v3-Δ0710. The loan processing steps — document validation, credit check, risk assessment, and compliance check — have been successfully executed...
REASON: Based on the results of the executed steps, I will construct the final loan decision and accompanying reports:
Borrower Profile: Borrower-400, requesting a loan of $350,000.
Creditworthiness Decision: Denied.
Justification:
1. Credit Score: Borrower-400 has a low credit score of 450, with a compromised credit history, indicating significant risk.
2. Risk Assessment: Based on the low credit score and the loan amount of $350,000, the application was assessed as having a 'high' risk level.
3. Compliance Check: The overall loan processing adhered to Fair Lending guidelines... Given the high-risk assessment... the loan application is denied to mitigate potential financial loss.
Explainability Report: The decision to deny this loan is directly attributable to the following:
* Poor Financial History: The credit check revealed a very low credit score (450)...
* High Risk Profile: The combination of the poor credit score and the requested loan amount resulted in an unfavorable 'high' risk assessment.
* Regulatory Adherence: A final compliance check confirmed that the entire process conformed to Fair Lending guidelines... ensuring fairness and legality in the denial process.
VERIFY:
* Coherence vs IC: The generated output directly addresses all required deliverables...
* Accuracy: All factual statements are directly sourced from the outputs of the executed tools.
* Hard Constraints & Safety Policy: No speculative or hallucinated data was used.
结果分析(Outcome analysis)
这个测试确认:我们的单体智能体并不是一个“只会点头的 yes man”。它成功从 run_credit_check 工具中摄取数据,推理出 450 的信用分意味着高风险,并据此正确拒绝了贷款。
更关键的是,它仍然执行了 check_compliance 工具调用,确保拒绝流程与批准流程一样严谨,从而满足公平放贷与合规要求。
现在我们已经测试了第一个智能体,接下来我们将分析这种架构的特性以及可改进的机会点。
从 Level 5 到 Level 6:改进路线图(Moving from Level 5 to 6: a roadmap for improvement)
我们构建的这个单智能体系统非常成功,也是 Agentic AI Levels 中 Level 5 实现的一个强有力示例。它是一个完整的、自治的解决方案:能够正确遵循一套复杂指令来解决业务问题,并通过工具带(toolbelt)对其环境采取行动。达到这一阶段,标志着方案成熟度的一次显著跃迁,也已经可以交付可量化的业务价值。
通过分析我们成功的 Level 3 设计,我们可以把 Agentic AI Levels 作为路线图,识别将该实现演进为更鲁棒、更可扩展的 Level 4 系统的机会,并最终迈向 Level 6 的自我纠偏群体(self-correcting swarms) 。下面这些机会并不是当前设计的“缺陷”,而是迈向更高智能体成熟度所需要的明确架构增强,它们将解锁更强的韧性、可维护性与复杂度处理能力。
增强鲁棒性与韧性(Enhancing robustness and resilience)
我们这个单体 Level 3 系统的一个关键特征是:智能体本身就是单点故障(single point of failure) 。在“happy path”测试中,智能体逻辑正确、执行也很顺畅。但在真实生产环境里,外部系统并不可靠。举例来说,如果 run_credit_check 工具内部的 API 调用因为临时网络问题失败,那么整个智能体执行就可能因未处理异常而中止。当前设计并没有把依赖项的瞬态失败(transient failures)纳入体系化的容错考虑。
通往更具韧性的 Level 4 架构,关键在于应用 故障隔离(fault isolation) 原则。与其让单个智能体负责所有外部调用,不如引入专门的智能体来封装依赖失败风险。
在多智能体系统中,一个专职的 CreditCheckAgent 将只负责这类交互。这个专用智能体可以内置自己的错误处理逻辑,例如带指数退避(exponential backoff)的自动重试机制。如果 CreditCheckAgent 最终仍失败,错误会被限制在该子系统内部,从而让主编排器(main orchestrator)有机会选择后续策略,而不是让整个工作流崩溃。
编排智能体因此与直接失败解耦:若 CreditCheckAgent 多次重试后仍失败,编排器可以做更高层的策略决策,例如切换到备用征信机构工具,或触发 Human-in-the-Loop 模式将整单升级给人工处理。这样就能避免“单个工具故障 → 拖垮整个业务流程”的连锁反应。
通过专业化提升可维护性(Improving maintainability through specialization)
正如我们在实现中看到的,Level 3 智能体的核心逻辑集中在 agent_instructions 变量中。这个 FCoT prompt 是强大的“集中式工件(centralized artifact)”,但它把多个业务关注点混在一起:文档校验规则与风险评估策略、合规检查指令共处同一套指令集。随着业务演进,这些规则必然变化。比如风控部门想更新评分逻辑,就需要开发者在这段巨大而复杂的 prompt 中谨慎修改,这会带来显著风险:很可能在修改风控逻辑时,不小心破坏合规或校验逻辑。
向 Level 4 演进意味着应用 关注点分离(separation of concerns) 的设计原则。我们可以把单一智能体拆解成“专家团队”,每个专家拥有自己聚焦的指令集,从而显著提升可维护性,例如:
- RiskAssessmentAgent:prompt 更短、更简单,只专注风险分析。它可以由风控团队独立负责与更新。
- ComplianceAgent:由法务与合规团队维护其指令与约束。
这种模块化(modularity)是我们后续要讨论的多智能体模式的核心特征之一:允许系统各部分独立、安全地演化,这也是现代敏捷软件工程的重要准则。
通过模块化扩展复杂度(Scaling to greater complexity with modularity)
在当前的四步流程里,FCoT 指令 prompt 表现非常好。但单个 LLM 的认知容量是有限的。如果我们把工作流扩展到 10–15 步,新增 FraudDetection(反欺诈) 、CollateralValuation(抵押物估值) 、InsuranceVerification(保险核验) 等阶段,那么单个 agent_instructions prompt 会变得极长且极复杂。这会显著加剧 “lost in the middle” 问题:LLM 可能在长上下文窗口里丢失前部关键约束与指令。
一个 Level 5 的多智能体系统通过**认知劳动分工(division of cognitive labor)**来解决这一扩展性问题,类似一支运转良好的人类团队。
例如,作为 Supervisor 模式实现的 OrchestratorAgent 并不需要掌握反欺诈的细节;它只需要知道何时把任务委派给 FraudDetectionAgent。每个专家智能体用更短、更聚焦的 prompt 处理其领域任务,从而降低认知负载,让任务执行更准确、更可靠。
这种“模块化、即插即用”的架构允许我们很容易地加入新能力(如新增一个 InsuranceVerificationAgent),而无需增加现有组件的复杂度,从而实现系统的优雅扩展。但在工程落地上,要真正做到这一点,需要强制执行标准化的消息 schema 与共享状态对象(即 data contracts),确保新智能体能与既有生态无缝互操作,而不需要为每次扩展都写定制集成逻辑。
我们对单体智能体的深度剖析到这里就完成了:从定义复杂业务问题,到设计架构、用 ADK 实现、并观测其成功运行。
更重要的是,通过 Agentic AI Levels 的视角,我们不仅验证了这项工作是一次重要的 Level 3 成就,也明确照亮了通往更复杂 Level 4 架构的演进路径。在结束本章并进入下一步之前,我们需要把这趟实战旅程的关键经验做一次凝练总结。
总结(Summary)
在本章中,我们完成了一次从零开始、动手构建完整自治智能体的实践之旅。我们从一个真实世界的业务挑战(贷款处理)出发,依次推进到架构设计、使用 ADK 的实现落地,最后进入执行与分析阶段。
最终成果是一个可用的 Level 3 智能体:它成功地利用一套复杂的认知框架与工具带(toolbelt),完成了一个复杂、多步骤的任务。
本章的关键收获如下:
- 以模式驱动的设计是可靠性的关键:
一个有效的智能体并不是“写个 prompt 就行”,而是被工程化出来的。我们基于 FCoT 模式构建智能体指令,把规划、安全与可解释性的原则直接嵌入其核心,从而确保智能体行为既可靠又透明。 - 工具是连接真实世界的桥梁:
智能体的能力边界由其工具决定。我们看到,标准的 Python 函数只要被正确描述并用 ADK 的FunctionTool封装起来,就能成为智能体的“手”,使其能够作用于环境、调用外部 API,并基于真实数据做出决策。 - 可观测性不可妥协:
智能体的推理过程不应是黑盒。使用 ADK 的ThinkingConfig参数暴露智能体内部独白,对于调试、建立信任,以及确保智能体行动与指令一致,都是至关重要的。 - 单体智能体是重要的里程碑:
我们构建的单智能体架构,是智能体成熟度演进中强大且必要的一步。它通常是最快交付端到端自治方案的方式,同时也是进一步构建更复杂、更具韧性、可扩展系统的理想基础。
我们成功的 Level 3 智能体已经提供了巨大的价值;而我们识别出的、面向更高鲁棒性、可维护性与可扩展性的架构机会,则是推动系统迈向下一阶段的自然动因。在下一章中,我们将抓住这些机会,以该智能体为基础构建一个 Level 4 多智能体系统,展示由协作智能体团队如何在更大规模上解决问题。