工作区契约

runtime 会递归加载 config/ 下的 YAML。文件名只是组织手段,真正的语义来自对象的 kindmetadataspec。这样既能保持结构灵活,又能维持稳定的发现规则。

config/
  workspace.yaml
  agent-context.md
  catalogs/
  agents/

YAML 原则

  • YAML 负责表达装配、策略和可复用命名对象。
  • 不要在 YAML 里再造一层 harness 私有语义去覆盖上游概念。
  • 集合配置尽量保持 Kubernetes 风格:apiVersion、复数 kindspec: []
  • 单例运行时配置用带 metadataspec 的单文档表达。

不要语义重影

YAML 的职责是把系统装出来,不是把 LangChain 或 DeepAgents 再换一套说法重新讲一遍。

workspace.yaml:只放 runtime 级配置

workspace.yaml 当成运行时单例配置。它应该承载 routing、recovery、concurrency、maintenance 和 runtime defaults,而不是 agent 私有行为或 prompt 细节。

tool module discovery policy 也应该放在这里。需要保留 YAML catalog 的递归发现、但把本地 resources/tools/ 模块发现限制成每个工具根目录下一层文件时,就在这里声明。

apiVersion: agent-harness/v1alpha1
kind: Workspace
metadata:
  name: default
spec:
  runtime:
    runtimeRoot: ./.agent
    defaults:
      governance:
        toolPolicy: default
    recovery:
      resumeResumingRequestsOnStartup: true
    maintenance:
      enabled: true
    concurrency:
      maxConcurrentRuns: 4
    toolModuleDiscovery:
      scope: top-level
  routing:
    defaultAgent: orchestra
该放这里

默认路由、并发策略、维护任务、恢复策略、tool module discovery policy、运行时默认治理。

不该放这里

agent prompt 片段、backend 私有调参、瞬时运行状态。

Catalog 文件怎么分

catalog 最重要的是“职责单一”。每个文件都应该回答得很清楚:它到底在给哪一类可复用对象命名。

models.yaml

命名 chat model preset。先有一个默认模型,再有一个清晰 fallback 就够了。

apiVersion: agent-harness/v1alpha1
kind: Models
spec:
  - metadata:
      name: model/default
    provider: openai
    model: gpt-5.4
    temperature: 0.2

  - metadata:
      name: model/fallback
    provider: anthropic
    model: claude-sonnet-4-5

embedding-models.yaml

给 vector recall 和 embedding 相关组件命名 embedding preset。

apiVersion: agent-harness/v1alpha1
kind: EmbeddingModels
spec:
  - metadata:
      name: embedding/default
    provider: openai
    model: text-embedding-3-large

stores.yaml

管理结构化持久化和 checkpoint 恢复。store 和 checkpointer 要分开写,不要糊成一个概念。

apiVersion: agent-harness/v1alpha1
kind: Stores
spec:
  - metadata:
      name: store/default
    kind: Store
    storeKind: SqliteStore
    url: ./.agent/runtime.db

  - metadata:
      name: checkpointer/default
    kind: Checkpointer
    storeKind: SqliteCheckpointer
    url: ./.agent/runtime.db

vector-stores.yaml

负责语义召回和 embedding-backed lookup。它不是 canonical durable store 的别名。

apiVersion: agent-harness/v1alpha1
kind: VectorStores
spec:
  - metadata:
      name: vector/default
    storeKind: LibSQLVectorStore
    url: ./.agent/runtime.db
    table: memory_embeddings
    embeddingModelRef: embedding/default

backends.yaml

只做 backend preset 命名,不要在这里堆 adapter 细枝末节。

apiVersion: agent-harness/v1alpha1
kind: Backends
spec:
  - metadata:
      name: backend/deepagent-default
    backend: deepagent

  - metadata:
      name: backend/langchain-default
    backend: langchain-v1

tools.yaml

