学习笔记 · Obsidian
LangChain TypeScript:MCP、多代理、检索与记忆
决策顺序
先问“单 agent + 合理 context engineering 是否已足够”,再选择能力:
- 需要连接外部标准化工具 → MCP;
- 需要私有知识 → loader/splitter/vector store/retriever 或检索工具;
- 需要跨会话偏好/事实 → long-term store;
- 工具太多但任务仍由同一主体完成 → skills 或动态工具选择;
- 确有 context 隔离、并行或责任边界 → multi-agent;
- 流程必须确定性 → custom LangGraph workflow。
多 agent 不是质量开关。它会增加 token、延迟、失败面、状态和观测复杂度;文档的性能示例是特定任务/模型的比较,不应外推成普遍结论。
MCP:TypeScript adapter 的真实语义
客户端使用 @langchain/mcp-adapters 的 MultiServerMCPClient,自建 server 使用 @modelcontextprotocol/sdk。配置可连接多个 server,再把加载出的 tools 交给 agent。
会话与 transport
MultiServerMCPClient默认无状态:每次工具调用新建ClientSession,执行后清理;需要 server-side 会话连续性时不能假设自动保持。stdio适合受控本地子进程。命令、参数、cwd、环境和可执行文件必须允许列表化,不能让模型直接拼 shell。http/streamable-http是远程 server 的现代传输;鉴权 header、TLS、超时、重试、代理和出网策略需要显式配置。- 页面仍保留一个 SSE custom server 示例,但 transport 章节以当前 streamable HTTP 为主。新系统应以当前 MCP specification 和 SDK 版本为准,不因旧示例优先选择 SSE。
错误与内容差异
JS adapter 的关键差异:当 MCP 返回 CallToolResult.isError: true 时,adapter 抛出 ToolException;它不会像 Python adapter 那样自动把失败变成给模型看的 failed ToolMessage。调用者或 wrapToolCall 必须捕获、分类、记录并决定:重试、返回受控工具错误、fallback 或终止。
工具结果可包含 text、image、audio 等多模态 content。必须限制大小、MIME、来源和反序列化,避免把任意远程内容直接渲染到浏览器。
当前 JS MCP 页面重点只覆盖 tools 和 multimodal tool content,没有像 Python 页面那样完整记录 resources、prompts、interceptor 或 stateful-session API。不存在于本页的能力不能据此宣称已由 JS adapter 支持;需查当前 SDK reference。
Multi-agent 五种模式
| 模式 | 控制者 | 上下文隔离 | 适用 |
|---|---|---|---|
| Subagents | 主 agent 调用 specialist tool | 强 | specialist 有复杂独立任务、结果回传 supervisor |
| Handoffs | 当前 agent/状态切换 active agent | 可连续 | 客服分流、用户直接继续与 specialist 对话 |
| Skills | 同一 agent 按需加载知识/流程 | 无新 agent | 工具和知识很多,主要问题是 prompt 膨胀 |
| Router | router 分类后派发一个或多个 worker | 可配置 | 输入可清晰分类、并行 fan-out/fan-in |
| Custom workflow | LangGraph 显式节点/边 | 完全自定义 | 确定性阶段与 agentic 节点混合、复杂状态合并 |
Subagents
主 agent 保留对话历史,subagent 通常每次从新上下文开始,只接收任务描述并返回最终结果。这减少主上下文污染,也便于并行。工具可以“一 specialist 一个工具”,也可以用单一 dispatch tool + enum/registry。
文档的 sync/async 是阻塞委派与后台任务之分,不是 TypeScript 是否使用 async/await:
- synchronous:主 agent 等子任务结束,适合结果立即用于推理;
- asynchronous:提交后台 job,返回 job ID,之后轮询/通知;需要真正的外部 worker/process/service、持久 job state、取消和重试,不是忘记
await。
subagent 输入只给完成任务所需上下文,输出用结构化短摘要/artefact 引用。若共享 checkpointer,需理解 namespace;不要让 specialist 意外读取其他租户 thread。
个人助理教程把 calendar/email 领域委派给 specialists,展示 supervisor 如何保留用户对话、parallel tool calls 和结果整合。它是 pattern 示例,不自带真实 OAuth、权限或幂等保证。
Handoffs
handoff 通常用 Command 更新 active-agent state,并把必要消息传给下一方。单 graph + middleware 的实现较简单,优先于多个 agent subgraph;后者只有在状态、工具或团队边界确需独立时使用。
多个 subgraph 共享消息时,tool-call/result 必须完整成对,否则恢复后模型会收到非法历史。customer support 教程演示分类、转交、active agent 和往返,但生产还需权限、SLA、升级人工、审计和防止无穷转交。
Router
Router 可返回一个 Command 选择单 worker,或用 LangGraph Send 并行派发。无状态 router 适合单次请求;需要对话连续性时,可以把 worker 包为工具或给完整 graph 持久化。并行结果必须定义 reducer、超时、部分失败和输出顺序。
知识库路由教程按数据源把问题发给 GitHub、Notion、Slack 等 specialist,再汇总。真实系统的 connector credentials、ACL 和 source-level citation 必须贯穿检索,不能因为进入同一 agent 就合并权限域。
Skills
Skill 用 progressive disclosure 控制上下文:启动时只暴露 name/description;模型需要时再读 SKILL.md,必要时读取 scripts/references/assets。核心原则是元数据清晰、目录边界稳定、按需加载,不把所有 skill 正文预塞 system prompt。
SQL assistant 教程展示 core skill + 数据库特定 skill + resources,适合把 schema 约定、查询工作流和领域规则分层。Skill 是指导材料而非安全边界;SQL 权限仍由数据库账号、allowlist/parser、limit/timeout 和 HITL 控制。
Custom workflow
显式 graph 可把 retrieval、generation、验证、fallback 和人工节点排成确定流程,同时在个别节点使用 agent。适合严格顺序与可恢复分支;代价是 state/reducer、并行、错误和迁移都由团队负责。
Retrieval 与知识库
语义检索管道:加载 Document → RecursiveCharacterTextSplitter 分块 → embedding → vector store → similarity search/retriever → 把相关片段用于回答。
TypeScript 语义:Document.pageContent 是正文,metadata 保存 source、page、ACL 等,id 可选。知识库教程以 in-memory store 展示流程;生产要评估持久 vector DB、批量写入、embedding 版本、重建、删除传播、租户隔离、metadata filter 和引用。
三种常见 RAG:
- 2-step:每次先检索再生成,延迟和路径可预测;
- agentic:检索作为工具,模型决定是否/如何查,灵活但轨迹不稳定;
- hybrid:确定性 routing/validation + agentic query refinement。
/oss/javascript/langchain/retrieval 当前 308 到 /oss/javascript/deepagents/retrieval,已经跨出 LangChain 栏目。该页仍计入可点击路由,但正文属于 Deep Agents retrieval 视角。页面与 knowledge-base 中可见 dict、as_retriever、Python reference 等模板残留;TypeScript 真实方法应查 JS reference(例如 camelCase)并由编译器验证。
Long-term memory
Store 以 namespace: string[] + key 组织跨 thread 数据,工具通过 runtime.store put/get/search。常见类型:
- semantic memory:用户偏好和事实;
- episodic memory:历史案例;
- procedural memory:长期规则/指令。
写入策略可由用户显式触发,也可由 agent 热路径或后台任务提取。生产必须设计:tenant/user namespace、数据来源、置信度、冲突合并、TTL、删除/导出、embedding 更新和 prompt injection 防护。不要把模型生成的“记忆”直接当权威业务事实。
短期 checkpointer 与长期 store 职责不同:前者恢复一个 thread 的执行 state,后者跨 thread 检索信息。两者都不是应用数据库的替代品。
SQL Agent 的安全底线
教程使用 SQLite 和精简 DB wrapper,明确不是 production-ready。真实部署至少需要:
- 只读或最小权限账号;写操作单独工具与审批;
- 允许 schema/table/statement 类型,禁止任意 DDL/DML;
- 参数化、行数/执行时间/资源限制;
- explain/cost gate、取消、审计和脱敏;
- 数据库错误转换为有限信息,避免泄漏 schema/凭证;
- 对关键查询做 golden/eval,并验证真实数据库版本。
路由闭包与 orphan 边界
/multi-agent(sitemap)和/multi-agent/index(llms)当前都 HTTP 200,正文相同;两条可点击路由均列入 sources,但只学习一次内容。- 可直接访问的
/oss/javascript/langchain/deep-agent-from-scratch是完整 JS 教程,但它不在 llms、sitemap、common-errors 或已抓页面内链中,属于不可点击 orphan。本任务按“每个能点的选项”口径不把它计入覆盖或 sources;若未来进入官方导航,应单独补录。
逐页覆盖
| 页面组 | 学习结论 |
|---|---|
| MCP | JS adapter 包、stateless session、HTTP/stdio、SSE 遗留示例、ToolException 和 multimodal。 |
| Multi-agent overview | 五种 pattern、选择标准、context/tool-call/性能权衡;canonical 与 index 两路同文。 |
| Subagents + personal assistant | supervisor、隔离上下文、同步/后台委派、dispatch tool 和个人助理实例。 |
| Handoffs + customer support | Command、active agent、单 agent middleware 优先、subgraph 消息完整性和客服实例。 |
| Router + knowledge base | Command/Send、无状态/持久 router、并行 fan-out 与多源知识实例。 |
| Skills + SQL assistant | metadata-first progressive disclosure、core/resources 分层与 SQL 领域实例。 |
| Custom workflow | 确定性 LangGraph + agentic nodes 的混合 RAG。 |
| Knowledge base / retrieval | Document、split/embedding/vector/retriever、RAG 类型与跨栏重定向。 |
| Long-term memory | namespace/key、runtime.store、记忆类型与治理。 |
| SQL agent | 自然语言查库 loop、SQLite demo 和生产安全缺口。 |