递归模式实现指南¶
本指南演示了如何使用Pydantic模型在Instructor中处理递归模式。虽然扁平模式通常更简单易用,但某些用例需要递归结构来有效地表示层次数据。
动机
递归模式在处理以下情况时特别有用:* 嵌套的组织结构 * 文件系统层次结构 * 带有回复的评论线程 * 带有子任务的任务依赖关系 * 抽象语法树
定义一个递归模式¶
以下是如何定义一个递归的Pydantic模型的示例:
from typing import List, Optional
from pydantic import BaseModel, Field
class RecursiveNode(BaseModel):
"""A node that can contain child nodes of the same type."""
name: str = Field(..., description="Name of the node")
value: Optional[str] = Field(
None, description="Optional value associated with the node"
)
children: List["RecursiveNode"] = Field(
default_factory=list, description="List of child nodes"
)
# Required for recursive Pydantic models
RecursiveNode.model_rebuild()
示例用法¶
让我们看看如何使用这个递归模式与Instructor:
import instructor
from openai import OpenAI
client = instructor.from_openai(OpenAI())
def parse_hierarchy(text: str) -> RecursiveNode:
"""Parse text into a hierarchical structure."""
return client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": "You are an expert at parsing text into hierarchical structures.",
},
{
"role": "user",
"content": f"Parse this text into a hierarchical structure: {text}",
},
],
response_model=RecursiveNode,
)
# Example usage
hierarchy = parse_hierarchy(
"""
Company: Acme Corp
- Department: Engineering
- Team: Frontend
- Project: Website Redesign
- Project: Mobile App
- Team: Backend
- Project: API v2
- Project: Database Migration
- Department: Marketing
- Team: Digital
- Project: Social Media Campaign
- Team: Brand
- Project: Logo Refresh
"""
)
验证与最佳实践¶
在处理递归模式时:
- 在定义模型后始终调用
model_rebuild() - 考虑添加最大深度的验证,以防止无限递归
- 正确使用类型提示以保持代码清晰性
- 考虑为特定业务规则实现自定义验证器
from pydantic import model_validator
class RecursiveNodeWithDepth(RecursiveNode):
@model_validator(mode='after')
def validate_depth(self) -> "RecursiveNodeWithDepth":
def check_depth(node: "RecursiveNodeWithDepth", current_depth: int = 0) -> int:
if current_depth > 10: # Maximum allowed depth
raise ValueError("Maximum depth exceeded")
return max(
[check_depth(child, current_depth + 1) for child in node.children],
default=current_depth,
)
check_depth(self)
return self
性能考虑¶
虽然递归模式很强大,但它们对于语言模型来说可能更具挑战性。请考虑以下建议:
- 尽量保持结构尽可能简单
- 使用清晰的命名约定
- 在您的提示中提供好的示例
- 考虑将非常大的结构拆分成更小的块
结论¶
递归模式为处理应用程序中的层次数据结构提供了一种强大的方式。虽然它们比扁平模式需要更谨慎的处理,但在某些使用场景中它们可能是无价的。
有关处理复杂数据结构的更多示例,请查看:1. Query Planning with Dependencies 2. Knowledge Graph Generation