docs: add evolution config controls (#2852)

* docs: add evolution config controls

* docs: address evolution config review
This commit is contained in:
lxowalle
2026-05-12 11:23:06 +08:00
committed by GitHub
parent 255a67e2da
commit 223ebdf0c7
12 changed files with 414 additions and 1 deletions
+9
View File
@@ -20,6 +20,15 @@
}
}
},
"evolution": {
"enabled": false,
"mode": "observe",
"state_dir": "",
"min_task_count": 2,
"min_success_ratio": 0.7,
"cold_path_trigger": "after_turn",
"cold_path_times": []
},
"model_list": [
{
"model_name": "gpt-5.4",
+1
View File
@@ -7,6 +7,7 @@ Internal architecture notes for major runtime mechanisms and subsystem design.
- [Session System](session-system.md): session scope allocation, JSONL persistence, alias compatibility, and migration. ([ZH](session-system.zh.md))
- [Routing System](routing-system.md): agent dispatch, session policy selection, and light/heavy model routing. ([ZH](routing-system.zh.md))
- [Runtime Events](runtime-events.md): runtime event envelope, centralized event logging, filters, and examples. ([ZH](runtime-events.zh.md))
- [Agent Self-Evolution](agent-self-evolution.md): learning records, draft generation, application modes, and state layout.
- [Hook System Guide](hooks/README.md): current hook architecture and protocol details.
- [Agent Refactor](agent-refactor/README.md): notes and checkpoints for the agent refactor work.
+47
View File
@@ -0,0 +1,47 @@
# Agent Self-Evolution
Agent self-evolution lets PicoClaw learn from completed turns and turn repeated successful behavior into skill improvements. The runtime is controlled by the top-level `evolution` config block.
## Flow
The hot path runs at the end of an agent turn. When `evolution.enabled` is true, it records a learning record with the turn summary, success state, used skills, tool executions, and session/workspace metadata. Heartbeat turns are skipped.
The cold path groups related task records, checks the configured success threshold, and prepares skill drafts for patterns that have enough evidence. Drafts can target new skills or append/replace/merge existing workspace skills.
The apply path validates generated `SKILL.md` content before writing. Invalid drafts are rejected before a skill directory or file is created.
## Safety Considerations
Evolution creates a persistent feedback loop: user input can become a task record, task records can be clustered into an LLM-generated draft, and an accepted draft can become `SKILL.md` content that is loaded into future agent prompts. Treat generated skill content as prompt-sensitive material, especially in `apply` mode.
The current local scanner is a narrow guardrail, not a complete safety boundary. It rejects structurally invalid drafts and a small set of obvious secret-like substrings, but it does not reliably detect prompt injection, unsafe instructions, or every form of sensitive data. Use `observe` or `draft` when human review is required before skill changes reach disk.
In `apply` mode, accepted drafts can update workspace skills automatically. Existing skills are backed up before replacement, but recovery is manual: an operator must restore the desired backup if an applied skill should be rolled back.
## Modes
| Mode | Behavior |
|------|----------|
| `observe` | Record learning data only. No cold-path draft generation runs automatically. |
| `draft` | Record learning data and generate candidate skill drafts when the cold path runs. |
| `apply` | Generate drafts and allow accepted drafts to update workspace skills. |
When `evolution.enabled` is false, `mode` is treated as disabled at runtime.
## Cold Path Trigger
`cold_path_trigger` only matters in `draft` and `apply` modes.
| Trigger | Behavior |
|---------|----------|
| `after_turn` | Run the cold path after eligible turns. |
| `scheduled` | Run the cold path at configured `cold_path_times`. |
| `manual` | Do not run automatically. There is no user-facing Web/API/CLI trigger yet; code can still invoke `Runtime.RunColdPathOnce`. |
`cold_path_times` uses `HH:MM` strings and is ignored unless the trigger is `scheduled`.
## State
By default, evolution state is stored under the workspace. `state_dir` can redirect that state to another directory. The state includes learning records, clustered pattern records, drafts, and skill profiles.
For user-facing configuration fields, see the [Configuration Guide](../guides/configuration.md#agent-self-evolution).
+30
View File
@@ -69,6 +69,36 @@ PicoClaw stores data in your configured workspace (default: `~/.picoclaw/workspa
> **Note:** Changes to `AGENT.md`, `SOUL.md`, `USER.md` and `memory/MEMORY.md` are automatically detected at runtime via file modification time (mtime) tracking. You do **not** need to restart the gateway after editing these files — the agent picks up the new content on the next request.
### Agent Self-Evolution
The `evolution` block controls PicoClaw's self-evolution runtime. When enabled, the agent records completed turns as learning records. In higher modes it can group repeated successful patterns, generate skill drafts, and optionally apply accepted drafts into workspace skills.
```json
{
"evolution": {
"enabled": false,
"mode": "observe",
"state_dir": "",
"min_task_count": 2,
"min_success_ratio": 0.7,
"cold_path_trigger": "after_turn",
"cold_path_times": []
}
}
```
| Field | Default | Description |
|-------|---------|-------------|
| `enabled` | `false` | Enables learning-record capture for completed agent turns. Heartbeat turns are ignored. |
| `mode` | `observe` | `observe` records data only. `draft` can generate candidate skill drafts. `apply` can apply accepted drafts to workspace skills. |
| `state_dir` | `""` | Optional directory for evolution state. Leave empty to use the default under the workspace. |
| `min_task_count` | `2` | Minimum related task records required before a pattern is eligible for draft generation. |
| `min_success_ratio` | `0.7` | Minimum success ratio for a task cluster. Use a value greater than `0` and up to `1`. |
| `cold_path_trigger` | `after_turn` | Runs draft generation `after_turn`, on a `scheduled` cadence, or disables automatic cold-path runs when set to `manual`. There is no user-facing manual trigger yet. Applies only in `draft` and `apply` modes. |
| `cold_path_times` | `[]` | Scheduled run times used when `cold_path_trigger` is `scheduled`, written as `HH:MM` strings. |
Use `observe` first if you want to inspect learning records without generating skill changes. Use `draft` when you want PicoClaw to prepare reviewable improvements. Use `apply` only when you are comfortable letting accepted drafts update workspace skills.
### Web launcher dashboard
**picoclaw-launcher** serves a browser UI that requires password sign-in first. On first run, open `/launcher-setup` to create the dashboard password. Later manual sign-ins use `/launcher-login`.
+30
View File
@@ -67,6 +67,36 @@ PicoClaw 将数据存储在您配置的工作区中(默认:`~/.picoclaw/work
> **提示:** 对 `AGENT.md`、`SOUL.md`、`USER.md` 和 `memory/MEMORY.md` 的修改会通过文件修改时间(mtime)在运行时自动检测。**无需重启 gateway**,Agent 将在下一次请求时自动加载最新内容。
### Agent 自进化
`evolution` 配置块控制 PicoClaw 的自进化运行时。启用后,Agent 会把已完成的回合记录为学习记录。在更高模式下,它可以聚类重复出现的成功模式、生成技能草稿,并可选择把已接受的草稿应用到工作区技能中。
```json
{
"evolution": {
"enabled": false,
"mode": "observe",
"state_dir": "",
"min_task_count": 2,
"min_success_ratio": 0.7,
"cold_path_trigger": "after_turn",
"cold_path_times": []
}
}
```
| 字段 | 默认值 | 说明 |
|------|--------|------|
| `enabled` | `false` | 启用已完成 Agent 回合的学习记录采集。Heartbeat 回合会被忽略。 |
| `mode` | `observe` | `observe` 只记录数据;`draft` 可生成候选技能草稿;`apply` 可将已接受草稿应用到工作区技能。 |
| `state_dir` | `""` | 自进化状态的可选目录。留空时使用工作区下的默认位置。 |
| `min_task_count` | `2` | 一个模式具备生成草稿资格前所需的最小相关任务记录数。 |
| `min_success_ratio` | `0.7` | 任务聚类所需的最小成功率,取值需大于 `0`,且不超过 `1`。 |
| `cold_path_trigger` | `after_turn` | 草稿生成可在 `after_turn` 后运行、按 `scheduled` 定时运行;设置为 `manual` 时会关闭自动冷路径运行。目前还没有用户可用的手动触发入口。仅在 `draft``apply` 模式下生效。 |
| `cold_path_times` | `[]` | 当 `cold_path_trigger``scheduled` 时使用的运行时间,格式为 `HH:MM` 字符串。 |
如果你只想先检查学习记录,建议从 `observe` 开始。需要生成可审查改进时使用 `draft`。只有在你接受让已通过的草稿更新工作区技能时,才使用 `apply`
### Web 启动器控制台
**picoclaw-launcher** 打开浏览器控制台前需要先使用密码登录。首次启动时打开 `/launcher-setup` 创建 dashboard 登录密码;后续手动登录使用 `/launcher-login`
+1 -1
View File
@@ -55,7 +55,7 @@ The current frontend exposes these major pages and flows:
- `/agent/tools`
- View tool availability and enable or disable tool switches through config-backed APIs.
- `/config`
- Edit agent defaults, exec controls, cron controls, heartbeat, device monitoring, launcher networking, and launch-at-login settings.
- Edit agent defaults, self-evolution, exec controls, cron controls, heartbeat, device monitoring, launcher networking, and launch-at-login settings.
- `/logs`
- View the in-memory gateway log buffer and clear it.
@@ -20,6 +20,7 @@ import {
AgentDefaultsSection,
CronSection,
DevicesSection,
EvolutionSection,
ExecSection,
LauncherSection,
MCPSection,
@@ -33,6 +34,7 @@ import {
type MCPServerForm,
buildFormFromConfig,
parseCIDRText,
parseFloatField,
parseIntField,
parseJSONObjectField,
parseMultilineList,
@@ -281,6 +283,16 @@ export function ConfigPage() {
"Cron exec timeout",
{ min: 0 },
)
const evolutionMinTaskCount = parseIntField(
form.evolutionMinTaskCount,
"Evolution minimum task count",
{ min: 1 },
)
const evolutionMinSuccessRatio = parseFloatField(
form.evolutionMinSuccessRatio,
"Evolution minimum success ratio",
{ min: 0.01, max: 1 },
)
const mcpDiscoveryValidationEnabled =
form.mcpEnabled && form.mcpDiscoveryEnabled
const mcpDiscoveryPatch: Record<string, unknown> = {
@@ -500,6 +512,20 @@ export function ConfigPage() {
session: {
dm_scope: dmScope,
},
evolution: {
enabled: form.evolutionEnabled,
mode: form.evolutionMode,
state_dir:
form.evolutionStateDir.trim() === ""
? null
: form.evolutionStateDir.trim(),
min_task_count: evolutionMinTaskCount,
min_success_ratio: evolutionMinSuccessRatio,
cold_path_trigger: form.evolutionColdPathTrigger,
cold_path_times: parseMultilineList(
form.evolutionColdPathTimesText,
),
},
tools: {
cron: {
allow_command: form.allowCommand,
@@ -661,6 +687,8 @@ export function ConfigPage() {
<RuntimeSection form={form} onFieldChange={updateField} />
<EvolutionSection form={form} onFieldChange={updateField} />
<MCPSection
form={form}
onFieldChange={updateField}
@@ -236,6 +236,152 @@ interface MCPSectionProps {
) => void
}
interface EvolutionSectionProps {
form: CoreConfigForm
onFieldChange: UpdateCoreField
}
export function EvolutionSection({
form,
onFieldChange,
}: EvolutionSectionProps) {
const { t } = useTranslation()
return (
<ConfigSectionCard
title={t("pages.config.sections.evolution")}
description={t("pages.config.evolution_section_hint")}
>
<SwitchCardField
label={t("pages.config.evolution_enabled")}
hint={t("pages.config.evolution_enabled_hint")}
layout="setting-row"
checked={form.evolutionEnabled}
onCheckedChange={(checked) =>
onFieldChange("evolutionEnabled", checked)
}
/>
<Field
label={t("pages.config.evolution_mode")}
hint={t("pages.config.evolution_mode_hint")}
layout="setting-row"
>
<Select
value={form.evolutionMode}
onValueChange={(value) => onFieldChange("evolutionMode", value)}
>
<SelectTrigger aria-label={t("pages.config.evolution_mode")}>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="observe">
{t("pages.config.evolution_mode_observe")}
</SelectItem>
<SelectItem value="draft">
{t("pages.config.evolution_mode_draft")}
</SelectItem>
<SelectItem value="apply">
{t("pages.config.evolution_mode_apply")}
</SelectItem>
</SelectContent>
</Select>
</Field>
<Field
label={t("pages.config.evolution_state_dir")}
hint={t("pages.config.evolution_state_dir_hint")}
layout="setting-row"
>
<Input
value={form.evolutionStateDir}
onChange={(e) => onFieldChange("evolutionStateDir", e.target.value)}
placeholder="e.g. /var/lib/picoclaw/evolution"
/>
</Field>
<Field
label={t("pages.config.evolution_min_task_count")}
hint={t("pages.config.evolution_min_task_count_hint")}
layout="setting-row"
>
<Input
type="number"
min={1}
value={form.evolutionMinTaskCount}
onChange={(e) =>
onFieldChange("evolutionMinTaskCount", e.target.value)
}
/>
</Field>
<Field
label={t("pages.config.evolution_min_success_ratio")}
hint={t("pages.config.evolution_min_success_ratio_hint")}
layout="setting-row"
>
<Input
type="number"
min={0.01}
max={1}
step="0.05"
value={form.evolutionMinSuccessRatio}
onChange={(e) =>
onFieldChange("evolutionMinSuccessRatio", e.target.value)
}
/>
</Field>
<Field
label={t("pages.config.evolution_cold_path_trigger")}
hint={t("pages.config.evolution_cold_path_trigger_hint")}
layout="setting-row"
>
<Select
value={form.evolutionColdPathTrigger}
onValueChange={(value) =>
onFieldChange("evolutionColdPathTrigger", value)
}
>
<SelectTrigger
aria-label={t("pages.config.evolution_cold_path_trigger")}
>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="after_turn">
{t("pages.config.evolution_cold_path_after_turn")}
</SelectItem>
<SelectItem value="scheduled">
{t("pages.config.evolution_cold_path_scheduled")}
</SelectItem>
<SelectItem value="manual">
{t("pages.config.evolution_cold_path_manual")}
</SelectItem>
</SelectContent>
</Select>
</Field>
{form.evolutionColdPathTrigger === "scheduled" && (
<Field
label={t("pages.config.evolution_cold_path_times")}
hint={t("pages.config.evolution_cold_path_times_hint")}
layout="setting-row"
>
<Textarea
value={form.evolutionColdPathTimesText}
placeholder={"03:00\n15:30"}
className="min-h-[88px] font-mono text-xs"
onChange={(e) =>
onFieldChange("evolutionColdPathTimesText", e.target.value)
}
/>
</Field>
)}
</ConfigSectionCard>
)
}
export function MCPSection({
form,
onFieldChange,
@@ -32,6 +32,13 @@ export interface CoreConfigForm {
mcpDiscoveryUseBM25: boolean
mcpDiscoveryUseRegex: boolean
mcpServers: MCPServerForm[]
evolutionEnabled: boolean
evolutionMode: string
evolutionStateDir: string
evolutionMinTaskCount: string
evolutionMinSuccessRatio: string
evolutionColdPathTrigger: string
evolutionColdPathTimesText: string
}
export type MCPServerType = "http" | "sse" | "stdio"
@@ -121,6 +128,13 @@ export const EMPTY_FORM: CoreConfigForm = {
mcpDiscoveryUseBM25: true,
mcpDiscoveryUseRegex: false,
mcpServers: [],
evolutionEnabled: false,
evolutionMode: "observe",
evolutionStateDir: "",
evolutionMinTaskCount: "2",
evolutionMinSuccessRatio: "0.7",
evolutionColdPathTrigger: "after_turn",
evolutionColdPathTimesText: "",
}
export const EMPTY_LAUNCHER_FORM: LauncherForm = {
@@ -215,6 +229,7 @@ export function buildFormFromConfig(config: unknown): CoreConfigForm {
const session = asRecord(root.session)
const heartbeat = asRecord(root.heartbeat)
const devices = asRecord(root.devices)
const evolution = asRecord(root.evolution)
const tools = asRecord(root.tools)
const mcp = asRecord(tools.mcp)
const mcpDiscovery = asRecord(mcp.discovery)
@@ -335,6 +350,29 @@ export function buildFormFromConfig(config: unknown): CoreConfigForm {
? EMPTY_FORM.mcpDiscoveryUseRegex
: asBool(mcpDiscovery.use_regex),
mcpServers: mapMCPServers(mcp.servers),
evolutionEnabled:
evolution.enabled === undefined
? EMPTY_FORM.evolutionEnabled
: asBool(evolution.enabled),
evolutionMode: asString(evolution.mode) || EMPTY_FORM.evolutionMode,
evolutionStateDir:
asString(evolution.state_dir) || EMPTY_FORM.evolutionStateDir,
evolutionMinTaskCount: asNumberString(
evolution.min_task_count,
EMPTY_FORM.evolutionMinTaskCount,
),
evolutionMinSuccessRatio: asNumberString(
evolution.min_success_ratio,
EMPTY_FORM.evolutionMinSuccessRatio,
),
evolutionColdPathTrigger:
asString(evolution.cold_path_trigger) ||
EMPTY_FORM.evolutionColdPathTrigger,
evolutionColdPathTimesText: Array.isArray(evolution.cold_path_times)
? evolution.cold_path_times
.filter((value): value is string => typeof value === "string")
.join("\n")
: EMPTY_FORM.evolutionColdPathTimesText,
}
}
@@ -356,6 +394,24 @@ export function parseIntField(
return value
}
export function parseFloatField(
rawValue: string,
label: string,
options: { min?: number; max?: number } = {},
): number {
const value = Number(rawValue)
if (!Number.isFinite(value)) {
throw new Error(`${label} must be a number.`)
}
if (options.min !== undefined && value < options.min) {
throw new Error(`${label} must be >= ${options.min}.`)
}
if (options.max !== undefined && value > options.max) {
throw new Error(`${label} must be <= ${options.max}.`)
}
return value
}
export function parseCIDRText(raw: string): string[] {
if (!raw.trim()) {
return []
+22
View File
@@ -802,6 +802,27 @@
"allowed_cidrs": "Allowed Network CIDRs",
"allowed_cidrs_hint": "Only clients from these CIDR ranges can access the service. One per line or comma-separated. Leave empty to allow all.",
"allowed_cidrs_placeholder": "192.168.1.0/24\n10.0.0.0/8",
"evolution_section_hint": "Let the agent learn from completed turns and prepare skill improvements.",
"evolution_enabled": "Enable Evolution",
"evolution_enabled_hint": "Record learning data for completed turns. Draft and apply modes can also generate skill updates.",
"evolution_mode": "Evolution Mode",
"evolution_mode_hint": "Observe only records data, Draft prepares candidate skills, Apply can write accepted drafts into workspace skills.",
"evolution_mode_observe": "Observe",
"evolution_mode_draft": "Draft",
"evolution_mode_apply": "Apply",
"evolution_state_dir": "State Directory",
"evolution_state_dir_hint": "Optional directory for evolution state. Leave empty to use the workspace default.",
"evolution_min_task_count": "Minimum Task Count",
"evolution_min_task_count_hint": "Minimum related tasks required before a pattern can produce a draft.",
"evolution_min_success_ratio": "Minimum Success Ratio",
"evolution_min_success_ratio_hint": "Required success ratio for clustered tasks. Use a value greater than 0 and up to 1.",
"evolution_cold_path_trigger": "Cold Path Trigger",
"evolution_cold_path_trigger_hint": "Choose when draft generation runs for eligible learning records.",
"evolution_cold_path_after_turn": "After each turn",
"evolution_cold_path_scheduled": "Scheduled",
"evolution_cold_path_manual": "Off",
"evolution_cold_path_times": "Scheduled Times",
"evolution_cold_path_times_hint": "Run times for scheduled cold-path processing. Enter one HH:MM value per line.",
"mcp_section_hint": "Configure MCP servers without editing config.json manually.",
"mcp_enabled": "Enable MCP",
"mcp_enabled_hint": "Turn MCP server integration on or off.",
@@ -835,6 +856,7 @@
"sections": {
"agent": "Agent",
"runtime": "Runtime",
"evolution": "Evolution",
"mcp": "MCP",
"exec": "Run Commands",
"cron": "Cron Tasks",
+22
View File
@@ -700,9 +700,31 @@
"allowed_cidrs": "CIDRs de Rede Permitidos",
"allowed_cidrs_hint": "Apenas clientes destes intervalos CIDR podem acessar o serviço. Um por linha ou separados por vírgula. Deixe vazio para permitir todos.",
"allowed_cidrs_placeholder": "192.168.1.0/24\n10.0.0.0/8",
"evolution_section_hint": "Permite que o agente aprenda com turnos concluídos e prepare melhorias de skills.",
"evolution_enabled": "Habilitar Evolução",
"evolution_enabled_hint": "Registrar dados de aprendizado para turnos concluídos. Os modos Draft e Apply também podem gerar atualizações de skills.",
"evolution_mode": "Modo de Evolução",
"evolution_mode_hint": "Observe apenas registra dados, Draft prepara skills candidatas, Apply pode gravar drafts aceitos nas skills do workspace.",
"evolution_mode_observe": "Observe",
"evolution_mode_draft": "Draft",
"evolution_mode_apply": "Apply",
"evolution_state_dir": "Diretório de Estado",
"evolution_state_dir_hint": "Diretório opcional para o estado de evolução. Deixe vazio para usar o padrão do workspace.",
"evolution_min_task_count": "Contagem Mínima de Tarefas",
"evolution_min_task_count_hint": "Número mínimo de tarefas relacionadas antes que um padrão possa produzir um draft.",
"evolution_min_success_ratio": "Taxa Mínima de Sucesso",
"evolution_min_success_ratio_hint": "Taxa de sucesso exigida para tarefas agrupadas. Use um valor maior que 0 e até 1.",
"evolution_cold_path_trigger": "Acionador Cold Path",
"evolution_cold_path_trigger_hint": "Escolha quando a geração de drafts roda para registros de aprendizado elegíveis.",
"evolution_cold_path_after_turn": "Após cada turno",
"evolution_cold_path_scheduled": "Agendado",
"evolution_cold_path_manual": "Desligado",
"evolution_cold_path_times": "Horários Agendados",
"evolution_cold_path_times_hint": "Horários para o processamento cold-path agendado. Insira um valor HH:MM por linha.",
"sections": {
"agent": "Agente",
"runtime": "Runtime",
"evolution": "Evolução",
"exec": "Execução de Comandos",
"cron": "Tarefas Agendadas",
"launcher": "Launcher",
+22
View File
@@ -803,6 +803,27 @@
"allowed_cidrs": "允许访问网段",
"allowed_cidrs_hint": "仅允许这些 CIDR 网段的客户端访问服务。可按行或逗号分隔;留空表示允许所有来源",
"allowed_cidrs_placeholder": "192.168.1.0/24\n10.0.0.0/8",
"evolution_section_hint": "让 Agent 从已完成的回合中学习,并准备技能改进。",
"evolution_enabled": "启用自进化",
"evolution_enabled_hint": "记录已完成回合的学习数据。Draft 和 Apply 模式还可以生成技能更新。",
"evolution_mode": "自进化模式",
"evolution_mode_hint": "Observe 只记录数据,Draft 生成候选技能,Apply 可将接受的草稿写入工作区技能。",
"evolution_mode_observe": "observe",
"evolution_mode_draft": "draft",
"evolution_mode_apply": "apply",
"evolution_state_dir": "状态目录",
"evolution_state_dir_hint": "自进化状态的可选目录。留空时使用工作区默认位置。",
"evolution_min_task_count": "最小任务数",
"evolution_min_task_count_hint": "一个模式能生成草稿前,至少需要多少个相关任务。",
"evolution_min_success_ratio": "最小成功率",
"evolution_min_success_ratio_hint": "聚类任务所需的成功率。取值需大于 0,且不超过 1。",
"evolution_cold_path_trigger": "冷路径触发方式",
"evolution_cold_path_trigger_hint": "选择何时为符合条件的学习记录运行草稿生成。",
"evolution_cold_path_after_turn": "每轮结束后",
"evolution_cold_path_scheduled": "定时运行",
"evolution_cold_path_manual": "关闭自动运行",
"evolution_cold_path_times": "定时运行时间",
"evolution_cold_path_times_hint": "定时冷路径处理的运行时间。每行填写一个 HH:MM。",
"mcp_section_hint": "通过可视化界面配置 MCP 服务器,无需手动编辑 config.json",
"mcp_enabled": "启用 MCP",
"mcp_enabled_hint": "开启或关闭 MCP 服务集成",
@@ -836,6 +857,7 @@
"sections": {
"agent": "智能体",
"runtime": "运行时",
"evolution": "自进化",
"mcp": "MCP",
"exec": "运行命令",
"cron": "定时任务",