diff --git a/messages/en/settings.json b/messages/en/settings.json
index 5b3044f2d..e63e3c253 100644
--- a/messages/en/settings.json
+++ b/messages/en/settings.json
@@ -574,6 +574,18 @@
       "statusEnabled": "enabled",
       "statusDisabled": "disabled"
     },
+    "inlineEdit": {
+      "save": "Save",
+      "cancel": "Cancel",
+      "saveSuccess": "Saved successfully",
+      "saveFailed": "Save failed",
+      "priorityLabel": "Priority",
+      "weightLabel": "Weight",
+      "costMultiplierLabel": "Cost Multiplier",
+      "priorityInvalid": "Please enter an integer >= 0",
+      "weightInvalid": "Please enter an integer between 1 and 100",
+      "costMultiplierInvalid": "Please enter a non-negative number"
+    },
     "schedulingDialog": {
       "title": "Provider Scheduling Rules",
       "description": "Understand how the system intelligently selects upstream providers for high availability and cost optimization",
diff --git a/messages/ja/settings.json b/messages/ja/settings.json
index 58d493575..a964040a2 100644
--- a/messages/ja/settings.json
+++ b/messages/ja/settings.json
@@ -1448,6 +1448,18 @@
       "statusEnabled": "有効",
       "statusDisabled": "無効"
     },
+    "inlineEdit": {
+      "save": "保存",
+      "cancel": "キャンセル",
+      "saveSuccess": "保存に成功しました",
+      "saveFailed": "保存に失敗しました",
+      "priorityLabel": "優先度",
+      "weightLabel": "重み",
+      "costMultiplierLabel": "コスト倍率",
+      "priorityInvalid": "0 以上の整数を入力してください",
+      "weightInvalid": "1〜100 の整数を入力してください",
+      "costMultiplierInvalid": "0以上の数値を入力してください"
+    },
     "schedulingDialog": {
       "title": "プロバイダースケジューリングルール",
       "description": "システムが高可用性とコスト最適化のために上流プロバイダーをインテリジェントに選択する方法を理解する",
diff --git a/messages/ru/settings.json b/messages/ru/settings.json
index 97ed8c673..0a4ff1ecc 100644
--- a/messages/ru/settings.json
+++ b/messages/ru/settings.json
@@ -1448,6 +1448,18 @@
       "statusEnabled": "включен",
       "statusDisabled": "отключен"
     },
+    "inlineEdit": {
+      "save": "Сохранить",
+      "cancel": "Отмена",
+      "saveSuccess": "Успешно сохранено",
+      "saveFailed": "Не удалось сохранить",
+      "priorityLabel": "Приоритет",
+      "weightLabel": "Вес",
+      "costMultiplierLabel": "Коэф цены",
+      "priorityInvalid": "Введите целое число >= 0",
+      "weightInvalid": "Введите целое число от 1 до 100",
+      "costMultiplierInvalid": "Введите число не меньше 0"
+    },
     "schedulingDialog": {
       "title": "Правила планирования провайдеров",
       "description": "Узнайте, как система интеллектуально выбирает вышестоящих провайдеров для высокой доступности и оптимизации затрат",
diff --git a/messages/zh-CN/settings.json b/messages/zh-CN/settings.json
index 1e806e995..dfda03d97 100644
--- a/messages/zh-CN/settings.json
+++ b/messages/zh-CN/settings.json
@@ -187,6 +187,18 @@
       "statusEnabled": "启用",
       "statusDisabled": "禁用"
     },
+    "inlineEdit": {
+      "save": "保存",
+      "cancel": "取消",
+      "saveSuccess": "保存成功",
+      "saveFailed": "保存失败",
+      "priorityLabel": "优先级",
+      "weightLabel": "权重",
+      "costMultiplierLabel": "成本倍数",
+      "priorityInvalid": "请输入大于等于 0 的整数",
+      "weightInvalid": "请输入 1-100 之间的整数",
+      "costMultiplierInvalid": "请输入大于等于 0 的数字"
+    },
     "schedulingDialog": {
       "title": "供应商调度规则说明",
       "description": "了解系统如何智能选择上游供应商，确保高可用性和成本优化",
diff --git a/messages/zh-TW/settings.json b/messages/zh-TW/settings.json
index 1edfdb61c..320009d6e 100644
--- a/messages/zh-TW/settings.json
+++ b/messages/zh-TW/settings.json
@@ -1454,6 +1454,18 @@
       "statusEnabled": "啟用",
       "statusDisabled": "禁用"
     },
