[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-82230":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":34,"readmeContent":35,"aiSummary":36,"trendingCount":15,"starSnapshotCount":15,"syncStatus":37,"lastSyncTime":38,"discoverSource":39},82230,"predikit","Tejas-TA\u002Fpredikit","Tejas-TA","The missing bridge between your ML models and your AI agents.","https:\u002F\u002Fpypi.org\u002Fproject\u002Fpredikit\u002F0.1.0\u002F",null,"Python",204,77,60,0,13,167,174,118,95.68,"MIT License",false,"main",true,[26,27,28,29,30,31,32,33],"agents","langchain","llm","machine-learning","openai","python","sklearn","xgboost","2026-06-12 04:01:37","# predikit\n[![PyPI version](https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fv\u002Fpredikit.svg)](https:\u002F\u002Fpypi.org\u002Fproject\u002Fpredikit\u002F)\n[![Python 3.10+](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fpython-3.10+-blue.svg)](https:\u002F\u002Fwww.python.org\u002F)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-green.svg)](LICENSE)\n\n\nTurn any trained scikit-learn or XGBoost model into an LLM-callable tool — auto-generated JSON schemas, typed I\u002FO, zero boilerplate.\n\n```python\ntool = ModelTool(model=clf, name=\"classify_iris\", ...)\ntool.to_openai()              # OpenAI function schema, ready to pass to the API\ntool.invoke({\"sqft\": 2200})   # → {\"price_usd\": 370730}\n```\n\n## Install\n\n```bash\npip install predikit\n\n# With XGBoost support\npip install predikit[xgboost]\n\n# With LangChain support\npip install predikit[langchain]\n\n# With MLflow Model Registry support\npip install predikit[mlflow]\n\n# With Snowflake Model Registry support\npip install predikit[snowflake]\n```\n\n## 30-second example\n\n```python\nfrom pydantic import BaseModel, Field\nfrom sklearn.datasets import load_iris\nfrom sklearn.linear_model import LogisticRegression\nfrom predikit import ModelTool\n\n# Train\nX, y = load_iris(return_X_y=True)\nclf = LogisticRegression(max_iter=200).fit(X, y)\n\n# Define what the LLM will pass in\nclass IrisInput(BaseModel):\n    sepal_length: float = Field(description=\"Sepal length in cm\")\n    sepal_width:  float = Field(description=\"Sepal width in cm\")\n    petal_length: float = Field(description=\"Petal length in cm\")\n    petal_width:  float = Field(description=\"Petal width in cm\")\n\n# Wrap the model\ntool = ModelTool(\n    model=clf,\n    name=\"classify_iris\",\n    description=\"Classify an iris flower: 0=setosa, 1=versicolor, 2=virginica.\",\n    input_schema=IrisInput,\n    output_name=\"species\",\n    output_description=\"Predicted species index\",\n)\n\n# Get an OpenAI-ready schema\nimport json\nprint(json.dumps(tool.to_openai(), indent=2))\n\n# Call it directly\ntool.invoke({\n    \"sepal_length\": 5.1, \"sepal_width\": 3.5,\n    \"petal_length\": 1.4, \"petal_width\": 0.2,\n})\n# → {\"species\": 0}\n```\n\n## Core API\n\n### `ModelTool`\n\n```python\nModelTool(\n    model,               # fitted sklearn-compatible estimator\n    name: str,           # tool name the LLM sees\n    description: str,    # tool description the LLM sees\n    input_schema,        # Pydantic BaseModel describing inputs\n    output_name: str,    # key for the prediction in the returned dict\n    output_description: str,\n)\n```\n\n| Method | Returns | What it does |\n|--------|---------|--------------|\n| `.invoke(input_dict)` | `dict` | Validates → predicts → returns `{output_name: value}` |\n| `.to_openai()` | `dict` | OpenAI function-calling schema |\n| `.to_langchain()` | `StructuredTool` | LangChain tool |\n| `.to_callable()` | `Callable` | Plain Python function |\n\n### `ToolRegistry`\n\nGroup multiple tools for bulk export:\n\n```python\nregistry = ToolRegistry([price_tool, risk_tool])\nregistry.to_openai()     # → list[dict], pass directly to OpenAI\nregistry.to_langchain()  # → list[StructuredTool]\nregistry.get(\"name\")     # → ModelTool\n```\n\n## Field naming rule\n\n**Your Pydantic schema field names must exactly match the column names the model was trained on.**\n\npredikit maps inputs to features by name, not position. If you trained on a DataFrame with columns `[\"sqft\", \"bedrooms\"]`, your schema fields must be `sqft` and `bedrooms` — not `sq_ft`, not `Sqft`.\n\n```python\n# ✓ Columns match: sqft, bedrooms, bathrooms\nclass GoodInput(BaseModel):\n    sqft:      float\n    bedrooms:  float\n    bathrooms: float\n\n# ✗ Name mismatch — raises ValueError at runtime\nclass BadInput(BaseModel):\n    square_footage: float  # model expects \"sqft\"\n    beds:           float  # model expects \"bedrooms\"\n    baths:          float  # model expects \"bathrooms\"\n```\n\nWhen there's a mismatch, predikit tells you exactly which names are wrong:\n\n```\nValueError: Input schema is missing model features: ['sqft', 'bedrooms'].\nSchema has: ['square_footage', 'beds', 'bathrooms'], model expects: ['sqft', 'bedrooms', 'bathrooms']\n```\n\n> **Tip:** If you trained with a numpy array (no DataFrame), predikit has no feature names to check — it uses your schema's field definition order instead.\n\n## Cookbook\n\n### XGBoost regression\n\n```python\nfrom xgboost import XGBRegressor\nfrom predikit import ModelTool\n\nreg = XGBRegressor().fit(X_train, y_train)\n\nclass HouseInput(BaseModel):\n    sqft:       float\n    bedrooms:   float\n    year_built: float\n\ntool = ModelTool(\n    model=reg,\n    name=\"price_estimate\",\n    description=\"Predict home price in USD.\",\n    input_schema=HouseInput,\n    output_name=\"price_usd\",\n    output_description=\"Predicted sale price in USD\",\n)\n```\n\n### Multiple tools in one registry\n\n```python\nregistry = ToolRegistry([price_tool, risk_tool, demand_tool])\n\n# OpenAI\nresponse = client.chat.completions.create(\n    model=\"gpt-4o\",\n    tools=registry.to_openai(),\n    ...\n)\n\n# LangChain\nagent = initialize_agent(tools=registry.to_langchain(), ...)\n```\n\n### Bool inputs from an LLM\n\nLLMs sometimes return `\"yes\"`, `\"true\"`, or `\"1\"` for boolean fields. predikit coerces these automatically before Pydantic validation:\n\n```python\nclass Input(BaseModel):\n    has_pool: bool\n\ntool.invoke({\"has_pool\": \"yes\"})   # → coerced to True\ntool.invoke({\"has_pool\": \"false\"}) # → coerced to False\ntool.invoke({\"has_pool\": \"maybe\"}) # → raises ValueError with clear message\n```\n\nSupported strings: `true\u002Ffalse`, `yes\u002Fno`, `1\u002F0`, `on\u002Foff`.\n\n### Confidence-aware routing\n\nRoute uncertain predictions to a fallback tool, or raise an error the agent can catch:\n\n```python\nfrom predikit import ModelTool, LowConfidenceError\n\ntool = ModelTool(\n    model=clf,\n    name=\"churn_risk\",\n    description=\"Predict member churn risk.\",\n    input_schema=MemberInput,\n    output_name=\"churn_probability\",\n    output_description=\"Probability of churn (0–1)\",\n    confidence_threshold=0.80,       # classifiers with predict_proba only\n    on_low_confidence=\"warn\",        # \"warn\" | \"raise\" | \"fallback\"\n    fallback_tool=rule_based_tool,   # used when mode=\"fallback\"\n)\n\nresult = tool.invoke(inputs)\nif result.get(\"_low_confidence\"):\n    print(f\"Uncertain ({result['_confidence']:.2f}) — consider routing to a human\")\n```\n\n| mode | behaviour |\n|------|-----------|\n| `\"warn\"` | returns prediction + `_confidence` + `_low_confidence: True` |\n| `\"raise\"` | raises `LowConfidenceError` |\n| `\"fallback\"` | invokes `fallback_tool` and returns its result |\n\nOnly applies to classifiers that implement `predict_proba`. Regressors are unaffected.\n\n### Multi-model ensemble\n\nCall multiple models and reconcile their outputs in one step:\n\n```python\nfrom predikit import ModelEnsemble, ToolRegistry\n\nensemble = ModelEnsemble(\n    tools=[price_tool_a, price_tool_b],\n    name=\"averaged_price\",\n    description=\"Ensemble price: mean of two XGBoost models.\",\n    strategy=\"mean\",              # \"collect\" | \"mean\" | \"vote\"\n)\n\nresult  = ensemble.invoke(inputs)  # → {\"price_usd\": 370112}\nschema  = ensemble.to_openai()     # works exactly like ModelTool\n```\n\n| strategy | behaviour |\n|----------|-----------|\n| `\"collect\"` | merges all outputs into one dict (tools can have different `output_name`) |\n| `\"mean\"` | averages numeric outputs (all tools must share `output_name`) |\n| `\"vote\"` | majority class vote (all tools must share `output_name`) |\n\nRegister ensembles alongside individual tools:\n\n```python\nregistry = ToolRegistry(tools=[price_tool], ensembles=[ensemble])\nregistry.to_openai()  # includes both tools and ensembles\n```\n\n### MLflow Model Registry loader\n\nLoad a registered MLflow model directly — no manual `.load_model()` call:\n\n```python\nfrom predikit.loaders import from_mlflow\n\ntool = from_mlflow(\n    model_uri=\"models:\u002Fchurn-classifier\u002FProduction\",\n    name=\"churn_risk\",\n    description=\"Predict member churn probability.\",\n    input_schema=MemberInput,\n    output_name=\"churn_probability\",\n    output_description=\"Churn probability 0–1\",\n)\n\ntool.invoke({\"tenure_months\": 24, \"trips_last_year\": 2, \"avg_spend\": 500})\n# → {\"churn_probability\": 0.73}\n```\n\nThe loader auto-detects `classes_` and `feature_names_in_` from the underlying sklearn model, so confidence routing and ensemble work unchanged. Requires `pip install predikit[mlflow]`.\n\n### Snowflake Model Registry loader\n\nLoad a model registered in the Snowflake Model Registry via the Snowpark ML Python library:\n\n```python\nfrom predikit.loaders import from_snowflake\n\ntool = from_snowflake(\n    session=snowpark_session,\n    model_name=\"VACATION_CHURN\",\n    model_version=\"V3\",\n    name=\"churn_risk\",\n    description=\"Vacation ownership churn classifier.\",\n    input_schema=MemberInput,\n    output_name=\"churn_probability\",\n    output_description=\"Churn probability 0–1\",\n    output_method=\"predict\",   # method to call on the Snowflake model object\n)\n```\n\nPass `output_method=\"predict_proba\"` or any other method your Snowflake model exposes. The returned `ModelTool` is identical to one built directly — all exporters, confidence routing, and ensemble strategies work as-is. Requires `pip install predikit[snowflake]`.\n\n### Orlando real estate demo\n\nSee [`examples\u002F03_orlando_real_estate.py`](examples\u002F03_orlando_real_estate.py) for a full end-to-end walkthrough: synthetic dataset → XGBoost training → `ModelTool` → registry → OpenAI schema → prediction.\n\n## Roadmap\n\nPlanned for later releases:\n\n- HuggingFace \u002F PyTorch \u002F TensorFlow support\n- Async invocation\n- Weighted ensemble strategies\n- CLI (`predikit inspect model.pkl`)\n\n## License\n\nMIT © Tejas Tumakuru Ashok\n","predikit 是一个将机器学习模型转换为可被AI代理调用工具的库。它支持scikit-learn和XGBoost训练好的模型，能够自动生成JSON模式、类型化的输入输出，并且无需编写额外的样板代码。通过简单的几行代码，用户可以将任何已训练的模型封装成符合OpenAI函数调用标准的工具，同时提供直接调用来获取预测结果的功能。此外，predikit还支持LangChain集成以及多种模型注册表服务（如MLflow和Snowflake）。此项目特别适用于需要将传统机器学习模型与现代AI代理技术相结合的应用场景中，比如自动化决策支持系统或者智能客服等。",2,"2026-06-11 04:08:07","CREATED_QUERY"]