Skip to content

Populate default args when provided in a tool's args_schema #34384

@msukmanowsky

Description

@msukmanowsky

Checked other resources

  • This is a feature request, not a bug report or usage question.
  • I added a clear and descriptive title that summarizes the feature request.
  • I used the GitHub search to find a similar feature request and didn't find it.
  • I checked the LangChain documentation and API reference to see if this feature already exists.
  • This is not related to the langchain-community package.

Package (Required)

  • langchain
  • langchain-openai
  • langchain-anthropic
  • langchain-classic
  • langchain-core
  • langchain-cli
  • langchain-model-profiles
  • langchain-tests
  • langchain-text-splitters
  • langchain-chroma
  • langchain-deepseek
  • langchain-exa
  • langchain-fireworks
  • langchain-groq
  • langchain-huggingface
  • langchain-mistralai
  • langchain-nomic
  • langchain-ollama
  • langchain-perplexity
  • langchain-prompty
  • langchain-qdrant
  • langchain-xai
  • Other / not sure / general

Feature Description

When a tool is defined to have a Pydantic-based args_schema with default values, LangChain should ensure those defaults are passed to positional or kwargs of the tool.

Currently

from langchain.tools import tool
from pydantic import BaseModel, Field


class SearchArgs(BaseModel):
    query: str = Field(..., description="The query string to use for lexical search.")
    page: int = Field(1, description="The page number of results to return.")
    size: int = Field(10, description="The number of results to return per page.")


@tool("search", args_schema=SearchArgs)
def search_tool(query: str, page: int, size: int) -> str:
    """Perform a lexical search."""
    # Implementation of the search logic goes here
    return f"Search results for query: {query}, page: {page}, size: {size}"


if __name__ == "__main__":
    # This will throw: TypeError: search_tool() missing 2 required positional arguments: 'page' and 'size'
    search_tool.invoke(input={"query": "example"})

While search_tool could set defaults (e.g. def search_tool(query: str, page: int=1, size: int=10)), this repeats what is already defined in SearchArgs and violates DRY.

Use Case

Beyond ensuring you don't need to repeat defaults, this will allow users to use additional functionality in Pydantic such as:

Field(default_factory=...) for dynamic defaults (e.g., default_factory=datetime.now)
@field_validator and @model_validator for input validation/transformation before the tool function is called
alias for field name mapping

Proposed Solution

LangChain could easily handle this by effectively doing:

input = args_schema.model_validate(args_dict_from_llm).model_dump()  # this will be a dict with defaults
tool.invoke(input=input)

We may want to allow folks to customize the call to model_dump as kwargs like by_alias may be important to control for some applications.

If there's consensus that this makes sense, happy to take a crack at implementation!

Alternatives Considered

No response

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    core`langchain-core` package issues & PRsfeature requestRequest for an enhancement / additional functionalitylangchain`langchain` package issues & PRs

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions