You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using instructor.Mode.ANTHROPIC_TOOLS, and generation doesn't pass the Pydantic validation, Instructor sends a user message validation error text ... to retry generation.
However, this is a mistake, since after a tool_call, we must always send a tool_response. This causes Anthropic to reject the retry with 400: tool_use ids were found without tool_result blocks immediately after.
Environment
instructor 1.11.3 (from PyPI)
Anthropic model: claude-3-haiku-20240307
Using instructor.from_anthropic(..., mode=instructor.Mode.ANTHROPIC_TOOLS)
Repro steps
Script (also saved in our repo at repro_instructor_anthropic_tools.py):
importre, json, httpx, anthropic, instructorfromdotenvimportload_dotenvfrompathlibimportPathfrompydanticimportBaseModel, Field, field_validatorC_IDENTIFIER_PATTERN=re.compile(r"[A-Za-z_][A-Za-z0-9_]*")
classCommandPortCycle(BaseModel):
port_list: list[str]
classCommandBase(BaseModel):
name: strdescription: strsymbol: str=Field(description="e.g., 'ACT', 'RD', 'WR'")
cycles: list[CommandPortCycle]
@field_validator("symbol")defvalid(cls, v):
ifnotC_IDENTIFIER_PATTERN.fullmatch(v):
raiseValueError(f"symbol must be a valid C identifier: {v}")
returnvclassCommandBaseList(BaseModel):
command_base_list: list[CommandBase]
defmain():
load_dotenv()
requests= []
defcap(req: httpx.Request):
body=req.content.decode("utf-8")
requests.append({"url": str(req.url), "body": json.loads(body)})
http_client=httpx.Client(event_hooks={"request": [cap]})
client=instructor.from_anthropic(
anthropic.Anthropic(http_client=http_client),
mode=instructor.Mode.ANTHROPIC_TOOLS,
)
try:
client.chat.completions.create(
model="claude-3-haiku-20240307",
messages=[{"role": "user", "content": "Return one command with symbol set to 'AUTO PRE' exactly (keep the space). Use CommandBaseList as the schema."}],
response_model=CommandBaseList,
temperature=0,
max_tokens=2000,
)
exceptExceptionasexc:
print("Caught exception:", exc)
Path("outputs/repro_requests.json").write_text(json.dumps(requests, indent=2))
if__name__=="__main__":
main()
Ensure ANTHROPIC_API_KEY is set (in .env or env).
Run uv run python repro_instructor_anthropic_tools.py.
Expected
First call fails Pydantic validation (symbol AUTO PRE not a C identifier).
Instructor should send the retry message as a "tool_response" type, rather than a user message. (Or alternatively, add a dummy tool response before the user message.)
Actual
Retry request messages sent to Anthropic include:
user prompt
assistant tool_use with id toolu_01LFNACj9EiGHstThekZzJkn
user validation-error message but no tool_result following the tool_use.
Anthropic returns 400: messages.2: tool_use ids were found without tool_result blocks immediately after: toolu_01LFNACj9EiGHstThekZzJkn....
When using
instructor.Mode.ANTHROPIC_TOOLS, and generation doesn't pass the Pydantic validation, Instructor sends a user messagevalidation error text ...to retry generation.However, this is a mistake, since after a tool_call, we must always send a tool_response. This causes Anthropic to reject the retry with 400:
tool_use ids were found without tool_result blocks immediately after.Environment
instructor.from_anthropic(..., mode=instructor.Mode.ANTHROPIC_TOOLS)Repro steps
repro_instructor_anthropic_tools.py):ANTHROPIC_API_KEYis set (in .env or env).uv run python repro_instructor_anthropic_tools.py.Expected
AUTO PREnot a C identifier).Actual
tool_usewith idtoolu_01LFNACj9EiGHstThekZzJknbut no tool_result following the tool_use.
messages.2: tool_use ids were found without tool_result blocks immediately after: toolu_01LFNACj9EiGHstThekZzJkn....outputs/repro_requests.jsonfrom the repro): request use function call argument to force function call #2/3 shows the malformed history.