AI AGENT 开发 · 从入门到实战 · #10 · 收官

实战收官:从 0 到 1 构建并部署一个多智能体应用

2026-09-17 QBnewb 约 10 分钟读完 约 2900 字
TL;DR
  • 收官项目一句话:给定主题 → 多路检索 → 精读 → 产出带引用的报告——「个人研究助理」,多智能体的最小完整形态。
  • 架构没有新东西:编排者-工作者(第 8 篇)+ ReAct 循环(第 3 篇)+ 工具调用(第 5 篇)+ 记忆(第 7 篇)+ 上下文预算(第 4 篇)——收官就是确认每块拼图都来自哪一篇。
  • 评测不编数字:本系列博客的生产线自身就是这套架构的实证——十篇文章、评审轮次与得分全程留痕,「评测驱动迭代」跑给你看。
  • 部署三条铁律:基础镜像固定版本且运行态最小化;密钥只走环境变量(12-factor);healthcheck 门控依赖,启动期给足宽限。

上篇回顾:上一篇立好了考勤制度——评测与护栏。至此,九篇零件全部到齐。收官篇只做一件事:把它们拧成一台真的能交付价值的多智能体应用,装进容器,部署上线,然后复盘。

一、需求与架构:先说清楚要做什么

收官项目的需求一句话就能说清:用户给定一个研究主题,系统多路检索资料、精读筛选,产出一份带引用的研究报告。这个「个人研究助理」是多智能体的最小完整形态——小到两篇文章能讲完,大到足以复用前九篇的每一块零件。为什么是它,而不是更炫的浏览器操作或客服机器人?回到第 1 篇的判据:「验证反馈越清晰的任务,Agent 越可靠」——这一判据与 Anthropic 强调的「成功标准清晰、结果可验证」一脉相承 [4]——研究报告的验证信号天然清晰:引用可逐条核对、事实可交叉验证、报告可读性用户可以直接反馈。收官选它,是选了一条每一步都能被检验的路。选它还有个私心:LangChain 官方的开源项目 open_deep_research 与它完全同构,学完可以对照一个生产级仓库继续深挖 [3]。

架构在第 8 篇已经画过:一个编排者(Orchestrator)把主题拆成多个检索角度,派出并行的工作者(Worker)各自搜索与精读,结果蒸馏回传,最后由写作角色汇总成带引用的报告,评审角色按第 9 篇的质量清单把关。落实第 9 篇的 BDD 精神,动手前先写三条验收标准:「给定任一主题,报告须包含至少 5 条可核验的引用」「每条引用的 URL 必须真实可达」「报告须注明检索完成日期」。写不出验收标准的需求,就是还没想清楚的需求——这条纪律对收官项目同样生效。落实到模块,每一块都有出处:

模块职责来自哪一篇
任务循环思考-行动-观察、停止条件、错误恢复第 3 篇 ReAct
工具层search、read(研究场景)+ write_report(沿用第 5 篇)+ 确认门控第 5 篇工具调用
上下文预算裁剪旧工具结果、摘要压缩第 4 篇上下文工程
记忆跨会话记住用户偏好与研究历史第 7 篇记忆系统
编排拆解、并行委派、汇总第 8 篇多智能体协作
评测与护栏数据集回放、轨迹断言、三层防线第 9 篇评测与护栏

这张表就是收官的底气:收官篇不引入任何新概念。Anthropic 在自己的多智能体研究系统里也是这么做的——编排、并行子 Agent、引用痕迹、质量评审,全是已知模式的生产级组合 [5]。真正的工程发生在「把它们正确地拼起来」。

二、总装:主程序骨架

项目结构保持朴素——五个文件,每个对应前文一份实现:

research-assistant/
├── agent_loop.py      # 第 3 篇:react() 循环 + 停止条件 + 错误回填
├── tools.py           # 第 5 篇:search/read/write_report 工具 + schema + 确认门控
├── memory.py          # 第 7 篇:MemoryStore(JSON + 关键词检索)
├── orchestrator.py    # 第 8 篇:plan() + 并行 worker + 汇总
├── main.py            # 本篇:入口——组装、注入记忆、落盘报告
└── evals/cases.jsonl  # 第 9 篇:评测集(从真实失败案例长出来)

main.py 负责把零件拧在一起(前文模块以 import 引入,函数签名与各篇一致):

from agent_loop import react_step
from memory import MemoryStore

memory = MemoryStore(f"memory/{__import__('os').environ['USER_ID']}.json")  # 跨用户隔离:一人一文件