给工具资源命名。真正的工具实现依然应该放在 resources/tools/

apiVersion: agent-harness/v1alpha1
kind: Tools
spec:
  - metadata:
      name: tool/write-file
    source: local
    toolName: write_file

mcp.yaml

给 MCP server 命名,把共享远程能力面集中表达出来。

apiVersion: agent-harness/v1alpha1
kind: McpServers
spec:
  - kind: McpServer
    id: awesome-github-mcp
    name: awesome-mcp/github-mcp
    description: GitHub 工作流与仓库操作的 MCP server
    repositoryUrl: https://github.com/modelcontextprotocol/servers
    transport: stdio
    command: npx
    args:
      - -y
      - "@modelcontextprotocol/server-github"
    env:
      GITHUB_TOKEN: CHANGE_ME

id 是 runtime 真正使用的主标识。像 transportcommandargsurlenvcwdtokenheaders 这些字段会参与运行时装配;而 namedescriptionrepositoryUrl 更适合作为 catalog 元数据。

catalog 里放的是 server preset。真正接到 agent 上时,应该在 spec.mcpServers 里用对象形态做引用;每个 agent 的工具筛选和 transport 覆盖也应该写在这里,而不是回头改共享 catalog。

Agent 定义

Agent 是唯一的一等产品配置对象。subagent 只是通过 spec.subagents 被另一个 agent 引用的 agent,不应该被包装成另一套“角色类型系统”。

apiVersion: agent-harness/v1alpha1
kind: Agent
metadata:
  name: orchestra
spec:
  backend: deepagent
  modelRef: model/default
  runtime:
    runtimeRoot: ./.agent

落到实际项目里,至少应该准备两类示例:一个 direct-response agent,一个能调 subagents 的 orchestration agent。

apiVersion: agent-harness/v1alpha1
kind: Agent
metadata:
  name: direct
spec:
  backend: langchain-v1
  modelRef: model/default
  runtime:
    runtimeRoot: ./.agent
  tools:
    - tool/write-file
  skills: []
  mcpServers: []
  subagents: []

---
apiVersion: agent-harness/v1alpha1
kind: Agent
metadata:
  name: orchestra
spec:
  backend: deepagent
  modelRef: model/default
  runtime:
    runtimeRoot: ./.agent
  tools:
    - tool/write-file
  skills:
    - repo-review
  mcpServers:
    - ref: mcp/awesome-github-mcp
      toolFilters:
        - "^issue_"
  subagents:
    - direct

Catalog 与复用对象

catalog 文档让团队能给模型、embedding models、stores、vector stores、tools、MCP servers 和 backends 命名并复用。运行时会把这些命名对象解析进最终的 agent binding。

Models

提供命名的 chat model preset。

Stores / checkpointers

负责持久化和恢复的底座配置。

Tools

让 agent 能按名字白名单选择能力。

MCP servers

承载更重、更共享的远程能力面。

装配流程

  1. 加载工作区中的 YAML 对象。
  2. 发现本地 resources/tools/resources/skills/
  3. 解析 catalog 引用,生成编译后的 agent bindings。
  4. 叠加运行时默认策略、持久化、恢复与治理配置。
  5. 向应用暴露稳定的运行时接口。

常见误区

把 store、checkpointer、vector store 混为一谈

结构化持久化、恢复和语义召回彼此有关,但绝不是同一个对象。

把实现写进 catalog

catalog 负责命名资源;工具实现仍应进 resources/tools/,应用代码仍应进 src/

workspace.yaml 写成大杂烩

它应该承载 runtime policy,而不是另一份 agent prompt 或 backend 调参清单。

在 YAML 里重新发明私有语义

如果上游已有原语,就应该直接映射,而不是重新命名一遍。

YAML 不该承载什么

不要把瞬时运行状态、checkpoint 内部结构或应用私有 view model 放进 YAML。YAML 是装配面,不是临时数据存储层。