from typing import Any, Dict, List, Tuple


def make_patch(path: Tuple[str, ...], kv: Dict[str, str]) -> Dict[str, Any]:
    """
    path=("个人信息","联系方式"), kv={"电话":"..","邮箱":".."} =>
    {"个人信息":{"联系方式":{"电话":"..","邮箱":".."}}}
    """
    node: Dict[str, Any] = dict(kv)
    for p in reversed(path):
        node = {p: node}
    return node


def slim_docs(docs: List[str], max_doc_chars: int) -> List[str]:
        out = []
        for d in docs or []:
            s = str(d)
            if len(s) > max_doc_chars:
                s = s[:max_doc_chars] + "…"
            out.append(s)
        return out


def merge_dicts(a: Dict, b: Dict) -> Dict:
    return {**a, **b}

def deep_merge(a: Dict[str, Any], b: Dict[str, Any]) -> Dict[str, Any]:
    out = dict(a or {})
    for k, v in (b or {}).items():
        if k in out and isinstance(out[k], dict) and isinstance(v, dict):
            out[k] = deep_merge(out[k], v)
        else:
            out[k] = v
    return out
