Where an Agent Touches the World: Seams, Tools, and Policy

DeepSeek Harness crosses from language to external action at a model-facing tool, but the tool is not the whole boundary. This chapter explains how the Harness separates a capability’s definition, provider, and consumer, then follows a tool through schema validation, policy, execution, result handling, and presentation. The practical outcome is a way to decide where a new provider, guard, timeout, approval rule, or UI view belongs—and what that mechanism cannot guarantee.

The distinction becomes visible when the model asks to run a test or edit a file. The request has a meaning for the model, an execution mechanism for the host, a policy for the deployment, a durable result for the Session, and possibly a card for the user. Treating all of those as one function makes changes easy to start and hard to control. DeepSeek Harness makes them separate responsibilities connected by explicit seams.

A seam separates what is stable from what changes

A capability seam in DeepSeek Harness is a complete swappable capability with three roles. The Service Definition owns the stable request and result vocabulary and the context service. A Service Provider implements that capability for a platform, vendor, or execution world. A Consumer uses the definition to expose the capability to an agent or another surface.

The Bash family makes the division concrete. The shell definition describes an execution request and the result of a foreground or background process. A local provider starts a process on the host; a sandboxed provider wraps the same kind of operation under a file-effect policy. The model-facing Bash tool consumes the shell service and turns its outcome into model-facing content. The tool does not need to import the local provider, and the provider does not need to know how the tool’s schema is presented.

The definition is therefore more than a TypeScript interface. It is the runtime service that occupies a stable context key, along with the types and obligations that providers and consumers share. A replacement provider can add meaningful facts—such as whether a sandbox enforced a policy completely—but it cannot silently change the meaning of an exit, timeout, or cancellation result without breaking consumers.

The LLM family follows the same pattern at a different boundary. The provider-neutral LLM service defines messages, content blocks, stream chunks, model metadata, and stable failure categories. The direct DeepSeek adapter translates the official route’s HTTP and streaming behavior. The pi-ai-backed adapter translates a range of provider catalogs and compatible gateways. The Agent loop asks the common service to prepare and stream a call; it does not need to parse each provider’s wire format.

What remains provider-owned is just as important as what is shared. A model’s image capability, reasoning-effort vocabulary, endpoint compatibility, replay metadata, and catalog availability may differ by adapter. The shared service gives those differences a place to be reported. It does not flatten them into a lowest-common-denominator success or promise that every provider can honor every option.

A seam is useful only when the package boundaries match real independent change. DeepSeek Harness’s own extension guidance says not to split a simple one-purpose plugin preemptively. Separate roles when providers, definitions, and consumers need to evolve or be replaced independently. Otherwise the extra boundary adds names and wiring without creating a meaningful choice.

Explicit resolution keeps requests honest

A recurring rule in DeepSeek Harness is to distinguish a caller’s request from the fully resolved specification an executor acts on. A shell request may leave its working directory or timeout unspecified.