Skip to content

🏁 9.13 综合实战:AI 智能数码选购与避坑决策 Agent(全链路融会贯通) ​

“学了十二节零件课,今天整机下线——真正的工程能力,不是认得每个零件,而是把它们装配成一台能跑、能扛、能卖的机器。”
本节是第九章的收官之战:我们把 9.1~9.12 装进工具箱的全部零件——统一模型 I/O、LCEL 管道、结构化输出、自定义工具、记忆管理、Callbacks 审计、RAG 检索、create_agent 架构、上下文工程、自定义中间件、生产级护栏——一次性总装成一个完整的生产级项目:SmartBuyer(AI 智能数码选购与避坑决策参谋)。

🚀 项目已独立"长大":SmartBuyer 现在拥有自己的项目目录 code/smart_buyer/(核心 Agent、独立 Gradio 工作台、测试与演进路线)。本节保留教学 walkthrough(讲清"每个零件装在哪、为什么"),完整代码、运行方式与后续演进计划(deepagents 深度版 / MCP 工具生态 / 多用户生产化)请进项目主页查看。


💡 先看一个直观例子:装机佬的整机组装 ​

1. 为什么最后一定要有综合实战? ​

学会零件 ≠ 会装机。前面十二节里,每一节都单独点亮了一块技能:可你会不会有种感觉——“每块都懂,但拼在一起就手忙脚乱”?这太正常了:单点知识是零件,工程能力是总装。真实企业项目从来不是“只用一个中间件”,而是十几个零件协同运转:护栏挡在门口、中间件盯着流水线、上下文工程递剧本、记忆管着抽屉、Callbacks 记着账——任何一环掉链子,整机就是废铁。

2. 生活比喻:攒一台旗舰整机 ​

把 SmartBuyer 想成一位装机佬攒出来的旗舰主机,每个硬件都对应前面学过的一节:

电脑硬件对应章节在 SmartBuyer 里是什么
🧠 CPU(大脑)9.1 统一模型 I/Oget_chat_model_primary() 一行换模型,业务代码零改动
🔌 主板(总装骨架)9.9 create_agent所有零件插在它上面,1.4 标准架构
⚙️ 散热与供电(稳压器)9.11 自定义中间件日志、调用限流、自动重试三件套
🛡️ 机箱侧板(防尘防静电)9.12 生产级护栏黑名单拦截 + PII 脱敏,纵深防御
🗂️ 内存与硬盘(记忆)9.6 记忆管理Checkpointer 线程记忆 + Store 长期顾客画像
💽 固态硬盘里的资料库9.8 RAG内置数码避坑宝典(Chroma 向量知识库)
🖱️ 外设(手脚)9.5 自定义工具差评搜索 / 性价比测算 / 避坑检索三大 @tool
📺 机箱灯效与仪表9.7 CallbacksToken 成本审计回调,黑匣子账单
🎛️ 开机前的 BIOS 设置9.10 上下文工程@dynamic_prompt 按人、按场景动态定稿"剧本"
📋 出厂质检报告9.4 结构化输出Pydantic《选购决策与避坑报告》
🔗 机箱内部排线9.3 LCELprompt | structured_llm 管道符编排

SmartBuyer 全链路架构:护栏层 → 上下文工程层 → 智能体中枢 → 工具生态 → 双模输出


🧩 融会贯通全景图:12 节知识点的落点对照 ​

先看总装清单——每一节学的东西,在整机里都有明确的位置,一个都不浪费:

章节零件名称在 SmartBuyer 中的落点
9.1 统一模型 I/O万能转换插头get_chat_model_primary() 工厂接入,换模型不改业务
9.3 LCEL 管道自动化传送带prompt | structured_llm 一根管道生成报表
9.4 结构化输出海关标准报关单ShoppingDecisionReport 强类型选购决策矩阵
9.5 自定义工具瑞士军刀卡槽3 个 @tool:差评搜索、性价比测算、避坑宝典
9.6 记忆管理抽屉 + 剪报员Checkpointer(thread_id 短期)+ Store(跨会话画像)
9.7 Callbacks航班黑匣子PerformanceAndCostCallback Token 成本自动审计
9.8 RAG 检索智能图书索引员langchain-chroma 内置避坑知识库,零配置开箱即用
9.9 create_agent高级私人秘书整机总装骨架,Tool Calling 自主推理
9.10 上下文工程导演的剧本调度@dynamic_prompt 三数据源动态注入系统提示
9.11 自定义中间件流水线质检员日志 + 调用限流 + 自动重试,三钩子协同
9.12 生产级护栏安检门与安检员黑名单 before_agent 拦截 + PII 输入脱敏