+    "inlineEdit": {
+      "save": "保存",
+      "cancel": "取消",
+      "saveSuccess": "保存成功",
+      "saveFailed": "保存失敗",
+      "priorityLabel": "優先級",
+      "weightLabel": "權重",
+      "costMultiplierLabel": "成本倍數",
+      "priorityInvalid": "請輸入大於等於 0 的整數",
+      "weightInvalid": "請輸入 1-100 之間的整數",
+      "costMultiplierInvalid": "請輸入大於等於 0 的數字"
+    },
     "schedulingDialog": {
       "title": "供應商調度規則說明",
       "description": "了解系統如何智慧選擇上游供應商，確保高可用性和成本優化",
diff --git a/src/app/[locale]/settings/providers/_components/inline-edit-popover.tsx b/src/app/[locale]/settings/providers/_components/inline-edit-popover.tsx
new file mode 100644
index 000000000..d6bc237e7
--- /dev/null
+++ b/src/app/[locale]/settings/providers/_components/inline-edit-popover.tsx
@@ -0,0 +1,185 @@
+"use client";
+
+import { Loader2 } from "lucide-react";
+import { useTranslations } from "next-intl";
+import type * as React from "react";
+import { useEffect, useMemo, useRef, useState } from "react";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
+import { cn } from "@/lib/utils";
+
+export interface InlineEditPopoverProps {
+  value: number;
+  label: string;
+  onSave: (value: number) => Promise<boolean>; // 返回是否成功
+  validator: (value: string) => string | null; // 返回 null 表示有效，否则返回错误信息
+  disabled?: boolean;
+  suffix?: string; // 如 "x" 用于 costMultiplier 显示
+  type?: "integer" | "number"; // 输入类型
+}
+
+export function InlineEditPopover({
+  value,
+  label,
+  onSave,
+  validator,
+  disabled = false,
+  suffix,
+  type = "number",
+}: InlineEditPopoverProps) {
+  const t = useTranslations("settings.providers.inlineEdit");
+  const [open, setOpen] = useState(false);
+  const [draft, setDraft] = useState(() => value.toString());
+  const [saving, setSaving] = useState(false);
+
+  const inputRef = useRef<HTMLInputElement>(null);
+  const initialValueRef = useRef<number>(value);
+
+  const trimmedDraft = draft.trim();
+
+  const validationError = useMemo(() => {
+    return validator(trimmedDraft);
+  }, [trimmedDraft, validator]);
+
+  const parsedValue = useMemo(() => {
+    if (trimmedDraft.length === 0) return null;
+    const numeric = Number(trimmedDraft);
+    if (Number.isNaN(numeric)) return null;
+    if (type === "integer" && !Number.isInteger(numeric)) return null;
+    return numeric;
+  }, [trimmedDraft, type]);
+
+  const canSave = !disabled && !saving && validationError == null && parsedValue != null;
+
+  useEffect(() => {
+    if (!open) return;
+    const raf = requestAnimationFrame(() => {
+      inputRef.current?.focus();
+      inputRef.current?.select();
+    });
+    return () => cancelAnimationFrame(raf);
+  }, [open]);
+
+  const stopPropagation = (e: React.SyntheticEvent) => {
+    e.stopPropagation();
+  };
+
+  const resetDraft = () => {
+    setDraft(initialValueRef.current.toString());
+  };
+
+  const handleOpenChange = (nextOpen: boolean) => {
+    if (disabled && nextOpen) return;
+
+    if (nextOpen) {
+      initialValueRef.current = value;
+      setDraft(value.toString());
+    } else {
+      resetDraft();
+      setSaving(false);
+    }
+
+    setOpen(nextOpen);
+  };
+
+  const handleCancel = () => {
+    resetDraft();
+    setOpen(false);
+  };
+
+  const handleSave = async () => {
+    if (!canSave || parsedValue == null) return;
+
+    setSaving(true);
+    try {
+      const ok = await onSave(parsedValue);
+      if (ok) {
+        setOpen(false);
+      }
+    } finally {
+      setSaving(false);
+    }
+  };
+
+  return (
+    <Popover open={open} onOpenChange={handleOpenChange}>
+      <PopoverTrigger asChild>
+        <button
+          type="button"
+          disabled={disabled}
+          className={cn(
+            "tabular-nums font-medium underline-offset-4 rounded-sm",
+            "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
+            disabled ? "cursor-default text-muted-foreground" : "cursor-pointer hover:underline"
+          )}
+          onPointerDown={stopPropagation}
+          onClick={stopPropagation}
+        >
+          {value}
+          {suffix}
+        </button>
+      </PopoverTrigger>
+
+      <PopoverContent
+        align="center"
+        side="bottom"
+        sideOffset={6}
+        className="w-auto p-3"
+        onPointerDown={stopPropagation}
+        onClick={stopPropagation}
+      >
+        <div className="grid gap-2">
+          <div className="text-xs font-medium">{label}</div>
+
+          <div className="flex items-center gap-2">
+            <Input
+              ref={inputRef}
+              value={draft}
+              onChange={(e) => setDraft(e.target.value)}
+              disabled={disabled || saving}
+              className="w-24 tabular-nums"
+              aria-label={label}
+              aria-invalid={validationError != null}
+              type="number"
+              inputMode="decimal"
+              step={type === "integer" ? "1" : "any"}
+              onPointerDown={stopPropagation}
+              onClick={stopPropagation}
+              onKeyDown={(e) => {
+                e.stopPropagation();
+                if (e.key === "Escape") {
+                  e.preventDefault();
+                  handleCancel();
+                }
+                if (e.key === "Enter") {
+                  e.preventDefault();
+                  void handleSave();
+                }
+              }}
+            />
+            {suffix && <span className="text-sm text-muted-foreground">{suffix}</span>}
+          </div>
+
+          {validationError && <div className="text-xs text-destructive">{validationError}</div>}
+
+          <div className="flex items-center justify-end gap-2 pt-1">
+            <Button
+              type="button"
+              size="sm"
+              variant="outline"
+              onClick={handleCancel}
+              disabled={saving}
+            >
+              {t("cancel")}
+            </Button>
+            <Button type="button" size="sm" onClick={handleSave} disabled={!canSave}>
+              {saving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
+              {t("save")}
+            </Button>
+          </div>
+        </div>
+      </PopoverContent>
+    </Popover>
+  );
+}
diff --git a/src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx b/src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx
index facf8a253..30aa6a0fd 100644
--- a/src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx
+++ b/src/app/[locale]/settings/providers/_components/provider-rich-list-item.tsx
@@ -42,7 +42,7 @@ import {
   DialogTitle,
 } from "@/components/ui/dialog";
 import { Switch } from "@/components/ui/switch";
-import { PROVIDER_GROUP } from "@/lib/constants/provider.constants";
+import { PROVIDER_GROUP, PROVIDER_LIMITS } from "@/lib/constants/provider.constants";
 import { getProviderTypeConfig, getProviderTypeTranslationKey } from "@/lib/provider-type-utils";
 import { copyToClipboard, isClipboardSupported } from "@/lib/utils/clipboard";
 import { getContrastTextColor, getGroupColor } from "@/lib/utils/color";
@@ -51,6 +51,7 @@ import { formatCurrency } from "@/lib/utils/currency";
 import type { ProviderDisplay } from "@/types/provider";
 import type { User } from "@/types/user";
 import { ProviderForm } from "./forms/provider-form";
+import { InlineEditPopover } from "./inline-edit-popover";
 
 interface ProviderRichListItemProps {
   provider: ProviderDisplay;
@@ -95,6 +96,35 @@ export function ProviderRichListItem({
   const tTypes = useTranslations("settings.providers.types");
   const tList = useTranslations("settings.providers.list");
   const tTimeout = useTranslations("settings.providers.form.sections.timeout");
+  const tInline = useTranslations("settings.providers.inlineEdit");
+
+  const validatePriority = (raw: string) => {
+    if (raw.length === 0) return tInline("priorityInvalid");
+    const value = Number(raw);
+    if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0 || value > 2147483647)
+      return tInline("priorityInvalid");
+    return null;
+  };
+
+  const validateWeight = (raw: string) => {
+    if (raw.length === 0) return tInline("weightInvalid");
+    const value = Number(raw);
+    if (
+      !Number.isFinite(value) ||
+      !Number.isInteger(value) ||
+      value < PROVIDER_LIMITS.WEIGHT.MIN ||
+      value > PROVIDER_LIMITS.WEIGHT.MAX
+    )
+      return tInline("weightInvalid");
+    return null;
+  };
+
+  const validateCostMultiplier = (raw: string) => {
+    if (raw.length === 0) return tInline("costMultiplierInvalid");
+    const value = Number(raw);
+    if (!Number.isFinite(value) || value < 0) return tInline("costMultiplierInvalid");
+    return null;
+  };
 
   // 获取供应商类型配置
   const typeConfig = getProviderTypeConfig(provider.providerType);
@@ -254,6 +284,32 @@ export function ProviderRichListItem({
     });
   };
 
+  const createSaveHandler = (fieldName: "priority" | "weight" | "cost_multiplier") => {
+    return async (value: number) => {
+      try {
+        const res = await editProvider(provider.id, { [fieldName]: value } as Parameters<
+          typeof editProvider
+        >[1]);
+        if (res.ok) {
+          toast.success(tInline("saveSuccess"));
+          queryClient.invalidateQueries({ queryKey: ["providers"] });
+          router.refresh();
+          return true;
+        }
+        toast.error(tInline("saveFailed"), { description: res.error || tList("unknownError") });
+        return false;
+      } catch (error) {
+        console.error(`更新 ${fieldName} 失败:`, error);
+        toast.error(tInline("saveFailed"), { description: tList("unknownError") });
+        return false;
+      }
+    };
+  };
+
+  const handleSavePriority = createSaveHandler("priority");
+  const handleSaveWeight = createSaveHandler("weight");
+  const handleSaveCostMultiplier = createSaveHandler("cost_multiplier");
+
   return (
     <>
       <div className="flex items-center gap-4 py-3 px-4 border-b hover:bg-muted/50 transition-colors">
@@ -393,15 +449,52 @@ export function ProviderRichListItem({
         <div className="hidden md:grid grid-cols-3 gap-4 text-center flex-shrink-0">
           <div>
             <div className="text-xs text-muted-foreground">{tList("priority")}</div>
-            <div className="font-medium">{provider.priority}</div>
+            <div className="font-medium">
+              {canEdit ? (
+                <InlineEditPopover
+                  value={provider.priority}
+                  label={tInline("priorityLabel")}
+                  type="integer"
+                  validator={validatePriority}
+                  onSave={handleSavePriority}
+                />
+              ) : (
+                <span>{provider.priority}</span>
+              )}
+            </div>
           </div>
           <div>
             <div className="text-xs text-muted-foreground">{tList("weight")}</div>
-            <div className="font-medium">{provider.weight}</div>
+            <div className="font-medium">
+              {canEdit ? (
+                <InlineEditPopover
+                  value={provider.weight}
+                  label={tInline("weightLabel")}
+                  type="integer"
+                  validator={validateWeight}
+                  onSave={handleSaveWeight}
+                />
+              ) : (
+                <span>{provider.weight}</span>
+              )}
+            </div>
           </div>
           <div>
             <div className="text-xs text-muted-foreground">{tList("costMultiplier")}</div>
-            <div className="font-medium">{provider.costMultiplier}x</div>
+            <div className="font-medium">
+              {canEdit ? (
+                <InlineEditPopover
+                  value={provider.costMultiplier}
+                  label={tInline("costMultiplierLabel")}
+                  validator={validateCostMultiplier}
+                  onSave={handleSaveCostMultiplier}
+                  suffix="x"
+                  type="number"
+                />
+              ) : (
+                <span>{provider.costMultiplier}x</span>
+              )}
+            </div>
           </div>
         </div>
 
diff --git a/src/lib/validation/schemas.test.ts b/src/lib/validation/schemas.test.ts
new file mode 100644
index 000000000..f13fabbcd
--- /dev/null
+++ b/src/lib/validation/schemas.test.ts
@@ -0,0 +1,103 @@
+import { describe, expect, test } from "vitest";
+
+import { CreateProviderSchema, UpdateProviderSchema } from "./schemas";
+
+describe("Provider schemas - priority/weight/costMultiplier 规则对齐", () => {
+  describe("UpdateProviderSchema", () => {
+    test("priority 接受 0 和正整数，拒绝负数", () => {
+      expect(UpdateProviderSchema.safeParse({ priority: -100 }).success).toBe(false);
+      expect(UpdateProviderSchema.safeParse({ priority: -1 }).success).toBe(false);
+      expect(UpdateProviderSchema.safeParse({ priority: 0 }).success).toBe(true);
+      expect(UpdateProviderSchema.safeParse({ priority: 123 }).success).toBe(true);
+    });
+
+    test("weight 接受 1-100 正整数，拒绝 0 和超出范围的值", () => {
+      expect(UpdateProviderSchema.safeParse({ weight: 0 }).success).toBe(false);
+      expect(UpdateProviderSchema.safeParse({ weight: 1 }).success).toBe(true);
+      expect(UpdateProviderSchema.safeParse({ weight: 100 }).success).toBe(true);
+      expect(UpdateProviderSchema.safeParse({ weight: 101 }).success).toBe(false);
+      expect(UpdateProviderSchema.safeParse({ weight: -1 }).success).toBe(false);
+    });
+
+    test("costMultiplier 接受 0 和正数（含小数），使用 coerce 支持字符串转换", () => {
+      expect(UpdateProviderSchema.safeParse({ cost_multiplier: 0 }).success).toBe(true);
+      expect(UpdateProviderSchema.safeParse({ cost_multiplier: 0.5 }).success).toBe(true);
+      expect(UpdateProviderSchema.safeParse({ cost_multiplier: 1.5 }).success).toBe(true);
+      // coerce 会将字符串转为数字
+      expect(UpdateProviderSchema.safeParse({ cost_multiplier: "0.5" }).success).toBe(true);
+      expect(UpdateProviderSchema.safeParse({ cost_multiplier: "1.5" }).success).toBe(true);
+      // 负数被拒绝
+      expect(UpdateProviderSchema.safeParse({ cost_multiplier: -1 }).success).toBe(false);
+    });
+
+    test("非法值被拒绝", () => {
+      // priority: 字符串和 null 被拒绝
+      expect(UpdateProviderSchema.safeParse({ priority: "-100" }).success).toBe(false);
+      expect(UpdateProviderSchema.safeParse({ priority: "abc" }).success).toBe(false);
+      expect(UpdateProviderSchema.safeParse({ priority: null }).success).toBe(false);
+
+      // weight: 字符串和 null 被拒绝
+      expect(UpdateProviderSchema.safeParse({ weight: "0" }).success).toBe(false);
+      expect(UpdateProviderSchema.safeParse({ weight: null }).success).toBe(false);
+
+      // cost_multiplier: 非数字字符串被拒绝
+      expect(UpdateProviderSchema.safeParse({ cost_multiplier: "abc" }).success).toBe(false);
+      // 注意: null 会被 coerce 转为 0 (Number(null) === 0)，所以会通过
+    });
+  });
+
+  describe("CreateProviderSchema", () => {
+    const base = {
+      name: "测试供应商",
+      url: "https://api.example.com",
+      key: "sk-test",
+    };
+
+    test("priority 接受 0 和正整数，拒绝负数", () => {
+      expect(CreateProviderSchema.safeParse({ ...base, priority: -100 }).success).toBe(false);
+      expect(CreateProviderSchema.safeParse({ ...base, priority: -1 }).success).toBe(false);
+      expect(CreateProviderSchema.safeParse({ ...base, priority: 0 }).success).toBe(true);
+      expect(CreateProviderSchema.safeParse({ ...base, priority: 123 }).success).toBe(true);
+    });
+
+    test("weight 接受 1-100 正整数，拒绝 0 和超出范围的值", () => {
+      expect(CreateProviderSchema.safeParse({ ...base, weight: 0 }).success).toBe(false);
+      expect(CreateProviderSchema.safeParse({ ...base, weight: 1 }).success).toBe(true);
+      expect(CreateProviderSchema.safeParse({ ...base, weight: 100 }).success).toBe(true);
+      expect(CreateProviderSchema.safeParse({ ...base, weight: 101 }).success).toBe(false);
+      expect(CreateProviderSchema.safeParse({ ...base, weight: -1 }).success).toBe(false);
+    });
+
+    test("costMultiplier 接受 0 和正数（含小数），使用 coerce 支持字符串转换", () => {
+      expect(CreateProviderSchema.safeParse({ ...base, cost_multiplier: 0 }).success).toBe(true);
+      expect(CreateProviderSchema.safeParse({ ...base, cost_multiplier: 0.5 }).success).toBe(true);
+      expect(CreateProviderSchema.safeParse({ ...base, cost_multiplier: 1.5 }).success).toBe(true);
+      // coerce 会将字符串转为数字
+      expect(CreateProviderSchema.safeParse({ ...base, cost_multiplier: "0.5" }).success).toBe(
+        true
+      );
+      expect(CreateProviderSchema.safeParse({ ...base, cost_multiplier: "1.5" }).success).toBe(
+        true
+      );
+      // 负数被拒绝
+      expect(CreateProviderSchema.safeParse({ ...base, cost_multiplier: -1 }).success).toBe(false);
+    });
+
+    test("非法值被拒绝", () => {
+      // priority: 字符串和 null 被拒绝
+      expect(CreateProviderSchema.safeParse({ ...base, priority: "-100" }).success).toBe(false);
+      expect(CreateProviderSchema.safeParse({ ...base, priority: "abc" }).success).toBe(false);
+      expect(CreateProviderSchema.safeParse({ ...base, priority: null }).success).toBe(false);
+
+      // weight: 字符串和 null 被拒绝
+      expect(CreateProviderSchema.safeParse({ ...base, weight: "0" }).success).toBe(false);
+      expect(CreateProviderSchema.safeParse({ ...base, weight: null }).success).toBe(false);
+
+      // cost_multiplier: 非数字字符串被拒绝
+      expect(CreateProviderSchema.safeParse({ ...base, cost_multiplier: "abc" }).success).toBe(
+        false
+      );
+      // 注意: null 会被 coerce 转为 0 (Number(null) === 0)，所以会通过
+    });
+  });
+});
diff --git a/src/lib/validation/schemas.ts b/src/lib/validation/schemas.ts
index 1dd0baab9..729ab43f1 100644
--- a/src/lib/validation/schemas.ts
+++ b/src/lib/validation/schemas.ts
@@ -331,9 +331,9 @@ export const CreateProviderSchema = z.object({
   is_enabled: z.boolean().optional().default(PROVIDER_DEFAULTS.IS_ENABLED),
   weight: z
     .number()
-    .int()
-    .min(PROVIDER_LIMITS.WEIGHT.MIN)
-    .max(PROVIDER_LIMITS.WEIGHT.MAX)
+    .int("权重必须是整数")
+    .min(PROVIDER_LIMITS.WEIGHT.MIN, "权重不能小于 1")
+    .max(PROVIDER_LIMITS.WEIGHT.MAX, "权重不能超过 100")
     .optional()
     .default(PROVIDER_DEFAULTS.WEIGHT),
   priority: z
@@ -525,9 +525,9 @@ export const UpdateProviderSchema = z
     is_enabled: z.boolean().optional(),
     weight: z
       .number()
-      .int()
-      .min(PROVIDER_LIMITS.WEIGHT.MIN)
-      .max(PROVIDER_LIMITS.WEIGHT.MAX)
+      .int("权重必须是整数")
+      .min(PROVIDER_LIMITS.WEIGHT.MIN, "权重不能小于 1")
+      .max(PROVIDER_LIMITS.WEIGHT.MAX, "权重不能超过 100")
       .optional(),
     priority: z
       .number()
