참고소스 수정본
This commit is contained in:
61
참고/instructor-main/examples/hooks/README.md
Normal file
61
참고/instructor-main/examples/hooks/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Instructor Hooks Example
|
||||
|
||||
This example demonstrates how to use the Hooks system in the Instructor library to monitor, log, and debug your LLM interactions.
|
||||
|
||||
## What are Hooks?
|
||||
|
||||
Hooks provide a powerful mechanism for intercepting and handling events during the completion and parsing process. They allow you to add custom behavior, logging, or error handling at various stages of the API interaction.
|
||||
|
||||
The Instructor library supports several predefined hooks:
|
||||
|
||||
- `completion:kwargs`: Emitted when completion arguments are provided
|
||||
- `completion:response`: Emitted when a completion response is received
|
||||
- `completion:error`: Emitted when an error occurs during completion
|
||||
- `completion:last_attempt`: Emitted when the last retry attempt is made
|
||||
- `parse:error`: Emitted when an error occurs during response parsing
|
||||
|
||||
## What This Example Shows
|
||||
|
||||
This example demonstrates:
|
||||
|
||||
1. **Basic Hook Registration**: How to register handlers for different hook events
|
||||
2. **Multiple Handlers**: How to register multiple handlers for the same event
|
||||
3. **Statistics Collection**: How to collect and track API usage statistics
|
||||
4. **Error Handling**: How to catch and process different types of errors
|
||||
5. **Hook Cleanup**: How to remove hooks when they're no longer needed
|
||||
|
||||
## Usage Examples
|
||||
|
||||
The code demonstrates three scenarios:
|
||||
|
||||
1. **Successful Extraction**: A basic example that works correctly
|
||||
2. **Parse Error**: An example that triggers a validation error
|
||||
3. **Multiple Hooks**: Shows how to attach multiple handlers to the same event
|
||||
|
||||
## How to Run the Example
|
||||
|
||||
```bash
|
||||
# Navigate to the hooks example directory
|
||||
cd examples/hooks
|
||||
|
||||
# Run the example
|
||||
python run.py
|
||||
```
|
||||
|
||||
## Expected Output
|
||||
|
||||
The example will print detailed information about each request, including:
|
||||
|
||||
- 🔍 Request details (model, prompt)
|
||||
- 📏 Approximate input token count
|
||||
- 📊 Token usage statistics
|
||||
- ✅ Successful responses
|
||||
- ⚠️ Parse errors
|
||||
- ❌ Completion errors
|
||||
- 🔄 Retry attempt notifications
|
||||
|
||||
At the end, it will print a summary of the statistics collected.
|
||||
|
||||
## Learn More
|
||||
|
||||
For more information about hooks in Instructor, see the [hooks documentation](https://instructor-ai.github.io/instructor/concepts/hooks/).
|
||||
204
참고/instructor-main/examples/hooks/run.py
Normal file
204
참고/instructor-main/examples/hooks/run.py
Normal file
@@ -0,0 +1,204 @@
|
||||
"""
|
||||
This example demonstrates how to use hooks in Instructor for monitoring,
|
||||
logging, and debugging your LLM interactions.
|
||||
|
||||
Hooks allow you to attach handlers to events that occur during the completion
|
||||
and parsing process. This can be useful for:
|
||||
- Logging API requests and responses
|
||||
- Debugging parsing errors
|
||||
- Collecting statistics about API usage
|
||||
- Adding custom error handling
|
||||
"""
|
||||
|
||||
import instructor
|
||||
import openai
|
||||
import pydantic
|
||||
|
||||
|
||||
class User(pydantic.BaseModel):
|
||||
"""A simple user model with validation."""
|
||||
|
||||
name: str
|
||||
age: int
|
||||
|
||||
@pydantic.field_validator("age")
|
||||
def validate_age(cls, v: int) -> int:
|
||||
if v < 0:
|
||||
raise ValueError("Age must be non-negative")
|
||||
return v
|
||||
|
||||
|
||||
class CompletionStats:
|
||||
"""A simple class to collect statistics about completions."""
|
||||
|
||||
def __init__(self):
|
||||
self.total_completions = 0
|
||||
self.errors = 0
|
||||
self.successful = 0
|
||||
self.tokens_used = 0
|
||||
|
||||
def report(self):
|
||||
"""Print a report of the statistics."""
|
||||
print("\n--- Completion Statistics ---")
|
||||
print(f"Total completions: {self.total_completions}")
|
||||
print(f"Successful: {self.successful}")
|
||||
print(f"Errors: {self.errors}")
|
||||
print(f"Total tokens used: {self.tokens_used}")
|
||||
|
||||
|
||||
def main():
|
||||
# Initialize the OpenAI client with Instructor
|
||||
client = instructor.from_openai(openai.OpenAI())
|
||||
|
||||
# Create a statistics collector
|
||||
stats = CompletionStats()
|
||||
|
||||
# Define hook handlers
|
||||
def log_completion_kwargs(_, **kwargs):
|
||||
"""Handler for completion:kwargs hook."""
|
||||
stats.total_completions += 1
|
||||
print(
|
||||
f"\n🔍 Sending completion request using model: {kwargs.get('model', 'unknown')}"
|
||||
)
|
||||
if "messages" in kwargs:
|
||||
for msg in kwargs["messages"]:
|
||||
if msg.get("role") == "user":
|
||||
print(f"📝 User prompt: {msg.get('content')}")
|
||||
|
||||
def log_completion_response(response):
|
||||
"""Handler for completion:response hook."""
|
||||
stats.successful += 1
|
||||
|
||||
# Extract token usage if available
|
||||
if hasattr(response, "usage") and response.usage:
|
||||
token_usage = response.usage.total_tokens
|
||||
stats.tokens_used += token_usage
|
||||
print(f"📊 Token usage: {token_usage}")
|
||||
|
||||
print(f"✅ Received completion response")
|
||||
|
||||
def log_completion_error(error):
|
||||
"""Handler for completion:error hook."""
|
||||
stats.errors += 1
|
||||
print(f"❌ Completion error: {type(error).__name__}: {str(error)}")
|
||||
|
||||
def log_parse_error(error):
|
||||
"""Handler for parse:error hook."""
|
||||
stats.errors += 1
|
||||
print(f"⚠️ Parse error: {type(error).__name__}: {str(error)}")
|
||||
|
||||
# Register the hooks
|
||||
client.on("completion:kwargs", log_completion_kwargs)
|
||||
client.on("completion:response", log_completion_response)
|
||||
client.on("completion:error", log_completion_error)
|
||||
client.on(
|
||||
"completion:last_attempt", lambda _: print(f"🔄 Last retry attempt failed")
|
||||
)
|
||||
client.on("parse:error", log_parse_error)
|
||||
|
||||
# Example 1: Successful extraction
|
||||
try:
|
||||
print("\n--- Example 1: Successful Extraction ---")
|
||||
user = client.chat.completions.create(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=[{"role": "user", "content": "Extract: John is 30 years old."}],
|
||||
response_model=User,
|
||||
)
|
||||
print(f"Result: {user}")
|
||||
except Exception as e:
|
||||
print(f"Main exception: {e}")
|
||||
|
||||
# Example 2: Parse error (validation fails)
|
||||
try:
|
||||
print("\n--- Example 2: Parse Error (Age Validation) ---")
|
||||
user = client.chat.completions.create(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=[{"role": "user", "content": "Extract: Alice is -5 years old."}],
|
||||
response_model=User,
|
||||
)
|
||||
print(f"Result: {user}")
|
||||
except Exception as e:
|
||||
print(f"Main exception: {e}")
|
||||
|
||||
# Example 3: Multiple hooks for the same event
|
||||
print("\n--- Example 3: Multiple Hooks ---")
|
||||
|
||||
# Add another hook for completion:kwargs that counts message tokens
|
||||
def count_input_tokens(_, **kwargs):
|
||||
"""Handler for counting approximate tokens in input messages."""
|
||||
if "messages" in kwargs:
|
||||
total_chars = sum(len(msg.get("content", "")) for msg in kwargs["messages"])
|
||||
# Rough approximation of tokens (not accurate)
|
||||
approx_tokens = total_chars / 4
|
||||
print(f"📏 Approximate input tokens: {approx_tokens:.0f}")
|
||||
|
||||
# Register the additional hook
|
||||
client.on("completion:kwargs", count_input_tokens)
|
||||
|
||||
try:
|
||||
user = client.chat.completions.create(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=[{"role": "user", "content": "Extract: Bob is 25 years old."}],
|
||||
response_model=User,
|
||||
)
|
||||
print(f"Result: {user}")
|
||||
except Exception as e:
|
||||
print(f"Main exception: {e}")
|
||||
|
||||
# Print the final statistics
|
||||
stats.report()
|
||||
|
||||
# Clean up hooks
|
||||
print("\n--- Cleaning Up Hooks ---")
|
||||
client.clear()
|
||||
print("All hooks cleared")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
"""
|
||||
|
||||
--- Example 1: Successful Extraction ---
|
||||
|
||||
🔍 Sending completion request using model: gpt-3.5-turbo
|
||||
📝 User prompt: Extract: John is 30 years old.
|
||||
📊 Token usage: 82
|
||||
✅ Received completion response
|
||||
Result: name='John' age=30
|
||||
|
||||
--- Example 2: Parse Error (Age Validation) ---
|
||||
|
||||
🔍 Sending completion request using model: gpt-3.5-turbo
|
||||
📝 User prompt: Extract: Alice is -5 years old.
|
||||
📊 Token usage: 82
|
||||
✅ Received completion response
|
||||
⚠️ Parse error: ValidationError: 1 validation error for User
|
||||
age
|
||||
Value error, Age must be non-negative [type=value_error, input_value=-5, input_type=int]
|
||||
For further information visit https://errors.pydantic.dev/2.9/v/value_error
|
||||
|
||||
🔍 Sending completion request using model: gpt-3.5-turbo
|
||||
📝 User prompt: Extract: Alice is -5 years old.
|
||||
📊 Token usage: 170
|
||||
✅ Received completion response
|
||||
Result: name='Alice' age=5
|
||||
|
||||
--- Example 3: Multiple Hooks ---
|
||||
|
||||
🔍 Sending completion request using model: gpt-3.5-turbo
|
||||
📝 User prompt: Extract: Bob is 25 years old.
|
||||
📏 Approximate input tokens: 7
|
||||
📊 Token usage: 82
|
||||
✅ Received completion response
|
||||
Result: name='Bob' age=25
|
||||
|
||||
--- Completion Statistics ---
|
||||
Total completions: 4
|
||||
Successful: 4
|
||||
Errors: 1
|
||||
Total tokens used: 416
|
||||
|
||||
--- Cleaning Up Hooks ---
|
||||
All hooks cleared
|
||||
"""
|
||||
Reference in New Issue
Block a user