Configuration

June 9, 2026 · View on GitHub

This document describes the config files under configs/ for deployment and troubleshooting:

First-run config path

For local onboarding, prefer guides/quickstart.md. It creates a temporary embedded config and registers an external_http agent there.

Agent definitions must be present in the active runtime config loaded by the process. The standalone configs/agents.yaml file is a reference for available fields, not the current quickstart entrypoint.

Minimal shape:

agents:
  agents:
    customer_support_bot:
      type: "external_http"
      description: "Existing customer support agent"
      external:
        url: "http://localhost:9000/invoke"
        timeout: "120s"

For API-only embedded mode, add the block to the API config. For split API/Worker deployments, keep the same agent definition available to both the API and Worker configs so the API can accept /api/agents/:id/message and the Worker can execute the job.

api.yaml

api

FieldDescription
portHTTP listen port, default 8080
hostListen address, default "0.0.0.0"
timeoutRequest timeout
cors.enable / allow_originsCORS toggle and allowed origins
middleware.authEnable auth
middleware.rate_limit / rate_limit_rpsRate limit toggle and RPS
middleware.jwt_key / jwt_timeout / jwt_max_refreshJWT (when auth is true); prefer ${JWT_SECRET} env for jwt_key
forensics.experimentalWhether to expose experimental forensics, evidence graph, audit log, compliance, and AI-forensics endpoints (/api/forensics/*, /api/jobs/:id/evidence-graph, /api/jobs/:id/audit-log, /api/compliance/*)

See forensics read model for the query schema and release drill. | grpc.enable / port | gRPC toggle and port, default 9090 |

jobstore

Task event storage (event stream + lease).

FieldDescription
typememory or postgres
dsnConnection string; use env JOBSTORE_DSN to override for Postgres
lease_durationLease duration; Heartbeat interval should be < lease_duration/2

Important: When jobstore.type=postgres, only Worker processes execute via event Claim; the API does not start an in-process Scheduler (single execution ownership). With memory, the API starts the Scheduler and runs jobs.

runtime production gates

When runtime.profile: "prod" or runtime.strict: true, API and Worker startup enforce production-safe storage:

  • jobstore.type=postgres with DSN
  • effect_store.type=postgres with DSN
  • checkpoint_store.type=postgres with DSN
  • no default database password
  • no sslmode=disable

The API process additionally requires specific CORS origins, authentication enabled, and a JWT key. See production runtime gates.

The Invocation Ledger does not have a separate public config block. It is assembled from the shared ToolInvocationStore during DAG compiler setup; in production this relies on the same Postgres-backed runtime storage path used by the configured stores.

security.evidence_signing

Optional Ed25519 signing for evidence ZIP exports.

FieldDescription
enabledWhen true, POST /api/jobs/:id/export signs proof.json inside the ZIP
key_idKey identifier written into signed proof metadata; defaults to default
private_key_base64Raw 64-byte Ed25519 private key encoded with standard base64; env substitution is supported
public_key_base64Optional raw 32-byte Ed25519 public key encoded with standard base64; startup validates it matches the private key when present

See evidence signing.

agent.job_scheduler

Only when jobstore.type=memory; with postgres the API does not start the Scheduler.

FieldDescription
enabledEnable scheduler
max_concurrencyMax concurrent jobs
retry_maxMax retries after failure (excluding first attempt)
backoffWait before retry
queuesOptional. Priority-ordered queue list, e.g. ["realtime","default","background"]. Scheduler claims from the first non-empty queue. Empty or unset → single queue (no class). Job.QueueClass / Job.Priority set at create time (e.g. by API) control which queue a job belongs to; Postgres store requires schema migration for queue columns to filter by queue.

agent.adk (Eino ADK 主 Runner)

agent.adk.enabled 未配置或为 true 时,对话入口 POST /api/agent/runPOST /api/agent/resumePOST /api/agent/stream 使用 Eino ADK Runner 执行(ChatModelAgent + 检索/生成/文档等工具)。设为 false 时改用原 Plan→Execute Agent。

FieldDescription
enabledOptional. When false, disable ADK and use legacy agent for /api/agent/run. Unset or true → use ADK.
checkpoint_storememory (default) for in-process checkpoint; reserved for future postgres/redis.

Resume:请求体 {"checkpoint_id":"..."},用于从 ADK 中断点恢复。Stream:与 run 相同请求体,响应为 SSE(text/event-stream)。详见 concepts/adk.md.

storage (API)

When present, the API uses it for ingest_pipeline and query_pipeline. Same structure as worker storage: storage.vector (type, collection, addr, db) and storage.ingest (batch_size, concurrency). See worker.yaml — storage for field descriptions. If api.yaml does not define storage, merged config may fall back to zero values (type "" → treated as memory; collection """default").

service

Service discovery: agent_service, index_service addr and timeout.

log

level, format, file (optional log file path).

monitoring

  • prometheus: enable, port (e.g. 9092).
  • tracing: OpenTelemetry. When enable is true, spans are exported; when export_endpoint is empty, env OTEL_EXPORTER_OTLP_ENDPOINT is used (endpoint only, e.g. localhost:4317). insecure: true means no TLS. See tracing.md.

model.yaml

Relation to pipelines

When model.defaults.llm and model.defaults.embedding are set, the API registers query_pipeline (retrieve + generate) and ingest_pipeline (parse + split + embed + index) at startup. If unset or keys missing, pipelines may not register or use placeholders.

Structure

  • model.llm.providers: Each provider (e.g. openai, qwen, claude) has api_key, base_url, models. Each model has name, context_window, temperature, etc.
  • model.embedding.providers: Same shape; models include dimension, input_limit, etc.
  • model.vision.providers: Optional; models include max_tokens, temperature, etc.
  • model.defaults: llm, embedding, vision are default keys in "provider.model" form, e.g. qwen.qwen3_max, openai.text-embedding-ada-002.

Secrets

Do not commit real API keys. Use environment variable placeholders, e.g.:

api_key: "${OPENAI_API_KEY}"

Use DASHSCOPE_API_KEY for Qwen/DashScope, ANTHROPIC_API_KEY for Claude, COHERE_API_KEY for Cohere. Viper substitutes these at runtime.


worker.yaml

worker

FieldDescription
concurrencyConcurrency
queue_sizeQueue size
retry_countRetry count
retry_delayRetry delay
timeoutTask timeout
poll_intervalInterval for Claiming jobs from the event store
capabilitiesOptional. List of worker capabilities (e.g. ["llm", "tool", "rag"]). When set, the Worker only claims jobs whose required_capabilities are satisfied by this list (empty job requirements = any worker). Enables multi-agent / multi-model dispatch: e.g. LLM-only workers vs. tool+rag workers. Omit or leave empty to accept any job.

jobstore

Must match the API jobstore (type and dsn). When sharing Postgres with the API, Workers run jobs via Claim; the API does not execute.

storage

  • metadata: type, dsn, pool_size. Currently only memory is fully supported; MySQL etc. require future implementations.
  • vector: Vector store used by ingest (index) and query (retrieve). Implemented via internal/einoext factory (memory uses internal/storage/vector; redis uses eino-ext components).
    • type: memory (default) or redis. With memory, a process-local in-memory store is used. With redis, Indexer and Retriever are created from eino-ext Redis components; Redis Stack is required (vector search via FT.SEARCH), and the index must be created separately (see eino-ext docs).
    • addr: For redis, Redis server address (e.g. localhost:6379). Ignored for memory.
    • db: For redis, Redis logical DB number as string (e.g. "0"). Ignored for memory.
    • collection: Default index/collection name. Ingest writes to this name; query retrieves from it. Empty means "default". For redis, this is used as the index name / key prefix. API and Worker should use the same value when sharing a vector store.
    • password: Optional. For redis, Redis AUTH password. Omit or leave empty if not used.
  • ingest: Optional tuning for the ingest pipeline (API and Worker).
    • batch_size: Vectors per batch when writing to the vector store (default 100).
    • concurrency: Concurrency for embedding and indexing (default 4).

Document metadata written by the indexer includes vector_store (the configured type) and collection (the index name used).

splitter

chunk_size, chunk_overlap, max_chunks for ingest splitting.

Model config

Worker loads config via LoadWorkerConfigWithModel, which merges configs/model.yaml, so LLM/Embedding/Vision are shared with the API.

log / monitoring

Same as API for log; monitoring.prometheus port can be set per Worker; use env AETHERIS_WORKER_METRICS_PORT when running multiple workers (e.g. 9094).


Environment variables summary

VariablePurpose
OPENAI_API_KEYOpenAI API key (model.yaml placeholder)
ANTHROPIC_API_KEYClaude API key
DASHSCOPE_API_KEYAlibaba DashScope / Qwen
COHERE_API_KEYCohere Embedding
AWS_ACCESS_KEY_IDAWS credentials for Bedrock
AWS_SECRET_ACCESS_KEYAWS credentials for Bedrock
JWT_SECRETAPI auth JWT secret (when middleware.auth is true)
JOBSTORE_DSNPostgres DSN; overrides jobstore.dsn in api.yaml / worker.yaml
OTEL_EXPORTER_OTLP_ENDPOINTTracing OTLP endpoint (when export_endpoint is unset)
PLANNER_TYPEPlanner type: rule for RulePlanner (fixed TaskGraph, no LLM needed for planning), llm for LLMPlanner (uses LLM to generate TaskGraph). RulePlanner is recommended for debugging. Default: llm
AETHERIS_API_URLCLI API base URL, default http://localhost:8080
AETHERIS_AGENT_IDUsed by CLI chat when agent_id is not passed
AETHERIS_WORKER_METRICS_PORTWorker Prometheus port (when running multiple instances)
AETHERIS_ENVEnvironment mode: development, staging, production
AETHERIS_REGIONRegion for regional scheduling (v2.2.0+)

For more on startup and typical flows see the "Environment variables and configuration" section in usage.md.


agents.yaml

Agent 定义配置文件,由 AgentFactory 在启动时加载。路径:configs/agents.yaml

结构

agents:
  <agent_name>:
    type: "react"              # Agent 类型:react, deer, manus, chain, graph, workflow, external_http, langchain, langgraph
    description: "描述"         # Agent 描述
    llm: "default"             # LLM 配置引用
    max_iterations: 10         # ReAct 最大迭代步数
    tools:                     # 可选:工具过滤列表;空或省略 = 使用全部可用工具
      - "web_search"
      - "calculator"
    system_prompt: |           # 系统提示词
      You are a helpful assistant.

HTTP 黑盒 Agent 使用 external 字段:

agents:
  customer_support_bot:
    type: "external_http"
    description: "Existing customer support agent"
    external:
      url: "http://customer-bot:9000/invoke"
      timeout: "120s"
      token_env: "CUSTOMER_BOT_TOKEN"

LangChain/LangGraph 等框架生成的 Python agent 可以直接使用框架类型别名。它们仍然走同一条 external_agent_call Runtime Tool 路径:

agents:
  research_agent:
    type: "langchain"
    description: "Existing LangChain ReAct agent"
    external:
      url: "http://localhost:9000/invoke"
      timeout: "120s"

  research_graph:
    type: "langgraph"
    description: "Existing LangGraph compiled graph"
    external:
      url: "http://localhost:9001/invoke"
      timeout: "120s"

如果希望 Aetheris 接管框架内部步骤,而不是只包裹一次外部调用,使用 embedded manifest 模式:

agents:
  research_agent:
    type: "langchain"
    description: "Embedded LangChain research agent"
    external:
      mode: "embedded"
      url: "http://localhost:9000"
      timeout: "120s"
      manifest_path: "./configs/framework-agents/research_agent.manifest.json"

mode=embedded 会读取 manifest_pathmanifest_url,或回退请求 GET {external.url}/aetheris/manifest,再把 manifest 转成 Aetheris TaskGraphexternal.url 在 embedded 模式下表示框架服务 base URL,Runtime 会调用 POST {external.url}/aetheris/nodes/{node_id}/invoke

agents 字段说明

FieldTypeRequiredDescription
typestringYesAgent 类型。react = ReAct 循环;deer = 增强推理;manus = 自主执行;chain = 简单链式;graph = DAG;workflow = 线性工作流;external_http = HTTP 黑盒 Agent;langchain / langgraph = 框架 agent HTTP 接入别名
descriptionstringNoAgent 描述,用于标识
llmstringNoLLM 配置引用,"default" 使用 model.yaml 中的默认配置
max_iterationsintNoReAct 最大迭代步数,超过则停止。默认 10
tools[]stringNo工具名称列表,用于过滤该 Agent 可使用的工具子集。空列表或省略表示使用全部注册工具(Engine 内置 + Registry + MCP)
system_promptstringNoAgent 系统提示词,注入到 Eino ADK Agent 的 Instruction 字段
chain_typestringNotype=chain 时的链类型(如 conversation
graph_typestringNotype=graph 时的图类型(如 directed
workflow_typestringNotype=workflow 时的工作流类型(如 linear
external.urlstringexternal agent required外部 Agent HTTP invoke endpoint
external.timeoutstringNo单次调用超时,如 120s;默认 120s
external.token_envstringNoBearer token 来源环境变量;配置后启动时必须存在
external.modestringNo外部 Agent 模式。默认 blackboxembedded 表示读取 framework manifest 并生成多节点 TaskGraph
external.manifest_pathstringNoEmbedded 模式本地 manifest JSON 路径;优先级高于 manifest_urlurl 回退
external.manifest_urlstringNoEmbedded 模式远程 manifest URL;未配置时可通过 external.url + /aetheris/manifest 获取
external.frameworkstringNo外部框架标签。type=langchain/langgraph 时自动填充;type=external_http 时可手动设置,如 langchainlanggraph

external_http 的可靠性边界是分层的:Aetheris 负责外层 Job、事件、Trace、重试、超时和 external_agent_call 工具调用幂等;外部 Agent 内部的支付、写库、发信等副作用需要继续迁移成 Runtime Tool,才获得 Invocation Ledger / Effect Store 的 at-most-once 保证。

Embedded manifest 支持以下节点类型:

Manifest kindTaskGraph node
runtime_tooltool
runtime_llmllm
runtime_workflowworkflow
waitwait
approvalapproval
remote_callableframework_callable

AgentFactory 加载流程

  1. internal/app/api/app.go 调用 agentFactory.GetOrCreateFromConfig(ctx, &bootstrap.Config.Agents)
  2. 遍历 agents map,为每个 agent 构建 AgentBuildConfig
  3. 调用 AgentFactory.CreateAgent() 创建 Eino ADK Runner
  4. Runner 缓存在 factory 中,通过 GetRunner(name) 获取

工具收集逻辑

AgentFactory.collectTools(toolNames) 合并以下来源:

  • Engine 内置工具GetDefaultTools(engine) — retriever, generator, document_loader, document_parser, splitter, embedding, index_builder
  • Registry 工具:通过 RegistryToolBridge.EinoTools()RuntimeToolRegistry 转换(包含 native + MCP 工具)
  • tools 字段非空,则按名称过滤;否则返回全部

示例

agents:
  # 带工具过滤的 Agent
  search_agent:
    type: "react"
    description: "搜索专用 Agent"
    max_iterations: 10
    tools:
      - "web_search"
      - "http_request"
    system_prompt: "你是一个搜索助手。"

  # 使用全部工具的 Agent
  general_agent:
    type: "react"
    description: "通用 Agent"
    max_iterations: 15
    system_prompt: "你是一个通用助手。"

Go 类型对应

pkg/config/config.go 中的 AgentDefConfig

type AgentDefConfig struct {
    Type          string   `mapstructure:"type"`
    Description   string   `mapstructure:"description"`
    LLM           string   `mapstructure:"llm"`
    MaxIterations int      `mapstructure:"max_iterations"`
    SystemPrompt  string   `mapstructure:"system_prompt"`
    Tools         []string `mapstructure:"tools"`
    External      AgentExternalConfig `mapstructure:"external"`
    // ...
}