🔑 一句话读懂整机:用户诉求先过护栏安检(9.12)→ 中间件记录与限流(9.11)→ 动态提示词按画像定稿剧本(9.10)→ create_agent 中枢自主推理调用工具(9.9 + 9.5 + 9.8)→ 输出结构化决策报告(9.4),全程 Callbacks 记账、Checkpointer 记忆(9.7 + 9.6)。


💻 核心实操:整机总装四步曲 ​

完整可运行脚本见 code/smart_buyer/main.py,全部零件均可单独溯源到对应章节。

第 1 步:备料——模型、工具与知识库(9.1 + 9.5 + 9.8) ​

python
# smart_buyer/main.py —— 备料三件套
from s01_model_io import get_chat_model_primary          # 【9.1】统一模型工厂
from s07_callbacks_and_tracing import PerformanceAndCostCallback  # 【9.7】Token 审计

@tool
def search_product_reviews_and_complaints(query_keyword: str) -> str:
    """全网实时搜索指定数码产品的真实用户评测、真实差评与翻车吐槽。"""   # 【9.5】Docstring = 工具说明书
    ...  # ddgs 联网搜索,失败时优雅降级为模拟数据

@tool
def calculate_specs_and_budget(formula: str) -> str:
    """精确计算价格优惠幅度、每元性能比与预算剩余额度(严禁心算)。"""
    ...

@tool
def query_hardware_traps(category_or_term: str) -> str:
    """查询内置数码硬件避坑宝典,识别偷工减料与营销话术陷阱。"""
    ...  # 【9.8】GLOBAL_BUYER_KB.as_retriever() Chroma 向量检索

第 2 步:装"大脑与剧本"——动态上下文工程(9.10) ​

这是本次总装的灵魂升级:老版实战写死 System Prompt,新版让系统提示活起来——每次模型调用前,从三数据源现场拼装:

python
# smart_buyer/main.py —— @dynamic_prompt 三数据源动态注入
@dynamic_prompt
def smart_buyer_dynamic_prompt(request: ModelRequest) -> str:
    # 1) Runtime Context:本次请求的固定配置(不传时优雅降级为游客画像)
    ctx = request.runtime.context
    user_id = getattr(ctx, "user_id", None) if ctx else None
    system = SMART_BUYER_BASE_PROMPT              # 基础人设:使命 + 三大工具 + 工作原则

    # 2) Store 长期画像:这位顾客"是谁",决定参谋怎么说话
    if user_id and request.runtime.store is not None:
        prefs = request.runtime.store.get(("buyers",), user_id)
        if prefs:
            system += f"\n\n【顾客画像】沟通风格:{prefs.value['communication_style']}..."

    # 3) State 短期感知:聊了很久就自动"长话短说"
    if len(request.messages) > 10:
        system += "\n\n【会话提示】这是一段较长的咨询,请尽量简洁直接地给出结论。"
    return system

💡 融会贯通点:Store 里预置了两位顾客画像——user-veteran(极简直接)与 user-rookie(手把手科普)。同一个问题,参谋对老手甩参数表、对新手讲避坑故事——这就是"同一个模型,千人千面"的上下文工程。

第 3 步:插上"神经、韧带与安检门"——中间件与护栏(9.11 + 9.12) ​