def research(topic: str, max_steps: int = 12) -> str:
    """入口:检索编排交给 orchestrator 的思路,单 Agent 版先用 react 走通全链路。"""
    hits = memory.search(topic)                       # 记忆注入:开场先看「以前研究过什么」
    known = "\n".join(f"- {i['content']}" for i in hits) or "(无相关历史)"
    messages = [
        {"role": "system", "content":
            "你是研究助理。流程:先用 search 工具多角度检索,read 工具精读,"
            "最后 write_report 产出带引用的报告。每次先说一句当前判断再行动;"
            "证据不足就继续检索,不要编造引用。" + f"\n\n[历史研究]\n{known}"},
        {"role": "user", "content": f"研究主题:{topic}"},
    ]
    for _ in range(max_steps):                        # 循环:第 3 篇的心脏,原样复用
        result = react_step(messages)                 # react 的单步封装(见 agent_loop.py)
        if result is not None:                        # 无工具调用 = 任务完成,返回最终答复
            return result
    return "已达步数上限,任务未完成。"

# 多智能体版:把 research() 换成第 8 篇的 orchestrate(),
# worker 的 system 换成上面的研究提示——其余一行不改。

if __name__ == "__main__":
    import sys
    topic = sys.argv[1] if len(sys.argv) > 1 else "AI Agent 评测方法 2026"
    print(research(topic))

注意总装的两个原则。第一,单 Agent 版先跑通,再换多智能体版——第 8 篇说「默认答案是别拆」,收官项目也一样:单 Agent 版能产出合格报告,就先上线它;撞到三瓶颈,把 research() 换成 orchestrate(),一行切换。第二,记忆注入保持稳定——「历史研究」段放在 system 尾部、内容按条目时间排序,别让 KV-cache 频繁失效(第 4 篇的账,部署后每天都要付)。另外两条目录纪律也值得写进 README:依赖用 requirements.txt 锁版本,保证容器里跑的就是你测过的组合;memory/ 与 output/ 在部署时挂载为数据卷——容器可以随时销毁重建,用户的记忆与研究产出不能跟着陪葬(第 7 篇的租约条款,在部署层兑现)。部署形态上,上线前补一个十行的 app.py:用 FastAPI 把 research() 包成 HTTP 服务,并提供 /health 探针——下一节 Dockerfile 的启动命令与探测,都指向它。

三、评测与迭代:用真实数据说话

收官项目的评测,直接套第 9 篇的三件套:数据集回放 + 轨迹断言 + 评审循环。而它「评测驱动迭代」的最好实证,恰恰是本系列博客的生产线自己——你正在读的这十篇文章,就是一套多智能体流水线(调研、写作、评审、排版各司其职)按同样纪律生产出来的。看它的真实台账:

  • 十篇文章全部经过「写作 → 评审 → 修订」循环,首轮评审得分 13~15/16 常见,修订后终轮全部 ≥15;评审抓出的典型问题包括:元信息失实(字数标注虚高)、引用错置(把 A 文的话挂到 B 来源)、代码演示不可解(工具集缺枚举能力)、跨篇回指错标——每一类都对应第 9 篇清单里的一项检查;
  • 每一轮评审意见都作为「错误回填」喂给写作者修订,与第 3 篇的循环同构;三轮上限 + 通过线(≥14 且无 0 分)就是停止条件与熔断器;
  • 全部过程留痕在项目仓库的台账与日志里——第 9 篇说「trace 先于评测」,这里连评审意见本身都是可追溯的。

这套对照不是修辞:你能读到十篇完整、可追溯、带评审得分的文章,本身就是「评测驱动迭代」有效的证据。把它搬到你的项目里:评测集先攒十个真实 bad case,跑第一轮回放,修到全绿,再谈上线。还有第二层值得记:每篇的 R1 失分类型(字数失实、引用错置、演示不可解)本身就是一份现成的改进清单——评测数据不应只修「这一篇」,还应修「生产线」:把它们合并进评审清单与作业手册,是这条流水线 v2 的第一件事。

四、部署:三条铁律与一个 Dockerfile

部署 Agent 应用没有黑魔法,但有三条铁律。铁律一:基础镜像固定版本,运行态最小化——基础镜像用官方 slim 变体并锁死版本(生产建议按 digest 锁定),运行态保持最小;Docker 官方 Python 指南还给了两条直接可抄的实践:「构建、运行两阶段,运行态只拷依赖与源码」,以及把 .env 挡在构建上下文之外 [1]。铁律二:密钥只走环境变量——12-factor 的配置原则:配置与代码严格分离,「代码库随时可以开源而不泄露凭据」[2]。铁律三:healthcheck 门控依赖——Agent 应用启动要加载配置、建连接,给足 start_period;slim 镜像没有 curl,探测命令用 Python 一行替代:

