Files
liqiang b119135836
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
2026-08-20 13:12:50 +00:00

366 lines
14 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Demo script for Experience Learning System
This script demonstrates all features of the experience learning system.
"""
import asyncio
import json
import logging
import os
import sys
from pathlib import Path
from typing import Dict, Any, List
import yaml
from dotenv import load_dotenv
# Add parent directory to path
sys.path.append(str(Path(__file__).parent))
from experience_agent import ExperienceAgent
from knowledge_base import KnowledgeBase
from trajectory_summarizer import TrajectorySummarizer
from llm_env import resolve_llm, DEFAULT_MODEL
from AWorld.aworld.config.conf import AgentConfig, TaskConfig
from AWorld.aworld.core.task import Task
# Setup logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class ExperienceLearningDemo:
"""Demo class for experience learning system."""
def __init__(self, config_path: str = "config.yaml"):
"""Initialize demo with configuration."""
self.config = self.load_config(config_path)
self.setup_environment()
self.knowledge_base = None
self.summarizer = None
self.agent = None
def load_config(self, config_path: str) -> Dict[str, Any]:
"""Load configuration from YAML file."""
if os.path.exists(config_path):
with open(config_path, 'r') as f:
return yaml.safe_load(f)
else:
logger.warning(f"Config file {config_path} not found, using defaults")
return {}
def setup_environment(self):
"""Setup environment and directories."""
load_dotenv()
# Create necessary directories
os.makedirs("./logs", exist_ok=True)
os.makedirs("./kb_index", exist_ok=True)
os.makedirs("./experiences", exist_ok=True)
async def demo_knowledge_base_indexing(self):
"""Demonstrate knowledge base indexing."""
print("\n" + "="*60)
print("DEMO 1: Knowledge Base Indexing")
print("="*60)
# Initialize knowledge base
kb_config = self.config.get('knowledge_base', {})
self.knowledge_base = KnowledgeBase(
index_path=kb_config.get('index', {}).get('path', './kb_index'),
model_name=kb_config.get('index', {}).get('embedding_model', 'all-MiniLM-L6-v2')
)
# Check if validation file exists
validation_file = self.config.get('dataset', {}).get('validation_file', 'gaia-validation.jsonl')
if os.path.exists(validation_file):
print(f"\n📚 Indexing GAIA validation data from {validation_file}...")
self.knowledge_base.index_gaia_validation(validation_file)
# Show statistics
stats = self.knowledge_base.get_statistics()
print(f"\n✅ Indexing complete!")
print(f" - Total documents: {stats['total_documents']}")
print(f" - Has embeddings: {stats['has_embeddings']}")
print(f" - Sources: {stats['sources']}")
# Demo search
test_query = "How to find information about scientific papers on arXiv?"
print(f"\n🔍 Testing search with query: '{test_query}'")
results = self.knowledge_base.search(test_query, top_k=3)
print(f"\n📋 Found {len(results)} relevant experiences:")
for i, result in enumerate(results, 1):
print(f"\n {i}. Question: {result.get('question', 'N/A')[:100]}...")
print(f" Approach: {result.get('approach', 'N/A')[:100]}...")
if result.get('tools_used'):
print(f" Tools: {', '.join(result['tools_used'][:3])}")
else:
print(f"\n⚠️ Validation file not found: {validation_file}")
print(" Creating synthetic experiences for demo...")
# Add synthetic experiences
synthetic_experiences = [
{
'question': "How to search for papers on arXiv?",
'approach': "Use web search to find arXiv, then use their search functionality",
'tools_used': ["web_browser", "search_engine"],
'answer': "Navigate to arxiv.org and use the search bar"
},
{
'question': "Calculate the distance between Earth and Moon",
'approach': "Search for astronomical data and perform calculations",
'tools_used': ["calculator", "web_search"],
'answer': "384,400 km average distance"
}
]
for exp in synthetic_experiences:
self.knowledge_base.add_experience(exp['question'], exp)
print(f"✅ Added {len(synthetic_experiences)} synthetic experiences")
async def demo_trajectory_summarization(self):
"""Demonstrate trajectory summarization."""
print("\n" + "="*60)
print("DEMO 2: Trajectory Summarization")
print("="*60)
# Initialize summarizerOpenAI 直连,缺 Key 时 OpenRouter 兜底)
summarizer_model = self.config.get('learning', {}).get('summarizer', {}).get('model', DEFAULT_MODEL)
llm_kwargs = resolve_llm(model_override=summarizer_model)
agent_config = AgentConfig(**llm_kwargs)
self.summarizer = TrajectorySummarizer(
llm_config=agent_config,
model_name=llm_kwargs["llm_model_name"]
)
# Create sample trajectory
sample_trajectory = [
{
'action': {
'tool_name': 'web_search',
'params': {'query': 'arxiv.org AI regulation 2022'}
}
},
{
'action': {
'tool_name': 'browser_navigate',
'params': {'url': 'https://arxiv.org/search'}
}
},
{
'action': {
'tool_name': 'browser_click',
'params': {'element': 'advanced_search'}
}
},
{
'action': {
'tool_name': 'browser_fill',
'params': {'field': 'date_range', 'value': '2022-06-01 to 2022-07-01'}
}
}
]
# Create mock response
class MockResponse:
def __init__(self):
self.answer = "The paper shows a figure with three axes labeled: deontological, egalitarian, utilitarian"
print("\n📝 Summarizing sample trajectory...")
print(f" Trajectory has {len(sample_trajectory)} steps")
summary = await self.summarizer.summarize(
question="Find AI regulation paper from June 2022 on arXiv",
response=MockResponse(),
trajectory=sample_trajectory
)
print("\n✅ Summary generated:")
print(f" - Summary: {summary.get('summary', 'N/A')}")
print(f" - Approach: {summary.get('approach', 'N/A')}")
print(f" - Tools used: {', '.join(summary.get('tools_used', []))}")
if summary.get('key_insights'):
print(f" - Key insights:")
for insight in summary['key_insights']:
print(f" • {insight}")
async def demo_experience_agent(self):
"""Demonstrate the experience agent."""
print("\n" + "="*60)
print("DEMO 3: Experience Agent")
print("="*60)
# Initialize agent with all featuresOpenAI 直连,缺 Key 时 OpenRouter 兜底)
agent_config = AgentConfig(
**resolve_llm(),
llm_temperature=0.0
)
# Basic system prompt
system_prompt = """You are an intelligent agent capable of learning from experience.
When solving problems, you can leverage past experiences to find better solutions.
Always provide your answer in the format: <answer>YOUR_ANSWER</answer>"""
self.agent = ExperienceAgent(
conf=agent_config,
name="demo_experience_agent",
system_prompt=system_prompt,
learning_mode=True,
apply_experience=True,
experience_db_path="./experiences/demo_experiences.json",
knowledge_base=self.knowledge_base,
summarizer=self.summarizer
)
print("\n🤖 Experience Agent initialized with:")
print(f" - Learning mode: {self.agent.learning_mode}")
print(f" - Apply experience: {self.agent.apply_experience}")
print(f" - Existing experiences: {len(self.agent.experiences)}")
# Test questions
test_questions = [
"What is the capital of France?",
"How many days are there in February during a leap year?"
]
for i, question in enumerate(test_questions, 1):
print(f"\n📌 Test Question {i}: {question}")
# Check for relevant experiences
relevant_exp = self.agent._get_relevant_experiences(question)
if relevant_exp:
print(f" Found {len(relevant_exp)} relevant experiences")
else:
print(" No relevant experiences found")
# Create task
task = Task(
input=question,
agent=self.agent,
conf=TaskConfig()
)
try:
# Execute task
print(" Executing task...")
response = await self.agent.execute_task(task)
if response and response.answer:
print(f" ✅ Answer: {response.answer[:100]}...")
else:
print(" ❌ No answer generated")
except Exception as e:
print(f" ❌ Error: {e}")
# Show learned experiences
if self.agent.experiences:
print(f"\n📚 Learned Experiences ({len(self.agent.experiences)} total):")
for exp_id, exp in list(self.agent.experiences.items())[:3]:
print(f"\n Experience ID: {exp_id[:8]}...")
print(f" Question: {exp.get('question', 'N/A')[:80]}...")
print(f" Summary: {exp.get('summary', 'N/A')[:80]}...")
async def demo_workflow(self):
"""Demonstrate complete workflow."""
print("\n" + "="*60)
print("COMPLETE EXPERIENCE LEARNING WORKFLOW DEMO")
print("="*60)
# Step 1: Index knowledge base
await self.demo_knowledge_base_indexing()
# Step 2: Setup summarizer
await self.demo_trajectory_summarization()
# Step 3: Run agent with experience learning
await self.demo_experience_agent()
print("\n" + "="*60)
print("DEMO COMPLETE!")
print("="*60)
# Summary statistics
if self.knowledge_base:
kb_stats = self.knowledge_base.get_statistics()
print(f"\n📊 Final Statistics:")
print(f" - Knowledge base documents: {kb_stats['total_documents']}")
if self.agent:
print(f" - Learned experiences: {len(self.agent.experiences)}")
print(f" - Experience DB: {self.agent.experience_db_path}")
async def run_interactive_mode(self):
"""Run interactive mode for testing."""
print("\n" + "="*60)
print("INTERACTIVE MODE")
print("="*60)
print("\nCommands:")
print(" 1. Index knowledge base")
print(" 2. Test trajectory summarization")
print(" 3. Run experience agent")
print(" 4. Run complete workflow")
print(" 5. Exit")
while True:
try:
choice = input("\nEnter command (1-5): ").strip()
if choice == "1":
await self.demo_knowledge_base_indexing()
elif choice == "2":
await self.demo_trajectory_summarization()
elif choice == "3":
await self.demo_experience_agent()
elif choice == "4":
await self.demo_workflow()
elif choice == "5":
print("\nGoodbye!")
break
else:
print("Invalid choice. Please enter 1-5.")
except KeyboardInterrupt:
print("\n\nInterrupted by user.")
break
except Exception as e:
logger.error(f"Error in interactive mode: {e}")
print(f"\n❌ Error: {e}")
async def main():
"""Main entry point for demo."""
demo = ExperienceLearningDemo()
# Check for command line arguments
import sys
if len(sys.argv) > 1:
if sys.argv[1] == "--interactive":
await demo.run_interactive_mode()
elif sys.argv[1] == "--kb":
await demo.demo_knowledge_base_indexing()
elif sys.argv[1] == "--summarize":
await demo.demo_trajectory_summarization()
elif sys.argv[1] == "--agent":
await demo.demo_experience_agent()
else:
await demo.demo_workflow()
else:
# Run complete workflow by default
await demo.demo_workflow()
if __name__ == "__main__":
print("\n🚀 Experience Learning System Demo")
print("=" * 60)
# Run the demo
asyncio.run(main())