python
# smart_buyer/main.py —— 整机总装:create_agent + 三层中间件纵深栈
self.agent = create_agent(
    model=self.llm,                                       # 【9.1】CPU
    tools=self.tools,                                     # 【9.5】外设
    middleware=[
        # 第 1 层【9.12】护栏:黑名单命中直接收尾,连模型都不调
        ContentFilterMiddleware(banned_keywords=["hack", "exploit", "malware", "刷单"]),
        # 第 2 层【9.11】治理:日志 / 调用超 10 次熔断 / 失败自动重试 3 次
        LoggingMiddleware(),
        CallCounterMiddleware(),
        retry_model,
        # 第 3 层【9.10】上下文工程:动态系统提示(放在最内层,最后定稿"剧本")
        smart_buyer_dynamic_prompt,
    ],
    checkpointer=self.checkpointer,   # 【9.6】thread_id 自动隔离多轮会话记忆
    store=self.store,                 # 【9.6】跨会话长期顾客画像
    context_schema=BuyerContext,      # 【9.10】声明运行期上下文 Schema
)

🔑 装配顺序有讲究:中间件列表由外到内执行——护栏放最外层(把坏请求挡在一切开销之前),动态提示词放最内层(等日志、限流、重试都就绪后,最后定稿递给模型的剧本)。这个"安检门在外、导演在内"的排布,正是 9.12 纵深防御 + 9.10 上下文工程的组合拳。

第 4 步:点火试车——多轮问诊与结构化报表(9.6 + 9.7 + 9.3 + 9.4) ​

python
# smart_buyer/main.py —— 双模输出:交互问诊 + 一键报表
def chat_recommend(self, user_query, session_id="default_shopper", user_id=None):
    callback = PerformanceAndCostCallback()                      # 【9.7】黑匣子账单
    invoke_kwargs = {"config": {"configurable": {"thread_id": session_id},   # 【9.6】会话记忆
                                "callbacks": [callback]}}
    if user_id:
        invoke_kwargs["context"] = BuyerContext(user_id=user_id) # 【9.10】运行期上下文
    response = self.agent.invoke({"messages": [("user", user_query)]}, **invoke_kwargs)
    ...  # 从 messages 流水线还原工具调用链(9.9 的审计姿势)

def generate_structured_report(self, user_demand):
    structured_llm = self.llm.with_structured_output(ShoppingDecisionReport)  # 【9.4】报关单
    chain = prompt | structured_llm                              # 【9.3】LCEL 管道
    return chain.invoke({"demand": user_demand})

🧪 出厂质检:整机的确定性自测 ​

整机不是装完就走,出厂前要过质检(呼应 9.12 的测试纪律):

  1. 护栏断言(零 API 依赖,可进 CI):复用 9.12 的 content_filter_check / pii_redact 纯函数断言——黑名单命中即收尾、邮箱自动脱敏;
  2. 端到端冒烟测试:uv run python -m smart_buyer.main 跑一次完整问诊 + 报表生成,核对 Token 账单与工具调用链是否完整;
  3. 回归基线:把"预算 5000 买轻薄本"等固定用例做成评估集,每次改 Prompt 都跑一遍回归;云端 Trace 与评估平台(LangSmith / Langfuse)暂不接入,如有需求后续单独成节介绍。

🖥️ 运行方式 ​

🚀 完整运行方式、目录结构与已完成的演进路线见项目主页:code/smart_buyer/。快速体验:

bash
cd 09_LangChain搭建Agent/code
uv sync                                          # 首次安装依赖
uv run python -m smart_buyer.main               # 课程版:整机点火试车(在 code/ 目录下运行)
uv run python -m smart_buyer.web_app            # 独立 Web 工作台:问诊 + 工具链 + 结构化报告(7861)
uv run python -m smart_buyer.deep_agent         # 深度版:三子代理协作(Phase 2,真实 API)
uv run pytest smart_buyer/tests/ -v             # 质量测试:19 项护栏/回归/持久化断言(零 API)

Web 工作台怎么读 ​

web_app.py 把同一套 Agent 搬进一个更适合演示和调试的页面:左侧是可延续上下文的问诊 对话,右侧的“过程透视”会把实际触发的工具、参数和返回摘要列出来;下方“决策报告”把 ShoppingDecisionReport 渲染成推荐卡片、避坑清单和最终结论,同时保留 Pydantic 校验后的 JSON。它不另写一套业务逻辑,所以前端看到的护栏、RAG、MCP 和成本统计与 CLI 一致。