# Dockerfile —— 多阶段:构建态装依赖,运行态只拷走 venv 与源码
# 生产建议按 digest 锁定版本
FROM python:3.12-slim AS build
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
COPY --from=build /install /usr/local
COPY . .
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start_period=20s \
  CMD python -c "import urllib.request;urllib.request.urlopen('http://localhost:8000/health')"
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

# docker-compose.yml(节选)—— 密钥运行时注入,绝不烧进镜像层
# services:
#   research-assistant:
#     build: .
#     environment:
#       OPENAI_API_KEY: ${OPENAI_API_KEY}   # 来自宿主机 .env,12-factor Factor III
#       USER_ID: demo
#     ports: ["8000:8000"]

部署后的第一件事,不是庆祝,是跑一遍第 9 篇的八条上线 checklist——冒烟集、回归集、门控、注入检测、输出审查、trace、人工抽检、成本预算,一条一条打勾。上线后第一周,盯三个数:失败率(按会话统计)、单次研究成本(token/会话)、长任务超时率——三个数各配一个「回退阈值」,触线即回滚到上一个镜像 tag。回滚预案在上线当天就要演练一次,等到出事才第一次执行回滚,你练手的那个时机,往往是最糟的时机。

五、踩坑复盘与系列总结

收官的复盘,还是用生产线自己的真实台账。十篇生产中评审抓出频率最高的问题,恰好是 Agent 工程的通用教训:

  • 元信息也会失实(两篇文章字数标注虚高)——元数据要像功能一样断言,不能靠自觉;
  • 引用会错置、链接会死亡(出处张冠李戴、文档迁移后 404)——引用必须程序化核验,关键论断要能逐字溯源;
  • 演示会「看起来可运行」(工具集缺枚举能力、变量未导入)——演示代码必须真跑一遍,注释与代码要同屏 review;
  • 评审循环真能兜底(首轮 13~15 分,终轮全部 ≥15)——回路不是仪式,是质量的本体。

最后,把十篇地图留给你:

#篇目带走的一件事
01从 Chatbot 到 Agent三问定身份:目标、工具、循环
02解剖一个 Agent四大件按需加装,每件都有税
03ReAct 与循环工程完成是目标,预算是底线,熔断是保险丝
04上下文工程上下文是工资单:先分配、再消费
05工具调用实战模型点菜,你的代码下厨;危险操作过人
06MCP 入门M×N 变 M+N;第三方 server 是不可信输入
07记忆系统实战宁可少记不可错记;遗忘是特性
08多智能体协作默认别拆;拆了就要把制度写进 prompt
09评测与护栏评测集从真实失败案例长出来,回放当 CI 跑
10实战收官(本篇)先单 Agent 跑通,再一行切换多智能体

延伸阅读分两层。想继续追生产级实现,只推一个:LangChain 官方的 open_deep_research 仓库 [3](已于 2026-08 归档为只读,仍值得精读)——与本篇同构,读完十篇的你已经完全有能力读懂它,然后超越它。想常备案头的四站官方文档也值得收藏:modelcontextprotocol.io(工具生态)、OpenAI 与 Anthropic 的 SDK 文档(两家官方能力边界)、docs.langchain.com(编排与记忆)——本系列的全部关键论断,最终都溯源到这四个域名的某一页。


系列结语

十篇之前,我们问「AI Agent 到底是什么」;十篇之后,你手里有循环、工具、记忆、上下文预算、编排、评测与护栏,以及把它们拧成一台真机器的完整过程。这个系列本身也是一条 proof:十篇文章由多智能体流水线按「调研 → 写作 → 评审 → 修订」的回路自动生产,全程留痕、可追溯——你刚读完的,既是一套教程,也是一次 loop engineering 的完整实验记录。

系列到这里完结,但 Agent 的故事才刚开始。最好的下一步,不是读第十一篇——是开一个空目录,写下你的第一行 run_agent()。遇到问题,回到对应的那一篇;做出来了,欢迎回来在评论区告诉我。

致谢:本系列的生产线(选题、评审清单、质量台账)本身遵循「AI 协作项目开发方法论」,全套文档与生产日志见本站项目仓库。署名与致谢:QBnewb。

参考来源

  1. Containerize a Python application, Docker Docs, 2026,docs.docker.com
  2. The Twelve-Factor App · III. Config, 2011-2026,12factor.net
  3. Open Deep Research, LangChain, 2025,github.com
  4. Building Effective Agents, Anthropic, 2024-2025,anthropic.com
  5. How we built our multi-agent research system, Anthropic, 2025,anthropic.com
Q
QBnewb
相信「AI 是杠杆」的独立开发者。这个博客由多智能体流水线调研、写作、评审与排版——用 AI 做内容,也是 AI Agent 实战的一部分。