第 2 课 · 现代软件开发者(斯坦福 CS146S)
The Anatomy of Coding Agents and MCP
本篇听书与视频
编码智能体的构造:一个循环加几把工具,再到 MCP
第二周拆开编码智能体看内部构造。课上的结论很朴素:不管是 Windsurf、Cursor 还是 Claude Code,核心都是一个循环。客户端把对话交给大模型,模型时不时发出工具调用,由客户端在模型之外执行,再把结果送回去。理解了这个循环,再看 MCP 就很自然:它是一个把工具接给模型的统一标准。
学习目标
- 能画出编码智能体的基本循环,说清模型、客户端和工具各自负责什么。
- 知道一个最小编码智能体需要哪几样工具。
- 理解 MCP 要解决的“M×N 连接器”问题,以及 Host、Client、Server、Tool 四个角色。
- 认识当前智能体在工具多、上下文紧张时的局限。
核心概念
最小智能体的四个步骤。 第一,在终端读取用户输入,持续追加到对话里。第二,在提示词里告诉模型有哪些工具可用。第三,模型在合适的时机发起工具调用。第四,客户端在本地执行工具,把结果交回模型。课上现场从零写了一个,工具只有三把:读文件、列目录、编辑文件(包括新建文件)。这三把工具已经够完成很多真实的编码任务。
成熟产品多做了什么。 讲师总结了 Claude Code 内部的几个做法:开头用一组短小、针对性强的提示词把上下文铺好;在系统提示词、用户消息、工具调用和工具结果里反复插入 <system-reminder> 提醒,防止模型跑偏;在执行命令前提取命令前缀,用于权限判断;派出子智能体分担工作,避免主对话的上下文被撑爆。
为什么需要 MCP。 大模型的知识是静态的,只有重新训练才会更新。天气、币价、你邮箱里的新邮件这类动态数据,只能靠 RAG 和工具调用接进来。如果每个大模型应用都要和每个外部 API 各写一套对接,就会有 M×N 个连接器,每个都要自己处理文档不全、格式不一、鉴权、错误处理和限流。MCP(Model Context Protocol)是 2024 年 11 月推出的开放协议,用统一的方式把工具暴露给模型,把连接器数量从 M×N 降到 M+N。它借鉴了编辑器领域的 LSP,统一使用 JSON-RPC 格式,但比 LSP 更主动,支持智能体自己发起操作。
MCP 的四个角色和一次调用的流程。 Host 是 Cursor、Claude Desktop 这样的宿主应用。Client 是嵌在宿主里的库,和每个 Server 各维持一个有状态的会话。Server 是包在工具外面的轻量封装。Tool 是可以调用的具体函数。一次调用的过程是:Client 向 Server 请求 tools/list,Server 返回每个工具的名称、说明和 JSON Schema,Host 把这些描述放进模型上下文;用户提问后,模型输出结构化的工具调用,Server 执行并返回结果,对话继续。传输层有 stdio 和 SSE 两种。
局限。 课上演示自建的 MCP Server 时发现,工具一多,就得在提示词里明确说用哪个 Server,模型才找得到。主要问题有三个:智能体同时面对很多工具时表现变差;工具描述会快速吃掉上下文窗口;照搬传统 REST API 的设计不适合模型使用,应该按照“AI 原生”的思路重新设计工具。
实践步骤
第二周的作业是“在 AI IDE 里迈出第一步”:用 Cursor 改造一个 FastAPI + SQLite 的小应用,它能把自由格式的笔记转成待办事项清单。
- 用
poetry run uvicorn week2.app.main:app --reload启动起始应用,先熟悉现有的提取功能。 - 读懂
extract.py里基于规则的extract_action_items(),让 Cursor 帮你实现一个基于大模型的版本extract_action_items_llm(),通过 Ollama 输出结构化的 JSON 数组。 - 为新函数补单元测试,覆盖项目符号列表、关键词前缀行、空输入等情况。
- 重构后端:明确 API 契约和 Schema,整理数据库层,理清应用生命周期和配置,完善错误处理。
- 用智能体模式完成两个小功能:新增调用大模型提取的接口和前端按钮,以及“列出全部笔记”的接口和按钮。
- 让 Cursor 读整个代码库,生成 README,内容包括概述、运行方法、接口说明和测试方法。
- 在
writeup.md里记下每一步用的提示词和改动。
常见误区
- 以为智能体有什么神秘内核。 主体就是一个循环加工具调用。各家产品的差别主要在上下文管理、提醒机制和权限控制上。
- 把所有 API 原样包成 MCP 工具。 工具越多、描述越长,上下文就越紧张,模型越容易选错。按模型的使用方式重新设计接口,往往比完整照搬更好用。
- 只盯着模型,忽视执行环境。 工具是在模型之外执行的,执行结果怎么组织后再交回给模型,同样决定了智能体能不能做好。
动手练习
用你熟悉的语言写一个不超过 200 行的终端智能体:只提供读文件、列目录、编辑文件三把工具,接上任意一个支持工具调用的模型 API。让它完成“给某个函数补一个单元测试”这样的任务,记录它一共调用了几次工具、哪一次调用走错了。然后把其中一把工具改成通过 MCP Server 提供,对比两种写法在代码量和调试难度上的差别。
要点回顾
编码智能体等于循环、工具和上下文管理。MCP 把“模型怎么用上外部工具”标准化,代价是工具描述会挤占上下文,所以工具设计本身就是一门功夫。下一周会把这套机制放进 IDE,看规格文档和代码库结构怎样决定智能体能走多远。
参考来源
- CS146S Fall 2025 课程大纲(Week 2):themodernsoftware.dev/fall2025,核验日期:2026-10-23。
- 讲义幻灯片:Building a Coding Agent From Scratch(Google Slides)、To MCP and Beyond(Google Slides)。
- 作业 Week 2 – Action Item Extractor:week2/assignment.md。