学习笔记 · Obsidian
Managed Deep Agents TypeScript:架构与项目模型
结论先行
Managed Deep Agents(MDA)TypeScript 版与 Python 版使用同一套三层模型:项目中的业务逻辑、Deep Agents harness、LangSmith 托管基础设施。差异主要在工程发现约定和 API:入口是 agent.ts 或 agent.tsx,必须导出命名对象 agent,配置入口是 defineDeepAgent,字段统一使用 camelCase。
当前产品处于 public beta,仅在 LangSmith Cloud 美国区提供。区域、兼容性和 CLI/API 变更都应被视为生产约束,而不是文档脚注。
清单中的 /langsmith/javascript/managed-deep-agents 与 ...-overview 是两个路由,但当前返回相同的概览正文。本笔记保留两个 source,以准确反映官方路由清单;知识层面不重复计算为两项能力。
三层职责
| 层 | 由谁负责 | 典型内容 |
|---|---|---|
| 业务逻辑 | 项目团队 | instructions、tools、skills、middleware 和普通模块 |
| Agent harness | Deep Agents | 规划、文件系统、子代理、上下文管理等通用 agent 能力 |
| 托管基础设施 | LangSmith | Agent Server、sandbox、Context Hub、channels、schedules、evals、部署与可观测性 |
这种分层的工程含义是:agent.ts 是组合根,不应把 prompt、身份、调度和所有业务实现都堆进一个文件;平台能力也不能被误当成业务授权策略。
TypeScript 项目发现约定
my-agent/
├── agent.ts | agent.tsx
├── instructions.md
├── skills/<name>/SKILL.md
├── tools/
├── middleware/
├── channels/<name>.ts
├── connectors/mcp.ts
├── schedules/<name>.ts
├── sandbox/index.ts
├── identity.ts
├── memory.ts
├── package.json
├── .env
└── evals/
关键规则:
- 唯一必需文件是根目录
agent.ts或agent.tsx,项目只允许一个 agent entry。 - 入口必须导出名为
agent的对象,并由defineDeepAgent创建。 - 文档示例使用
.ts;托管声明也接受支持的.tsx、.mts、.cts变体。 instructions.md与skills/**是 managed context,部署时同步到 Context Hub。tools/、middleware/与其他本地模块是普通应用代码,必须由入口显式导入后才参与组合。identity.ts、memory.ts、sandbox/index.ts,以及channels/、connectors/、schedules/的直接子模块属于约定式托管配置。- 依赖在
package.json声明;.env用于本地加载和合格 deployment secrets,但不进入 build archive。 evals/是 Harbor 工作区,不进入 agent 部署产物。
与 Python 的文件差异
| 概念 | TypeScript | Python |
|---|---|---|
| Agent entry | agent.ts / agent.tsx | agent.py |
| Agent factory | defineDeepAgent | define_deep_agent |
| Sandbox | sandbox/index.ts | sandbox/__init__.py |
| MCP connector | 常见为 connectors/mcp.ts | connectors/*.py |
| 依赖清单 | package.json | pyproject.toml |
文件后缀受模块系统影响时,应在本地构建中验证 ESM/CJS 解析,不要只凭源码编辑器能跳转就认定托管编译会成功。
defineDeepAgent 的职责边界
| TypeScript 字段 | 责任 | Python 对应项 |
|---|---|---|
name | Agent、默认 assistant ID 与默认 deployment 名 | name |
model | provider:model 或 LangChain chat model 实例 | model |
tools | 项目 authored tools | tools |
middleware | 模型、工具与生命周期横切行为 | middleware |
subagents | 专用子代理配置 | subagents |
permissions | 内建文件工具的路径访问规则 | permissions |
interruptOn | 敏感工具执行前审批 | interrupt_on |
responseFormat | 结构化输出 schema | response_format |
name 必须是静态字符串,以字母开头,只包含字母、数字、下划线或连字符。CLI 可以通过 mda deploy --name 覆盖 deployment 名,不必修改 agent definition。
系统 prompt、skills、memory、sandbox、identity、channels 和 schedules 都应通过约定文件配置,而不是塞进 defineDeepAgent。
模型与 Gateway
普通模型用 provider:model,例如 openai:...;需要自定义模型参数时,可以传入 LangChain chat model 实例。
LangSmith Gateway 是一个特殊边界:
- 使用
ChatOpenAI并把baseURL指向 Gateway。 - Gateway API key 从
LANGSMITH_GATEWAY_API_KEY读取,不能硬编码。 - Gateway 下的模型 slug 使用
provider/model-name,而不是常规的provider:model-name。 mda init --gateway可按 Gateway 模式初始化项目。
这两个模型标识格式不能混用;配置检查应同时覆盖模型名称、base URL 和 key 来源。
Instructions、Skills、Memory 的职责分离
| 能力 | 加载方式 | Agent 能否改写 | 放什么 |
|---|---|---|---|
| Instructions | 每次运行始终加载 | 否 | 角色、约束、常驻行为与工具原则 |
| Skills | 先看名称/描述,匹配任务后再加载正文 | 否 | 可复用任务流程、脚本、引用和模板 |
| Memory | 显式启用后按热/冷层读取 | 是 | 运行时学习且允许跨线程共享的知识 |
Skill 的 SKILL.md 必须有 name 与 description frontmatter。支持文件只有在 SKILL.md 引用并且任务需要时才应加载,这就是渐进披露的价值。
部署会把 instructions 和每个 UTF-8 skill 文件同步到 Context Hub;后续部署还会移除本地已经删除的远端 skill 文件。Context Hub UI 可以在线更新内容,但项目部署也会再次同步,因此团队必须明确 Git 与 UI 哪一个是长期真源,并在发布前检查并发更新或覆盖风险。
TypeScript 实施原则
- 使用 camelCase 配置,禁止从 Python 示例直接复制
interrupt_on、response_format等字段。 - 保持
agent.ts为组合根,把 Zod schema、工具实现和 middleware 拆到职责目录。 - 对
.mts、.cts或非默认 module resolution,执行真实mda build验证编译与运行时导入。 - 把 instructions 保持短而常驻,把任务型长流程放 skills,减少每次运行的上下文成本。
- 对 public beta 固定并记录包版本,为入口发现、Context Hub 同步和配置 schema 建回归测试。
- 不把 Context Hub 可编辑能力等同于无发布治理;线上 prompt/skill 变更也需要审计、回滚与验证。