Skip to main content ホーム クリエイター adu2021 skillxiv learning-on-job-self-evolving-agent
learning-on-job-self-evolving-agent Build autonomous agents that accumulate structured knowledge from task execution into hierarchical memory (strategic, procedural, tool) without human annotation, enabling knowledge transfer to unseen tasks.
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/ADu2021/skillXiv --skill learning-on-job-self-evolving-agentコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... name learning-on-job-self-evolving-agent title Learning on the Job: An Experience-Driven Self-Evolving Agent for Long-Horizon Tasks version 0.0.2 engine skillxiv-v0.0.2-claude-opus-4.6 license MIT url https://arxiv.org/abs/2510.08002 keywords ["Self-Evolution","Agent Learning","Memory Systems","Experience Reuse","Long-Horizon Tasks"] description Build autonomous agents that accumulate structured knowledge from task execution into hierarchical memory (strategic, procedural, tool) without human annotation, enabling knowledge transfer to unseen tasks.
Technique: Hierarchical Memory for Autonomous Agent Self-Evolution
Task-specific fine-tuning of agents is expensive and doesn't generalize. Autonomous agents need to accumulate knowledge from their own experiences and apply it to new problems. Learning on the Job enables this through a hierarchical memory architecture that captures execution traces at multiple levels of abstraction.
The core insight is treating memory as natural language rather than parameters. After executing a task, agents extract high-level strategies, procedural steps, and tool patterns into structured memory. This memory becomes accessible for future tasks without retraining, enabling knowledge transfer across diverse problem domains.
Core Concept
The system implements a "Plan-Execute-Reflect-Memorize" loop with three memory types:
Strategic Memory : High-level problem-solution mappings guiding overall approach
Procedural Memory : Step-by-step SOPs indexed by application domain
Tool Memory : Individual tool usage patterns and instructions
After each subtask, the Reflect Agent distills the trajectory into new memory entries, enabling seamless transfer across different LLMs without fine-tuning.
Architecture Overview
Execution Phase : Agent generates and executes actions within task environment
Reflection Phase : Analyze trajectory to extract generalizable knowledge
Memory Update : Store strategic insights, procedural steps, tool patterns
Retrieval Phase : For new tasks, fetch relevant memory entries as context
Generalization : Apply learned patterns to previously unseen challenges
Implementation Steps
Define the hierarchical memory structure.
class MemoryEntry :
def __init__ (self, entry_type, content, domain, success_rate=None ):
self .type = entry_type
self .content = content
self .domain = domain
self .success_rate = success_rate or
:
( ):
.strategic = []
.procedural = []
.tools = []
( ):
entry = MemoryEntry( , solution_approach, domain)
.strategic.append(entry)
( ):
entry = MemoryEntry( , steps, application_domain, success_rate)
.procedural.append(entry)
( ):
entry = MemoryEntry( , { : tool_name, : usage_pattern},
domain)
.tools.append(entry)
( ):
relevant = []
memory_type [ , ]:
relevant.extend( ._semantic_match(task_description, .strategic))
memory_type [ , ]:
relevant.extend( ._semantic_match(task_description, .procedural))
memory_type [ , ]:
relevant.extend( ._semantic_match(task_description, .tools))
relevant
( ):
sklearn.metrics.pairwise cosine_similarity
memory_list:
[]
query_embedding = ._embed(query)
scores = []
entry memory_list:
entry_embedding = ._embed(entry.content)
similarity = cosine_similarity([query_embedding], [entry_embedding])[ ][ ]
scores.append((entry, similarity))
scores.sort(key= x: x[ ], reverse= )
[entry entry, _ scores[:top_k]]
( ):
sentence_transformers SentenceTransformer
model = SentenceTransformer( )
model.encode(text)
0.0
class
HierarchicalMemory
def
__init__
self
self
self
self
def
add_strategic_memory
self, problem_pattern, solution_approach, domain
"""Store high-level strategy."""
'strategy'
self
def
add_procedural_memory
self, steps, application_domain, success_rate
"""Store step-by-step procedure."""
'procedure'
self
def
add_tool_memory
self, tool_name, usage_pattern, domain
"""Store tool usage pattern."""
'tool'
'name'
'usage'
self
def
retrieve_relevant_memory
self, task_description, memory_type='all'
"""Retrieve memory entries relevant to task."""
if
in
'all'
'strategy'
self
self
if
in
'all'
'procedure'
self
self
if
in
'all'
'tool'
self
self
return
def
_semantic_match
self, query, memory_list, top_k=3
"""Retrieve top-k semantically similar memories."""
from
import
if
not
return
self
for
in
self
0
0
lambda
1
True
return
for
in
def
_embed
self, text
"""Embed text for similarity computation."""
from
import
'all-MiniLM-L6-v2'
return
Implement the Reflection module that extracts knowledge from execution traces.
def extract_memory_from_trajectory (trajectory, task_description, llm_model ):
"""
Use LLM to reflect on execution trajectory and extract generalizable knowledge.
Args:
trajectory: Dict with 'actions', 'observations', 'results'
task_description: Original task
llm_model: Language model for reflection
Returns:
memories: Dict with 'strategy', 'procedures', 'tools'
"""
trajectory_text = f"""Task: {task_description}
Actions taken:
{format_actions(trajectory['actions' ])}
Results achieved:
{trajectory['results' ]}
Extract generalizable knowledge:
1. What high-level strategy was effective?
2. What step-by-step procedures can be reused?
3. How were tools used effectively?
"""
reflection = llm_model.generate(trajectory_text)
memories = parse_reflection_to_memories(reflection)
return memories
def format_actions (actions ):
"""Format action list for LLM review."""
formatted = []
for i, action in enumerate (actions, 1 ):
formatted.append(f"{i} . {action.get('type' )} : {action.get('content' )} " )
return "\n" .join(formatted)
def parse_reflection_to_memories (reflection_text ):
"""Parse LLM reflection into typed memory entries."""
memories = {
'strategy' : [],
'procedures' : [],
'tools' : []
}
lines = reflection_text.split('\n' )
current_type = None
for line in lines:
if 'Strategy:' in line:
current_type = 'strategy'
memories['strategy' ].append(line.replace('Strategy:' , '' ).strip())
elif 'Procedure:' in line or 'Step:' in line:
current_type = 'procedures'
memories['procedures' ].append(line.replace('Procedure:' , '' ).strip())
elif 'Tool:' in line:
current_type = 'tools'
memories['tools' ].append(line.replace('Tool:' , '' ).strip())
return memories
Implement the Plan-Execute-Reflect-Memorize loop.
def agent_execution_loop (agent, task, memory, max_steps=20 ):
"""
Execute task with memory-guided planning and reflection.
Args:
agent: Agent policy
task: Task description
memory: Hierarchical memory
max_steps: Maximum steps before timeout
Returns:
result: Task result
trajectory: Execution trace for reflection
"""
trajectory = {'actions' : [], 'observations' : [], 'results' : None }
relevant_memory = memory.retrieve_relevant_memory(task)
memory_context = format_memory_for_context(relevant_memory)
state = {'task' : task, 'memory_context' : memory_context}
for step in range (max_steps):
action = agent.generate_action(state, memory_context)
trajectory['actions' ].append(action)
observation = execute_action(action)
trajectory['observations' ].append(observation)
if is_task_complete(observation):
trajectory['results' ] = observation
break
state['last_observation' ] = observation
extracted_memories = extract_memory_from_trajectory(
trajectory, task, agent.llm_model
)
for strategy in extracted_memories.get('strategy' , []):
memory.add_strategic_memory(task, strategy, extract_domain(task))
for procedure in extracted_memories.get('procedures' , []):
memory.add_procedural_memory(procedure, extract_domain(task),
success_rate=1.0 if trajectory['results' ] else 0.0 )
for tool_usage in extracted_memories.get('tools' , []):
memory.add_tool_memory(tool_usage, extract_domain(task),
extract_domain(task))
return trajectory['results' ], trajectory
def format_memory_for_context (memory_entries ):
"""Format retrieved memory entries as LLM context."""
if not memory_entries:
return "No relevant prior experiences."
formatted = []
for entry in memory_entries:
formatted.append(f"{entry.type .upper()} : {entry.content} " )
return "\n" .join(formatted)
Practical Guidance Aspect Recommendation Notes Memory embedding model all-MiniLM-L6-v2 or similar Balance quality vs. inference speed Reflection LLM Same as agent or smaller Trade-offs between extraction quality and cost Memory retention Keep all entries; use success rate to rank More memory enables better transfer Memory update frequency After each completed subtask More frequent updates capture finer details When to use Long-horizon task sequences with pattern reuse Project planning, web navigation, research tasks When NOT to use One-off tasks or non-repeating problem types Memory overhead not justified Common pitfall Memory content becomes too generic Enforce specificity in reflection prompts
When to Use Learning on the Job
Agent systems solving sequences of related tasks
Domains where patterns repeat across problems
Scenarios where maintaining task-specific fine-tuning is impractical
When NOT to Use Learning on the Job
Single-task agents where memory transfer is unnecessary
Domains with high task diversity and low pattern reuse
Real-time systems where reflection overhead is problematic
Common Pitfalls
Generic memory : Reflection produces overly-abstract knowledge; ask for concrete procedures
Memory staleness : Periodically prune low-success-rate memories
Encoding drift : Use consistent embedding model across all memory operations
Scalability : Very large memory requires efficient retrieval; consider periodic consolidation
Reference