关于 uipath-functions
用于使用 Python、JavaScript 或 TypeScript 构建确定性 UiPath Coded Functions 的技能。涵盖类型化输入输出、本地测试、打包、发布和部署,不包含大模型推理或 Agent 循环。
主要功能
- 01搭建 Python 和 JS/TS 函数
- 02定义类型化输入输出架构
- 03本地运行和测试函数
- 04打包、发布和推送项目
- 05在函数中调用 UiPath API
- 06配置资源绑定
适用场景
- 01实现自定义业务规则
- 02按类型化契约转换数据
- 03发布前测试函数
- 04从函数代码调用平台 API
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ uipath/ skills --skill uipath-functions安装后在 Claude Code 中输入/uipath-functions确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/solutions/metadata.jsonreferences/js/authoring-guide.mdbindings-guide.mdcalling-uipath-apis-guide.mdcoded-app-wiring-guide.mddeployment-guide.mdhttp-semantics-guide.mdjob-mode-guide.mdlocal-dev-guide.mdreferences/python/bindings-reference.mdworkflow-guide.md详细介绍
UiPath Coded Functions
原子化、确定性的业务逻辑单元——不涉及 LLM 推理,也没有 Agent 循环——使用 Python 或 TypeScript/JavaScript 编写,并作为一等 UiPath 制品发布。一个 uip function CLI 即可驱动这两种语言。Coded Function 接收类型化输入,执行确定性代码,并返回类型化输出;当通用活动无法满足所需逻辑时(例如自定义身份验证 API 调用、领域规则、通过 Integration Service 查询 ERP、数据转换),即可使用它。
何时使用此技能
- 使用任一语言搭建、编写或修改 coded function(
uip function new <NAME> -l py|ts|js) - 声明类型化契约——Pydantic Input/Output(Python)或
defineSchema<T>()/ JSON Schema 字面量(JS/TS) - 在本地测试:
uip function run(两种语言),uip function serve+ curl(JS/TS HTTP 端点) - 错误处理:返回错误字段(Python)、
FunctionError/ 状态码和作业故障语义(JS/TS) - 在函数内调用 UiPath 平台 API(Python SDK;通过
ctxtoken 使用@uipath/uipath-typescript) - 将 Coded App 前端连接到 JS/TS 函数后端(token、CORS、超时预算、本地开发循环)
- 打包、发布并在生产环境中调用;在解决方案中注册;根据 SDK 调用生成
bindings.json资源绑定 - 调试已部署函数的故障:冷启动卡住、错误代码 4801/4804/1623、缺少 token、入口点错误
请勿将此技能用于:
- LLM/Agent 项目(
agent.json、LangGraph、LlamaIndex、OpenAI Agents、Agent 循环)→uipath-agents - Coded App 前端本身(React/Vite 应用代码、PKCE 设置、应用部署)→
uipath-coded-apps
语言区分
开始操作前,先根据项目特征识别现有项目;对于新项目,语言由调用方的技术栈决定。
| Python | JS/TS | |
|---|---|---|
| 搭建 | uip function new <NAME> -l py(必须指定 -l py) | uip function new <NAME> -l ts / -l js(CLI 默认使用 ts) |
| 项目特征 | pyproject.toml + uipath.json functions 映射 | package.json + uipath.json functions 映射 |
| 契约 | Pydantic BaseModel / @dataclass Input/Output | defineSchema<T>()(TS)/ JSON Schema 字面量(JS) |
| 入口点 | "main": "main.py:<fn>",由 uip function init 生成 | functions/<FILE>.ts:default,自动同步;无需 init |
| 调用模式 | 作为作业运行(Maestro、Agent、Orchestrator API) | 仅可声明一种模式:HTTP 端点或作为作业运行,不能同时使用 |
| 本地开发 | uip function run | uip function serve(HTTP 端口为 :7070)/ uip function run(单次作业) |
| 参考资料 | references/python/ | references/js/ |
可启动作业的函数可通过 Maestro BPMN/Flow(Service Task)、编码 Agent(作为工具或步骤)、其他函数、Orchestrator API(POST /Jobs/StartJobs)或计划/触发器调用。JS/TS HTTP 模式函数则通过其 Orchestrator HTTP 触发器进行同步调用(references/js/http-semantics-guide.md)。
重要规则
两种语言通用
- Coded Function 内不得调用 LLM。 LLM 推理会破坏确定性契约——此类项目属于 Agent →
uipath-agents。 uipath.json中的functions映射用于标识 Coded Function 项目——所有工具都会读取此标记。- 云端工作需要身份验证:
uip login --organization "<ORG>" --tenant "<TENANT>" --output json。
Python
- 绝不能在模块级实例化
UiPath()——在 getter 中使用延迟单例。 - 返回错误,不要抛出错误:填充输出字段
error_type/error_message;绝不能让异常从入口点冒出。 - 必须先运行
uip function init,再运行pack或push——此命令会生成entry-points.json和project.uiproj,并在缺少bindings.json时将其创建为空骨架;架构或入口点发生任何变更后都要重新运行。它绝不会从代码推导绑定(规则 7)。 - 必须使用类型化 I/O——使用 Pydantic
BaseModel、pydantic.dataclasses.dataclass、标准库@dataclass或精简的类型化类;为入口点应用@traced(name=..., run_type="uipath"),以记录 LLM Ops Traces。 pyproject.toml必须包含authors(否则pack会拒绝并报错:Project authors cannot be empty),且不能包含[build-system]部分。uip function new -l py会生成函数脚手架——包含functions映射的uipath.json,不包含langgraph.json——无论虚拟环境中是否安装了任何 Agent 框架包(uipath-langchain、uipath-llamaindex、uipath-openai-agents)。- 绑定必须根据
uipathSDK 调用推导——绝不能留空,也绝不能猜测。init会保留"resources": []。每次sdk().assets/queues/processes/buckets/context_grounding/connections/mcp/tasks调用都需要在bindings.json中有匹配条目,并通过参考文档中的同步工作流生成。如果没有绑定,项目仍可顺利打包和发布,但部署时不会显示可供映射的资源,并会在运行时失败。uip function push会像uip codedagent push一样,根据资源目录解析这些条目。
JS/TS
- 抛出
FunctionError,不要抛出普通Error。 普通抛出始终会变成通用 500(JsCodedFunction.HandlerError),并泄露原始堆栈;FunctionError(message, status)会携带由作者控制的状态码(在选项中传入errorCode可设置作业错误码)。参数顺序为(message, status)。请参阅错误处理。 - 契约以架构为先。 使用
defineSchema<T>()定义接口(TS,会在构建时转换),或使用裸 JSON Schema 字面量(JS)。不要在新函数中使用 zod/arktype/valibot——它们会破坏静态契约提取,并增加运行时依赖。不得使用$ref、any、bigint或元组;架构字面量必须是静态的。 - 每个文件在
functions/目录下直接默认导出一个defineFunction。 辅助模块以_开头(functions/_helpers.ts)。method和path必须同时提供,或都不提供——这对参数会决定函数唯一的调用模式:HTTP 端点或普通作业运行,不能两者兼有。两种调用方式都需要的逻辑应由两个精简函数共享一个_辅助模块。 - 项目内部导入必须带
.ts扩展名(./_helpers.ts)。省略扩展名的导入在本地开发时可以解析,但会导致生产环境冷启动时整个运行时卡住,且没有日志。 - 运行时依赖放在
dependencies中,且只能使用公共 npm 包;SDK 保留在devDependencies中。 生产环境会在冷启动时运行npm install --omit=dev——从devDependencies或私有注册表导入运行时依赖会导致函数崩溃或卡住。更改任何依赖后都要重新生成锁文件;过期的package-lock.json会导致每个路由都以 errorCode 4801 失败。 - 在 20 秒内完成——网关会在 25 秒时超时,并返回一个没有 CORS 的
303和轮询 URL:浏览器调用方会永久丢失结果,而通过重定向在服务器端恢复结果的做法没有文档说明。对每个外部调用都使用AbortSignal.timeout(...);将耗时更长的工作移到以作业方式运行的函数中。 - 部署后的 POST 即使输入为空,也仍需提供
body: '{}'——网关会以400 errorCode 4804拒绝空请求体(本地服务不会,因此该问题只会在生产环境出现)。 - 两个令牌,对应两个身份。
ctx.user.accessToken= 调用方的令牌(委托令牌,拥有调用方文件夹的权限);ctx.robot.accessToken= 函数自身的机器人身份(S2S,拥有特权读取权限)。本地服务下ctx.robot始终为 null(未发送 Bearer 令牌时才有ctx.user)——请回退使用process.env["UIPATH_ACCESS_TOKEN"]。 - 从
ctx.platform读取平台坐标(baseUrl、orgId、tenantId、folderKey),不要从输入字段读取——由调用方控制的 URL 存在重定向风险。环境变量(UIPATH_BASE_URL、UIPATH_ORG_ID、UIPATH_TENANT_ID)仅作为本地环境的回退方案。 - 只有 SDK 的
logger.*会写入 Orchestrator 作业日志。console.*只会在本地输出,不会转发。 - 不要使用
Buffer。 请使用Uint8Array、TextEncoder、TextDecoder。 - 运行
uip function publish后,手动更新 Orchestrator 中的 Function Release(Automations → Processes)——只有更新 release 后,触发器才会同步到新版本。 uip function run是一次性作业执行,不是 HTTP 调用。 若要在本地测试 HTTP 调用方式,请使用 curl/fetch 访问serve服务器——没有任何 CLI 子命令会替你调用路由。
快速入门
Python
uip function new <NAME> -l py # scaffold a Python function project
# author: Pydantic Input/Output + @traced entrypoint, lazy UiPath() singleton, errors returned not raised
uip function init # generate entry-points.json / project.uiproj; bindings.json starts empty
# sync bindings.json from the SDK resource calls — references/python/bindings-reference.md
uip function run <ENTRYPOINT> '{"document_id": "42"}'
uip function pack && uip function publish
完整工作流(架构、模板、uipath.json 注册、pyproject.toml、SDK 功能、附件、packOptions):references/python/workflow-guide.md。
JS/TS
uip function new <NAME> -l ts # or -l js; --empty for no sample
# author: one default-exported defineFunction per functions/ file — method+path for HTTP, neither for run-as-job
uip function serve # HTTP on :7070, hot reload; test with curl
uip function run --function <NAME> --input '{}' # one-shot local job execution
uip function pack && uip function publish # then update the Function Release in Orchestrator
// functions/invoice.ts
import { defineFunction, defineSchema, FunctionError } from "@uipath/coded-functions-js-sdk";
interface Input {
invoiceId: string;
/** @default 0 */
amount?: number;
}
interface Output {
approved: boolean;
}
export default defineFunction({
name: "approve-invoice",
method: "POST",
path: "/invoice", // omit method+path entirely for a run-as-job function
input: defineSchema<Input>(),
output: defineSchema<Output>(),
handler: async (input, ctx) => {
if (!ctx.user?.accessToken) throw new FunctionError("Unauthorized", 401);
return { approved: input.amount! < 10_000 }; // success data only — errors are thrown
},
});
编写详情、本地开发、HTTP 语义、部署、绑定、Coded App 接线:references/js/(请参阅下方导航)。
CLI 参考
uip function new <NAME> -l py|ts|js [--empty] # scaffold (TypeScript default; --empty is JS/TS only)
uip function init # Python only — entry-points.json, project.uiproj, empty bindings.json skeleton
uip function serve [--port 7070] [--runtime node|deno] # JS/TS only — local HTTP server, hot reload
uip function run # both languages — one-shot local execution
uip function pack [--nolock] # build the .nupkg
uip function publish [--feed-id <FEED_ID>] # upload package to a process feed
uip function push --project-id <PROJECT_ID> [--ignore-resources] # sync sources to Studio Web and import bindings.json resources
uip function runtime-install # JS/TS — one-time runtime pre-install (otherwise downloaded on first serve/run)
已废弃的复数拼写(
functions)不可用——请始终使用单数形式uip function。
参考导航
| 我需要…… | 阅读 |
|---|---|
| Python:完整工作流 — 脚手架、架构、模板、注册、依赖项、初始化、SDK 调用、附件、打包 | python/workflow-guide.md |
Python:根据 SDK 资源调用派生并同步 bindings.json — 按资源定义架构、SubType、入口点绑定、push 的作用 | python/bindings-reference.md |
| JS/TS:编写处理程序、契约、ctx、错误、日志记录 | js/authoring-guide.md |
| JS/TS:在本地运行和测试(serve、run、环境、令牌) | js/local-dev-guide.md |
| JS/TS:路由、状态码、部署限制 | js/http-semantics-guide.md |
| JS/TS:以作业模式运行、故障语义 | js/job-mode-guide.md |
| JS/TS:打包、发布、在生产环境中调用、解决方案、冷启动 | js/deployment-guide.md |
| JS/TS:绑定 — entry-points.json、bindings_v2.json、覆盖项 | js/bindings-guide.md |
| JS/TS:从函数调用 UiPath API(uipath-typescript、IS) | js/calling-uipath-apis-guide.md |
| JS/TS:将 Coded App 前端连接到函数后端 | js/coded-app-wiring-guide.md |
反模式
Python
- 在模块级实例化
UiPath()— 应始终在 getter 中使用惰性单例(Python Rule 1)。 - 从入口点抛出异常 — 填充错误输出字段并返回(Python Rule 2)。
- 架构变更后跳过
uip function init— 过时的entry-points.json会导致发布错误的契约(Python Rule 3)。 - 代码调用 SDK 资源时,发布
"resources": []的bindings.json—init只会创建骨架;需要派生出各条目(Python Rule 7)。
JS/TS
throw new Error("…")— 会产生通用 500 错误、泄露原始堆栈,且无法由作者控制状态码 — JS Rule 1。- 在 200 响应中返回
errors[]数组。 输出架构只承载成功数据;函数一次只抛出一个错误。 - 在新函数中使用 zod/arktype 契约 — 会破坏静态提取,并引入运行时依赖 — JS Rule 2。
- 不带扩展名的相对导入 — 本地运行正常,但会导致生产环境冷启动卡住 — JS Rule 4。
- 将运行时依赖放在
devDependencies中或放在私有注册表上 — 冷启动时会跳过或无法获取 — JS Rule 5。 - 在 Coded App 的 Vite 配置中添加
server.proxy来访问函数 — 这会破坏应用的 OAuth 回调;直接 fetchhttp://localhost:7070/<PATH>(serve 会发送 CORS*)。 - 将
baseUrl/orgId/tenantId作为函数输入接受 — 有重定向风险;应使用ctx.platform— JS Rule 9。 - 从浏览器调用门户域名 — 该域名不支持 CORS;浏览器必须调用
api.<HOST>子域名。 - 使用
console.log进行生产环境诊断 — 永远不会出现在作业日志中 — JS Rule 10。 - 根据触发器自身的 Id 构造调用 URL — 会产生 404 错误码 1623;URL 使用文件夹 Key GUID + 包 ID + slug。
- 期望调用方在 25 秒后仍能恢复结果 — HTTP 函数应控制在 20 秒以内,将耗时更长的工作转移到以作业模式运行的函数 — JS Rule 6。