English | ä¸ć–‡
AutoSkill is a practical implementation of Experience-driven Lifelong Learning (ELL). It learns from real interaction experience (dialogue + behavior/events), automatically creates reusable Skills, and continuously evolves existing Skills through merge + version updates.
python3 -m pip install -e .
export INTERNLM_API_KEY="YOUR_INTERNLM_API_KEY"
export DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY"
python3 -m examples.web_ui \
--host 127.0.0.1 \
--port 8000 \
--llm-provider internlm \
--embeddings-provider qwen \
--store-dir Skills \
--user-id u1 \
--skill-scope all \
--rewrite-mode always \
--extract-mode auto \
--extract-turn-limit 1 \
--min-score 0.4 \
--top-k 1Open http://127.0.0.1:8000.
AutoSkill can also be deployed as a reverse proxy that exposes OpenAI-compatible endpoints while transparently applying:
- skill retrieval/injection for each chat request
- asynchronous skill extraction/maintenance after responses
python3 -m pip install -e .
export INTERNLM_API_KEY="YOUR_INTERNLM_API_KEY"
export DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY"
python3 -m examples.openai_proxy \
--host 127.0.0.1 \
--port 9000 \
--llm-provider internlm \
--embeddings-provider qwen \
--store-dir Skills \
--user-id u1 \
--skill-scope all \
--rewrite-mode always \
--min-score 0.4 \
--top-k 1Endpoints:
POST /v1/chat/completions(supportsstream=true)POST /v1/embeddingsGET /v1/modelsGET /health
Per-request user isolation:
- request body field
user(recommended) - or header
X-AutoSkill-User
Streaming chat curl example (stream=true):
curl -N http://127.0.0.1:9000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "intern-s1-pro",
"user": "u1",
"stream": true,
"messages": [
{"role": "user", "content": "Write a concise summary of skill self-evolution."}
]
}'If proxy auth is enabled (--proxy-api-key), add:
-H "Authorization: Bearer $AUTOSKILL_PROXY_API_KEY"If the user only asks to "write a report" and gives no stable preference/correction, AutoSkill does not create a new skill (it outputs an empty extraction result) to avoid noisy, generic skills.
When the user adds durable constraints (for example: "do not hallucinate"), AutoSkill extracts or merges a skill into version v0.1.0.
Skill management is backend-first (automatic add/merge), with optional human edit/save/delete of SKILL.md.
Caption: Daily scenario — reusable writing constraints are extracted into a new skill (v0.1.0).
Caption: Science scenario — reusable lab/process constraints (for example hard limits and mandatory SOP steps) are extracted as a skill (v0.1.0).
When user feedback adds new constraints or changes priorities in later turns, AutoSkill updates the existing skill (instead of creating duplicates)
and evolves the version from v0.1.0 to v0.1.1.
Caption: Daily scenario — later user feedback updates constraints and evolves the skill to v0.1.1.
Caption: Science scenario — follow-up technical feedback updates the existing science skill instead of creating duplicates (v0.1.1).
For the next similar task (for example, writing a government report about a self-evolving agent), the updated skill is retrieved and used to generate outputs aligned with user expectations.
Caption: Daily scenario — the evolved skill is retrieved and reused in the next similar task.
Caption: Science scenario — the evolved science skill is retrieved for subsequent domain-consistent requests.
- Experience-driven continuous skill evolution: extracts reusable capabilities directly from real user interactions and behavior traces, then continuously maintains versioned skills so the system better aligns with user needs over time.
- Universal skill format: uses the Agent Skill artifact (
SKILL.md) with clear explainability and editability: the structure is transparent, content is reviewable, and humans can revise it as needed; this also enables both importing existing skills and migrating extracted skills to other systems. - Standard API service integration: integrates into existing LLM stacks in a plug-in style; with an OpenAI-compatible proxy, AutoSkill can be adopted without changing business-side calling patterns.
Experience (messages/events)
-> Skill Extraction (candidate)
-> Skill Maintenance (add / merge / discard)
-> Skill Store (Agent Skill artifact + vector index)
- Extractor emits at most one high-quality candidate per attempt.
- Maintainer checks similarity against existing skills, then decides add/merge/discard.
- Merge updates preserve and improve capabilities, then bump patch version.
User Query (+ recent history)
-> Query Rewrite (optional)
-> Embedding + Vector Search
-> Skill Selection for Context
-> LLM Response
- Retrieval runs every turn.
- Similarity threshold and
top_kcontrol precision/recall. - Retrieved skills are filtered again before context injection.
- The top-1 retrieved skill (only if it passes
min_score) is passed to extraction as auxiliary identity context; extraction does not run a second retrieval internally.
extract_mode=auto: attempt extraction everyextract_turn_limitturns.extract_mode=always: attempt every turn.extract_mode=never: disable auto extraction./extract_now [hint]: force immediate background extraction for current context (alias:extract_now [hint]).- Generic requests without user correction (for example, one-time report writing) should return no skill extraction.
- User feedback that encodes durable preferences/constraints (for example, "do not hallucinate") should trigger extraction or update.
- If a similar user skill already exists, prefer merge/update over creating a duplicate skill.
Client (OpenAI-compatible request)
-> AutoSkill Proxy (/v1/chat/completions)
-> Query rewrite + skill retrieval + context injection
-> Upstream model generation
-> Return response to client
-> Async skill extraction/maintenance (background)
- Response latency focuses on retrieval + generation.
- Skill evolution runs asynchronously to avoid blocking the client.
- Experience: dialogue messages or behavior/event records used as learning signal.
- Skill: reusable capability artifact with metadata + executable instructions.
- Skill Candidate: temporary extraction output before maintenance decisions.
- Maintenance: logic that decides add/merge/discard and handles versioning.
- Skill Store: persistence layer for skill artifacts and vector mappings.
- Retrieval Context: selected skills rendered into prompt context for answering.
When using store={"provider": "local", "path": "Skills"}:
Skills/
Users/
<user_id>/
<skill-slug>/
SKILL.md
scripts/ (optional)
references/ (optional)
assets/ (optional)
Common/
<skill-slug>/SKILL.md
<library>/<skill-slug>/SKILL.md
vectors/
<embedding-signature>.meta.json
<embedding-signature>.ids.txt
<embedding-signature>.vecs.f32
Notes:
Users/<user_id>: user-specific skills.Common/: shared library skills (read-only in normal interactive usage).vectors/: persistent vector cache keyed by embedding signature, so switching embedding models will build/use separate indexes.
autoskill/: SDK core.examples/: runnable demos and entry scripts.autoskill/proxy/: OpenAI-compatible reverse proxy runtime.web/: static frontend assets for local Web UI.Skills/: default local storage root.imgs/: README demo images.
autoskill/client.py: public SDK entrypoint (ingest,search,render_context, import/export).autoskill/config.py: global config model.autoskill/models.py: core data models (Skill,SkillHit, etc.).autoskill/render.py: convert selected skills into injectable context.
autoskill/skill_management/extraction.py: extraction logic and prompts.autoskill/skill_management/maintenance.py: merge/version/add-discard decisions.autoskill/skill_management/formats/agent_skill.py:SKILL.mdrender/parse.autoskill/skill_management/stores/local.py: directory-based storage + vector mapping.autoskill/skill_management/vectors/flat.py: on-disk vector index backend.autoskill/skill_management/importer.py: import external Agent Skills.
autoskill/interactive/app.py: terminal interactive app orchestration.autoskill/interactive/session.py: headless session engine for Web/API usage.autoskill/interactive/rewriting.py: query rewriting for better retrieval.autoskill/interactive/selection.py: optional LLM skill selection before injection.
examples/web_ui.py: local Web UI server.examples/interactive_chat.py: CLI interactive chat.examples/openai_proxy.py: OpenAI-compatible proxy entrypoint.examples/proxy_health_check.py: proxy endpoint and streaming health check.examples/import_agent_skills.py: bulk import existing skills.examples/normalize_skill_ids.py: normalize missing IDs inSKILL.md.examples/dashscope_qwen_chat.py: DashScope chat API demo.examples/dashscope_qwen_embeddings.py: DashScope embeddings API demo.examples/bigmodel_glm_embed_extract.py: GLM + embedding online extraction demo.examples/bigmodel_glm_persistent_store.py: GLM + local persistent store demo.examples/basic_ingest_search.py: minimal offline SDK loop.examples/local_persistent_store.py: offline local persistence demo.
from autoskill import AutoSkill, AutoSkillConfig
sdk = AutoSkill(
AutoSkillConfig(
llm={"provider": "mock"},
embeddings={"provider": "hashing", "dims": 256},
store={"provider": "local", "path": "Skills"},
)
)
sdk.ingest(
user_id="u1",
messages=[
{"role": "user", "content": "Before each release: run regression -> canary -> monitor -> full rollout."},
{"role": "assistant", "content": "Understood."},
],
)
hits = sdk.search("How should I do a safe release?", user_id="u1", limit=3)
for h in hits:
print(h.skill.name, h.score)export DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY"
python3 -m examples.interactive_chat --llm-provider dashscopeexport ZHIPUAI_API_KEY="YOUR_ID.YOUR_SECRET"
python3 -m examples.interactive_chat --llm-provider glmexport OPENAI_API_KEY="YOUR_OPENAI_KEY"
python3 -m examples.interactive_chat --llm-provider openai
export ANTHROPIC_API_KEY="YOUR_ANTHROPIC_KEY"
python3 -m examples.interactive_chat --llm-provider anthropicexport INTERNLM_API_KEY="YOUR_INTERNLM_TOKEN"
python3 -m examples.interactive_chat --llm-provider internlm --llm-model intern-s1-proexport DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY"
python3 -m examples.interactive_chat --llm-provider dashscopeUseful commands:
/extract_now [hint]/extract_every <n>/extract auto|always|never/scope user|common|all/search <query>/skills/export <skill_id>
export INTERNLM_API_KEY="YOUR_INTERNLM_API_KEY"
export DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY"
python3 -m examples.web_ui --llm-provider internlm --embeddings-provider qwenpython3 -m examples.import_agent_skills --root-dir /path/to/skills --scope common --store-dir Skillspython3 -m examples.normalize_skill_ids --store-dir Skillsexport INTERNLM_API_KEY="YOUR_INTERNLM_API_KEY"
export DASHSCOPE_API_KEY="YOUR_DASHSCOPE_API_KEY"
python3 -m examples.openai_proxy --llm-provider internlm --embeddings-provider qwenDiscoverability:
curl http://127.0.0.1:9000/v1/autoskill/capabilities
curl http://127.0.0.1:9000/v1/autoskill/openapi.jsonOpenAI-compatible:
POST /v1/chat/completionsPOST /v1/embeddingsGET /v1/models
Streaming chat example (/v1/chat/completions, SSE):
curl -N http://127.0.0.1:9000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "intern-s1-pro",
"user": "u1",
"stream": true,
"messages": [
{"role": "user", "content": "Give me 3 points about AutoSkill."}
]
}'Skill APIs:
GET /v1/autoskill/skillsGET /v1/autoskill/skills/{skill_id}GET /v1/autoskill/skills/{skill_id}/mdPUT /v1/autoskill/skills/{skill_id}/mdDELETE /v1/autoskill/skills/{skill_id}POST /v1/autoskill/skills/{skill_id}/rollbackGET /v1/autoskill/skills/{skill_id}/versionsGET /v1/autoskill/skills/{skill_id}/exportPOST /v1/autoskill/skills/searchPOST /v1/autoskill/skills/import
Retrieval and extraction:
POST /v1/autoskill/retrieval/previewPOST /v1/autoskill/extractionsPOST /v1/autoskill/extractions/simulateGET /v1/autoskill/extractions/latestGET /v1/autoskill/extractionsGET /v1/autoskill/extractions/{job_id}GET /v1/autoskill/extractions/{job_id}/events(SSE)
python3 -m examples.proxy_health_check --mode health --base-url http://127.0.0.1:9000Large-scale automated evaluation (assistant via proxy + optional Qwen user simulator):
export DASHSCOPE_API_KEY="your_dashscope_key"
python3 -m examples.proxy_health_check \
--mode eval \
--base-url http://127.0.0.1:9000 \
--eval-runs 24 \
--report-json ./proxy_eval_report.jsonVector admin:
GET /v1/autoskill/vectors/statusPOST /v1/autoskill/vectors/rebuild
Chat completion example:
curl http://127.0.0.1:9000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "YOUR_MODEL_NAME",
"user": "u1",
"messages": [
{"role": "user", "content": "Write a concise release checklist."}
]
}'Retrieval preview example:
curl http://127.0.0.1:9000/v1/autoskill/retrieval/preview \
-H "Content-Type: application/json" \
-d '{
"user": "u1",
"query": "Write a concise government report with no hallucinations."
}'Extraction event stream example:
curl -N http://127.0.0.1:9000/v1/autoskill/extractions/<job_id>/events \
-H "Accept: text/event-stream"Vector rebuild example:
curl http://127.0.0.1:9000/v1/autoskill/vectors/rebuild \
-H "Content-Type: application/json" \
-d '{
"user": "u1",
"scope": "all",
"force": true,
"blocking": true
}'AutoSkill turns short-term interaction into long-term capability.
- It reduces manual Skill authoring cost.
- It keeps capabilities aligned with real user feedback over time.
- It enables a transferable skill ecosystem across different agent runtimes.
In short, this framework is a concrete path from prompt engineering to experience-driven lifelong agent learning.
If you use AutoSkill in academic work, technical reports, or demos, please cite:
@software{autoskill_2026,
author = {Yutao Yang, Junsong Li, Qianjun Pan, Bihao Zhan, Yuxuan Cai, Xin Li, Bo Zhang, Qin Chen, Jie Zhou, Kai Chen, Liang He},
title = {AutoSkill: Experience-Driven Lifelong Learning via Skill Self-Evolution},
year = {2026},
url = {https://github.com/ECNU-ICALK/AutoSkill},
note = {GitHub repository}
}Institutions: Shanghai AI Laboratory, School of Computer Science at East China Normal University
Core Authors: Yutao Yang
Contribution: Junsong Li, Qianjun Pan, Bihao Zhan, Yuxuan Cai
Lead Authors: Jie Zhou, Kai Chen, Liang He
Scientific Directors: Xin Li, Bo Zhang, Qin Chen
