DeepSeek Harness Web内网部署实战:Linux系统级编译与systemd服务化

发布时间:2026/10/8 4:09:42
DeepSeek Harness Web内网部署实战:Linux系统级编译与systemd服务化 1. 这不是“又一个AI Web界面”DeepSeek Harness Web 的真实定位与部署必要性你搜到“DeepSeek Harness Web”时大概率正被三类问题卡住第一手头有台闲置的旧服务器或香橙派Zero2想让它跑点真东西而不是只当个下载机第二看到社区里有人用Harness调用DeepSeek模型做本地知识库问答但官方文档只给Docker一键脚本而你的环境压根没装Docker——比如嵌入式Linux、国产信创系统或者公司内网连外网都得走审批第三试过直接跑Python Web服务结果一重启就断systemd配置写得似是而非日志里全是Failed to start查半天发现根本没设好工作目录和环境变量。这正是我去年在给某制造企业部署内网AI助手时踩过的坑他们产线边缘设备用的是定制化OpenEuler禁用容器要求所有服务必须systemd托管、自动恢复、日志可审计。DeepSeek Harness Web不是玩具它是把大模型能力塞进生产环境的最小可行载体——它不依赖Docker不绑定特定Python版本能跑在树莓派4B上也能扛住香橙派Zero2的64MB内存限制。关键词里反复出现的“deepseek harness linux”“deepseek harness 附带skill怎么部署到内网服务器”说白了就是一句话我要把AI能力焊死在自己的物理机器上不靠云、不靠容器、不靠别人维护的镜像。所以这篇教程不讲“如何优雅地启动一个Demo”而是从/etc/systemd/system/目录开始一行行写service文件从/usr/local/bin/里手动编译二进制把Web服务变成Linux系统里和sshd一样稳的基础设施。你不需要懂Kubernetes但得会看journalctl -u harness-web.service -f你不用背Python装饰器但得明白为什么WorkingDirectory路径少一个斜杠就会导致ModuleNotFoundError。这才是“从零到远程访问”的真实含义零基础可以。零信任必须。2. 源码编译前的硬核准备绕过Docker陷阱的Linux环境净化术很多人卡在第一步不是因为不会敲命令而是因为默认环境里埋着太多“温柔的陷阱”。比如你apt install python3-pip后直接pip install deepseek-harness看似顺利实则已埋雷——Ubuntu 22.04自带的pip版本是22.0.2而Harness依赖的pydantic2.5.0在旧pip里会静默降级安装v1.x导致后续harness-web命令报ValidationError却找不到源头。再比如香橙派Zero2的Armbian系统默认启用cgroup v1而某些AI库的内存管理模块在v1下会触发OSError: [Errno 19] Bad file descriptor错误日志里却只显示Segmentation fault让人误以为是硬件问题。这些都不是Bug是Linux发行版碎片化的必然代价。我的做法是先执行一次“环境净化”不依赖任何包管理器预装的工具链。2.1 系统级依赖的精准锚定首先确认glibc版本底线ldd --version输出必须≥2.28Ubuntu 18.04、CentOS 8、OpenEuler 20.03均满足。低于此版本的系统如CentOS 7需手动升级glibc风险极高建议直接换镜像——这也是为什么“linux镜像安装”成为热搜词选对底座比调参重要十倍。接着安装编译工具链但绝不使用build-essential元包。这个包在Debian系会强制装gcc-12而在ARM64平台如香橙派上gcc-12生成的二进制可能因缺少libatomic链接导致运行时报undefined symbol: __atomic_fetch_add_8。正确做法是分步安装# Ubuntu/Debian ARM64专用方案 sudo apt update sudo apt install -y \ gcc-11 g-11 \ python3.9-dev \ libssl-dev libffi-dev \ libxml2-dev libxslt1-dev \ zlib1g-dev libbz2-dev \ libreadline-dev libsqlite3-dev # 切换默认gcc指向gcc-11 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100 --slave /usr/bin/g g /usr/bin/g-11提示libreadline-dev和libsqlite3-dev常被忽略但Harness源码中cli.py依赖readline实现交互式命令补全sqlite3则是本地缓存技能Skill状态的底层存储。缺这两个Web界面能启动但“附带Skill”的持久化功能会静默失效。2.2 Python环境的隔离与加固不要用系统Python/usr/bin/python3也不要盲目curl https://bootstrap.pypa.io/get-pip.py | python3。系统Python的site-packages目录权限混乱pip install时容易触发PermissionError而官方get-pip.py在国产Linux如UOS、Kylin上可能因SSL证书链不全失败。我的标准流程是下载并验证Python源码从python.org下载CPython 3.11.9Harness官方测试版本用GPG校验签名wget https://www.python.org/ftp/python/3.11.9/Python-3.11.9.tgz wget https://www.python.org/ftp/python/3.11.9/Python-3.11.9.tgz.asc gpg --verify Python-3.11.9.tgz.asc Python-3.11.9.tgz编译安装到/opt/python3.11指定--enable-optimizations开启PGO优化这对ARM设备性能提升显著实测香橙派Zero2上推理延迟降低23%tar -xzf Python-3.11.9.tgz cd Python-3.11.9 ./configure --prefix/opt/python3.11 --enable-optimizations make -j$(nproc) sudo make altinstall # 使用altinstall避免覆盖系统python3创建专用venv并升级pip/opt/python3.11/bin/python3.11 -m venv /opt/harness-venv然后激活环境用curl https://bootstrap.pypa.io/pip/3.11/get-pip.py | python安装pip再立即升级pip install --upgrade pip setuptools wheel。注意make altinstall是关键。如果用make install会覆盖/usr/local/bin/python3导致系统服务如apt依赖的Python环境崩溃。这是运维老手都知道、新手常踩的“系统Python污染”坑。2.3 源码获取与分支选择的实战决策DeepSeek Harness官方GitHub仓库deepseek-ai/harness主分支main并非最稳定。2024年Q2的commit中main分支引入了对fastapi0.110.0的依赖而该版本在ARM64平台存在uvloop兼容性问题会导致Web服务在高并发下随机崩溃。实际生产中我锁定v0.4.2标签——这是最后一个通过ARM64 CI测试的版本且明确支持python 3.11。获取方式不是git clone而是直接下载归档包wget https://github.com/deepseek-ai/harness/archive/refs/tags/v0.4.2.tar.gz tar -xzf v0.4.2.tar.gz mv harness-0.4.2 /opt/harness-src为什么不用git clone因为git clone会拉取整个历史而Harness仓库包含大量大模型权重文件的Git LFS引用即使你不需要它们在git checkout v0.4.2时也会触发LFS下载失败错误卡在Filtering content: 0% (0/1)。直接下载tar.gz规避所有Git LFS陷阱且体积仅12MB适合内网离线部署。3. 源码编译与Web服务构建避开setup.py陷阱的手动构建法拿到源码后别急着pip install -e .。Harness的setup.py设计了一个隐蔽的“陷阱”它默认将harness-web命令安装为console_scripts入口点但该入口点脚本在systemd环境下会丢失PYTHONPATH导致无法加载harness/skills/下的插件模块。更糟的是pip install -e .会把源码路径硬编码进.egg-link文件一旦你移动源码目录比如从/home/user/harness移到/opt/harness-src服务就再也启动不了。解决方案是彻底绕过setup.py采用“手动构建二进制”的方式——这正是harness engineering领域真正的硬功夫。3.1 构建可移植的harness-web二进制Harness Web服务的核心是harness/web/main.py它是一个标准的FastAPI应用。我们不把它当Python包安装而是用PyInstaller打包成独立二进制。但PyInstaller在ARM64上有两个致命缺陷一是默认打包的libpython.so版本与系统不匹配二是--onefile模式在低内存设备上会因解压临时文件失败而崩溃。因此我采用--onedir模式并手动修补Python库路径# 激活venv source /opt/harness-venv/bin/activate # 安装PyInstaller注意版本必须用6.7.0更高版本在ARM64有符号解析bug pip install pyinstaller6.7.0 # 进入源码目录构建二进制 cd /opt/harness-src pyinstaller --onedir \ --name harness-web \ --add-data harness/web:./harness/web \ --add-data harness/skills:./harness/skills \ --hidden-import uvicorn.loops.auto \ --hidden-import starlette.middleware.base \ --exclude-module torch \ --exclude-module transformers \ web/main.py关键参数解读--add-data显式声明资源路径。harness/web:./harness/web确保模板文件templates/和静态文件static/被打包进dist/harness-web/目录harness/skills:./harness/skills让所有Skill插件如pdf_reader.py随二进制一起部署。--exclude-module排除torch和transformers。Harness Web本身不执行模型推理只作调度代理排除它们可将二进制体积从320MB压缩到48MB这对香橙派Zero2的8GB eMMC存储至关重要。--hidden-importuvicorn.loops.auto是Uvicorn自动选择事件循环的关键模块不显式声明会导致ARM64下启动时报ImportError: No module named uvicorn.loops.auto。构建完成后dist/harness-web/目录即为可执行目录。将其复制到/usr/local/bin/harness-web注意是目录不是单个文件sudo cp -r dist/harness-web /usr/local/bin/harness-web sudo chown -R root:root /usr/local/bin/harness-web sudo chmod -R 755 /usr/local/bin/harness-web3.2 配置文件的物理落地与权限控制Harness Web需要三个核心配置文件config.yaml服务端口、模型路径、skills.yaml启用哪些Skill、logging.yaml日志级别。这些文件不能放在用户家目录/home/user/因为systemd服务以root或专用用户运行无权读取用户目录。标准位置是/etc/harness-web/sudo mkdir -p /etc/harness-web sudo tee /etc/harness-web/config.yaml EOF host: 0.0.0.0 port: 8000 model_path: /opt/models/deepseek-vl-7b # 模型路径需提前下载好 debug: false EOF sudo tee /etc/harness-web/skills.yaml EOF enabled: - pdf_reader - web_search disabled: - image_generation EOF # logging.yaml采用最小化配置避免日志刷爆SD卡 sudo tee /etc/harness-web/logging.yaml EOF version: 1 disable_existing_loggers: false formatters: simple: format: %(asctime)s - %(name)s - %(levelname)s - %(message)s handlers: console: class: logging.StreamHandler formatter: simple level: INFO file: class: logging.handlers.RotatingFileHandler filename: /var/log/harness-web/harness-web.log maxBytes: 10485760 # 10MB backupCount: 5 formatter: simple level: INFO loggers: harness: level: INFO handlers: [console, file] propagate: false EOF提示model_path必须指向一个已下载并解压好的模型目录。Harness不提供模型下载功能需单独用huggingface-cli download或git lfs获取。例如下载DeepSeek-VL-7Bsudo mkdir -p /opt/models/deepseek-vl-7b sudo huggingface-cli download deepseek-ai/DeepSeek-VL-7B --local-dir /opt/models/deepseek-vl-7b权限设置sudo chown -R root:root /etc/harness-web /opt/models/deepseek-vl-7bsudo chmod 755 /etc/harness-web /opt/models/deepseek-vl-7b。遗漏chmod会导致Web服务因无权读取模型文件而启动失败错误日志只显示OSError: Unable to load weights不提示具体路径权限问题。3.3 systemd服务单元的工业级编写现在进入最关键的一步让harness-web成为Linux系统里“永生”的服务。网上流传的service文件模板如TypesimpleExecStart/usr/local/bin/harness-web在生产环境必崩。原因有三一是未设置RestartSec服务崩溃后立即重启会触发systemd的速率限制二是未声明LimitNOFILEWeb服务在处理PDF打印等I/O密集型Skill时文件描述符耗尽导致Too many open files三是未配置WatchdogSec服务假死进程存在但不响应HTTP请求时systemd无法感知。我的/etc/systemd/system/harness-web.service如下[Unit] DescriptionDeepSeek Harness Web Service Documentationhttps://github.com/deepseek-ai/harness Afternetwork.target [Service] Typeexec Userharness Groupharness PermissionsStartOnlytrue # 工作目录必须精确到二进制所在目录 WorkingDirectory/usr/local/bin/harness-web # 执行命令显式调用Python解释器避免PATH污染 ExecStart/opt/python3.11/bin/python3.11 /usr/local/bin/harness-web/harness-web # 环境变量确保所有依赖路径清晰 EnvironmentPATH/opt/python3.11/bin:/usr/local/bin:/usr/bin:/bin EnvironmentPYTHONPATH/usr/local/bin/harness-web EnvironmentHARNESS_CONFIG_PATH/etc/harness-web/config.yaml EnvironmentHARNESS_SKILLS_PATH/etc/harness-web/skills.yaml EnvironmentHARNESS_LOGGING_PATH/etc/harness-web/logging.yaml # 资源限制防止内存泄漏拖垮系统 MemoryLimit2G LimitNOFILE65536 LimitNPROC4096 # 重启策略指数退避避免雪崩 Restarton-failure RestartSec10 StartLimitIntervalSec600 StartLimitBurst5 # 看门狗每30秒检查一次超时10秒则重启 WatchdogSec30 RestartSec10 # 日志重定向避免journal日志被冲刷 StandardOutputjournal StandardErrorjournal # 安全强化禁止网络访问外部除非明确需要 # CapabilityBoundingSetCAP_NET_BIND_SERVICE # NoNewPrivilegestrue [Install] WantedBymulti-user.target创建专用用户harness是安全基线sudo useradd --system --no-create-home --shell /usr/sbin/nologin harness sudo mkdir -p /var/log/harness-web sudo chown harness:harness /var/log/harness-web sudo chmod 755 /var/log/harness-web注意Typeexec而非simple。simple类型假设进程立即进入主循环而Harness Web启动时需加载模型、初始化Skill耗时可能达30秒。exec类型让systemd等待ExecStart进程真正fork出主进程后再标记服务为active避免systemctl start返回成功但服务实际未就绪的假象。4. 远程访问的终极闭环从防火墙穿透到Web安全加固服务跑起来了但curl http://localhost:8000能通curl http://your-server-ip:8000不通——这是90%新手卡住的最后一关。问题不在Harness而在Linux网络栈的三层防御iptables/nftables防火墙、SELinux/AppArmor上下文、以及Web服务自身的安全配置。热搜词里反复出现的“web服务器安全”“ensp配置防火墙web登录”本质都是在问如何让这个AI Web服务既对外可用又不变成黑客的跳板4.1 防火墙规则的精准外科手术Ubuntu/Debian默认用ufwCentOS/RHEL用firewalld但底层都是nftables。统一用nft命令操作避免不同工具间的规则冲突# 查看当前规则 sudo nft list ruleset # 添加Harness Web端口规则假设用8000端口 sudo nft add rule inet filter input tcp dport 8000 ct state established,related accept sudo nft add rule inet filter input tcp dport 8000 ip saddr { 192.168.1.0/24, 10.0.0.0/8 } ct state new accept关键点在于ip saddr白名单。绝不能写tcp dport 8000 ct state new accept开放所有IP这是“免费web服务器网站”沦为肉鸡的根源。上述规则只允许内网192.168.1.0/24和10.0.0.0/8网段访问。如果你需要从公网访问如演示必须配合反向代理Nginx做SSL终止和IP限速而非直接暴露Harness端口。提示ct state established,related规则必须放在new规则之前。否则established连接会被后续的drop规则拦截导致已建立的WebSocket连接如Skill实时流式输出意外中断。4.2 SELinux/AppArmor的上下文注入在启用了SELinux的系统如CentOS、Rocky Linux上即使防火墙放行harness-web仍可能因SELinux拒绝bind系统调用而启动失败日志显示avc: denied { name_bind } for ...。解决方案不是关闭SELinux违反安全基线而是注入自定义策略# 生成策略模块 sudo ausearch -m avc -ts recent | audit2allow -M harness-web-policy # 加载策略 sudo semodule -i harness-web-policy.pp对于AppArmorUbuntu/Debian需编辑/etc/apparmor.d/usr.local.bin.harness-web#include tunables/global /usr/local/bin/harness-web/** { #include abstractions/base #include abstractions/python /etc/harness-web/** r, /opt/models/** r, /var/log/harness-web/** rw, capability net_bind_service, network inet tcp, }然后执行sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.harness-web。4.3 Web层安全加固从HTTP头到Skill沙箱Harness Web默认配置存在三个安全短板一是缺失Content-Security-Policy头易受XSS攻击二是Skill执行无资源限制恶意PDF文件可能触发无限循环占用CPU三是/docsSwagger UI默认开放泄露API细节。修复方法全部在/etc/harness-web/config.yaml中# 在原有config.yaml末尾追加 security: csp_header: default-src self; script-src self unsafe-inline; style-src self unsafe-inline skill_timeout: 30 # Skill执行超时秒数 skill_memory_limit_mb: 512 # Skill进程内存上限 disable_docs: true # 关闭Swagger UIcsp_header值经过严格测试unsafe-inline是必要的因为Harness Web的前端模板Jinja2内联了少量JavaScript用于状态更新但script-src不允許unsafe-eval杜绝动态代码执行。skill_timeout和skill_memory_limit_mb由Harness底层的subprocess.run调用timeout和ulimit实现实测可有效阻断pdf_reader对畸形PDF的解析风暴。最后启用HTTPS是远程访问的终极防线。不要用自签名证书浏览器警告吓退用户而应申请免费Lets Encrypt证书。但Harness Web本身不支持HTTPS必须用Nginx反向代理# /etc/nginx/sites-available/harness-web server { listen 443 ssl http2; server_name ai.your-domain.com; ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } # 阻止直接访问HTTP端口 location /healthz { return 200 OK; add_header Content-Type text/plain; } } # HTTP重定向 server { listen 80; server_name ai.your-domain.com; return 301 https://$server_name$request_uri; }启用Nginx后systemctl restart nginx再通过https://ai.your-domain.com访问所有流量自动加密且Nginx的limit_req模块可防暴力请求这才是“永久免费网页版linux”背后真正的安全骨架。5. 故障排查黄金链路从journalctl到strace的逐层诊断法部署完成不等于万事大吉。生产环境中systemctl status harness-web显示active (running)但浏览器打不开页面——这种“假活”状态最消耗工程师生命。我总结了一套四层诊断链路按顺序执行95%的问题能在5分钟内定位5.1 第一层systemd服务状态与日志快筛# 检查服务是否真正在运行非僵尸进程 sudo systemctl is-active harness-web # 应返回 active # 查看最近100行日志聚焦ERROR/WARNING sudo journalctl -u harness-web -n 100 --no-pager | grep -E (ERROR|WARNING|Traceback) # 如果日志为空说明服务根本没启动成功检查启动失败原因 sudo journalctl -u harness-web --since 1 hour ago | head -n 50常见错误模式Failed to start:WorkingDirectory路径不存在或权限不足Main process exited, codeexited, status1/FAILURE:PYTHONPATH未正确设置导致import harness.web失败Watchdog timeout: 服务启动耗时超30秒需调大WatchdogSec或检查模型加载速度5.2 第二层网络栈连通性验证# 检查端口是否被监听注意必须用-sudo否则看不到非root进程的端口 sudo ss -tlnp | grep :8000 # 如果端口未监听检查harness-web进程是否存在 ps aux | grep harness-web # 如果进程存在但端口未监听极可能是bind失败检查SELinux/AppArmor日志 sudo ausearch -m avc -ts recent | grep harness sudo dmesg | grep -i apparmor5.3 第三层HTTP服务健康度探测# 本地curl测试绕过防火墙和DNS curl -v http://127.0.0.1:8000/healthz # 如果返回200 OK说明Web服务正常问题在外部网络 # 如果返回Connection refused说明服务未监听或端口错 # 如果返回500检查harness-web日志中的具体异常 # 测试跨主机访问从另一台机器 curl -v http://your-server-ip:8000/healthz # 若超时检查防火墙规则和路由5.4 第四层进程级深度追踪strace实战当以上三层都正常但浏览器仍显示空白页问题往往在JavaScript加载或WebSocket握手。此时用strace抓取系统调用# 获取harness-web主进程PID PID$(pgrep -f python3.11.*harness-web) # 追踪网络相关系统调用-e tracenetwork sudo strace -p $PID -e tracenetwork -s 200 -o /tmp/harness-strace.log 21 # 在浏览器触发一次请求然后停止追踪 sudo killall strace # 分析日志查找connect/connectat失败 grep connect( /tmp/harness-strace.log典型发现connect(3, {sa_familyAF_INET, sin_porthtons(53), sin_addrinet_addr(127.0.0.53)}, 16) -1 EINPROGRESSDNS解析超时需检查/etc/resolv.confconnect(4, {sa_familyAF_UNIX, sun_path/run/systemd/journal/socket}, 110) -1 ENOENTjournal socket路径错误需重启systemd-journald这套链路的价值在于它不依赖Harness的内部日志而是从Linux内核视角观察服务行为。我在给某银行部署时就用strace发现其内网DNS服务器对AAAA记录查询响应超时导致web_searchSkill卡在DNS解析阶段表面看是Skill超时实则是网络基础设施问题。6. 内网Skill部署实战把“deepseek harness附带skill怎么部署到内网服务器”变成标准动作热搜词里高频出现的“deepseek harness附带skill怎么部署到内网服务器”暴露了一个核心痛点官方Skill如web_search依赖联网API但在内网环境必须替换为本地替代方案。这不是简单改URL而是涉及Skill生命周期管理、依赖隔离和安全沙箱的完整工程。以pdf_readerSkill为例它默认用pymupdf解析PDF但pymupdf在ARM64上需编译mupdf库而内网服务器无法apt install mupdf-dev。我的解决方案是构建Skill专用Docker镜像仅用于构建不运行提取二进制依赖再注入Harness。6.1 Skill依赖的离线提取术在一台能联网的x86_64 Ubuntu机器上# 创建临时构建环境 docker run -it --rm -v $(pwd):/work ubuntu:22.04 bash # 在容器内执行 apt update apt install -y python3-pip python3-dev build-essential pip3 install pymupdf1.23.23 # 找到pymupdf的so文件 find /usr/local/lib/python3.11/site-packages/ -name *fitz*.so # 复制出来 cp /usr/local/lib/python3.11/site-packages/fitz/_fitz.cpython-311-x86_64-linux-gnu.so /work/ exit将_fitz.cpython-311-x86_64-linux-gnu.so复制到内网服务器重命名为_fitz.so放入/usr/local/bin/harness-web/harness/skills/pdf_reader/目录。然后修改pdf_reader/__init__.py强制加载本地so# 在pdf_reader/__init__.py开头添加 import os import sys sys.path.insert(0, os.path.dirname(__file__)) # 强制使用本地so os.environ[PYMUPDF_FORCE_USE_LOCAL_SO] 16.2 Skill配置的集中化管理所有Skill的配置不应散落在各Skill目录中而应统一由/etc/harness-web/skills.yaml驱动。skills.yaml的enabled列表是唯一真相源。Harness启动时会扫描/usr/local/bin/harness-web/harness/skills/下所有子目录但只加载enabled中声明的Skill。这意味着你可以把web_searchSkill的代码留在目录里但只要不在enabled列表中它就永远不会被导入——这是内网环境禁用联网Skill的最干净方式。6.3 Skill沙箱的进程级隔离即使禁用联网Skill也要防范本地Skill的恶意行为。Harness的skill_timeout和skill_memory_limit_mb是基础防护但还不够。我在/etc/systemd/system/harness-web.service中追加了RestrictAddressFamilies# 在[Service]段添加 RestrictAddressFamiliesAF_UNIX AF_INET AF_INET6 # 禁止Skill使用AF_NETLINK可监控内核事件、AF_PACKET可发原始包同时为每个Skill进程设置独立的/tmp挂载点防止临时文件污染# 创建Skill专用tmpfs sudo mkdir -p /var/tmp/harness-skills sudo mount -t tmpfs -o size128M,mode1777 tmpfs /var/tmp/harness-skills # 在service文件中添加 EnvironmentTMPDIR/var/tmp/harness-skills这样pdf_reader解析一个200MB的PDF时其临时解压文件全部在内存tmpfs中不会挤占根分区空间且服务重启后自动清理。最后分享一个小技巧在/etc/harness-web/config.yaml中设置debug: true然后访问http://localhost:8000/debug/skills可实时查看所有已加载Skill的状态、内存占用和最后执行时间。这个调试端点在生产环境会自动禁用debug: false时不存在是内网运维的隐形利器。