页面启动阶段不会创建模型,首次咨询时才读取 .env 并初始化 Agent。没有配置 API Key 时 仍可打开页面检查布局;真正调用失败会在对话和过程透视中提示需要补充的配置。完整的环境变量、 端口和验收清单见 code/smart_buyer/README.md。

🚀 项目独立后的"长大"成果(Phase 1~4 全部落地) ​

SmartBuyer 独立成项目后按四阶段演进(详见项目 README),已全部完成:

Phase成果用到的课程零件
1 质量加固19 项测试全绿:黑名单护栏断言(含大小写绕过、eval 代码注入拦截)、固定用例回归、SqliteSaver 会话记忆落盘(跨进程重启记忆仍在)9.12 测试纪律 / 9.6 Checkpointer
2 deepagents 深度版三个专项子代理(差评侦察/参数测算/避坑审核)经 task() 派单协作,真实 API 试跑产出四份报告(/reports/final_report.md 等)写入虚拟文件系统9.9 deepagents 五件套
3 MCP 工具生态1.4 MCPAdapter 一键接入 MCP 服务器(三档缓存),ProviderToolSearch 延迟挂载 + LLMToolSelector 分诊(工具多时自动启用)9.1 MCP / 9.7 中间件
4 多用户生产化/memories/<user_id>/ 按 StoreBackend namespace 隔离沉淀顾客档案;FilesystemPermission 最小权限网;TracePolicy 链路打码 + LangSmith 零代码观测9.6 Store / 9.11 TracePolicy

💡 教学价值:这个"从课堂 demo 到独立项目"的演进过程本身就是一个完整的学习样本——每个 Phase 都只用了课程里教过的零件,没有引入任何新框架。

🔁 业务闭环(Phase 3 深化):项目现已内置一个 MCP 演示服务器(mcp_server.py:历史价格/官方参数/以旧换新/物流时效/售后政策 5 把工具), 与本地三大 @tool 合并装配进同一个 Agent(8 把工具同层调度),真实咨询中模型会自主组合调用—— 例如"以旧换新"场景:查历史价格 → 估价旧机 → 核对官方参数 → RAG 避坑 → 测算器算出真实入手成本。


📚 权威官方资料直达 ​


上线前的验收清单 ​

这个项目能生成推荐报告,还不能直接等同于可上线服务。至少还要验证:搜索失败时不会编造价格;旧资料会标明日期;不同用户的偏好与会话相互隔离;高风险链接和提示注入会被拦截;结构化输出失败能够恢复;每条关键结论都能追到来源。

还应准备一组固定问题,覆盖预算冲突、信息不足、用户临时改需求和多个来源互相矛盾等情况。记录答案质量、引用正确率、耗时与人工返工量。只有这些结果稳定,才能进一步考虑缓存、并发和部署。

🎯 全章收官:十三步,从管道到整机 ​

  1. 核心收获:本节把 9.1~9.12 的全部零件总装成 SmartBuyer——护栏挡在门外、中间件守住流水线、上下文工程千人千面、工具与 RAG 让参谋有据可依、结构化报表让决策可交付、Callbacks 与测试让整机可审计、可回归。至此你完成的不是"又一个 Demo",而是一个零件可溯源、层级可解释、安全可验证的生产级 Agent。
  2. 全章回顾:从 9.1 一次 invoke() 调用,到 LCEL 管道编排、工具生态、记忆裁剪、Callbacks 审计、RAG 增强,再到 create_agent 现代架构、上下文工程、自定义中间件与生产级护栏——十三步走完,你已经具备用工业级框架交付智能体系统的完整能力。
  3. 下一站:第九章之后,LangGraph 将带你在多智能体编排的维度上继续进阶——但请记住本章的整机思维:零件易学,总装见真章。愿你在下一次"攒机"中,装出属于自己的旗舰 Agent!🚀