Skip to content

SDK 使用指南

JarvisClaw Python 与 Go SDK 的完整参考。两个 SDK 都内置了认证、x402 支付流程、流式输出、重试和错误处理。


安装

bash
pip install jarvisclaw

# Base(EVM)链 x402 钱包支付
pip install jarvisclaw[agent]

# Solana 链 x402 钱包支付
pip install jarvisclaw[solana]

# asyncio 异步客户端
pip install jarvisclaw[async]

# 全部
pip install jarvisclaw[all]
bash
go get github.com/api-jarvisclaw/go-sdk/v2@latest

如何选择客户端

Python SDK 按调用面拆分成多个客户端,另有两个聚合入口。选覆盖你需求的最小那个即可。

客户端适用场景
Agent自主循环 —— ask()、带工具的 run()、消费追踪
JarvisClawAIP 全貌 —— resolve()execute()stream()audit()
IntentClient需要 preferences 与分析接口的 AIP 调用
ChatClient仅对话补全
ImageClient / VideoClient / AudioClient多媒体生成
SearchClient网页搜索与正文提取
MarketplaceClient直接调用 Marketplace 服务
WalletClient余额、流水、限额、资金池
PromptCoachClientPrompt 优化
NetworkClient网络节点管理与爬取
OpenAIopenai 同形客户端(client.chat.completions.create

Go SDK 只有一个 *Client 承载全部方法,另有若干类型化的轻量包装(ChatClientImageClientVideoClientAudioClientSearchClientMarketplaceClient),通过 NewChatClient(...) 等构造。


初始化

两种认证模式 —— API Key(托管计费)或钱包私钥(x402 链上直付)。

python
from jarvisclaw import JarvisClaw

client = JarvisClaw(api_key="sk-your-api-key")
python
from jarvisclaw import JarvisClaw

# Agent 直接签名支付,无需托管账户
# 十六进制私钥 → Base(EVM);Base58 密钥对 → Solana。SDK 从格式自动识别
client = JarvisClaw(private_key="0x<your-hex-private-key>")
go
package main

import jc "github.com/api-jarvisclaw/go-sdk/v2"

func main() {
    client, err := jc.NewClient(jc.WithAPIKey("sk-your-api-key"))
    if err != nil {
        panic(err)
    }
    _ = client
}
go
package main

import jc "github.com/api-jarvisclaw/go-sdk/v2"

func main() {
    // Base 链用 EVM 十六进制私钥。Solana 目前仅 Python SDK 支持
    client, err := jc.NewClient(jc.WithPrivateKey("0x<your-hex-private-key>"))
    if err != nil {
        panic(err)
    }
    _ = client
}

Go 的构造函数都返回 error

jc.NewClient 及所有 jc.NewXxxClient 返回 (*Client, error)。忽略第二个返回值无法编译。

环境变量:

bash
export JARVISCLAW_API_KEY=sk-...
export JARVISCLAW_WALLET_KEY=0x...                     # 钱包私钥(十六进制或 base58)
export JARVISCLAW_BASE_URL=https://api.jarvisclaw.ai   # 默认值

设置了环境变量后可以无参初始化。两者都存在时 JARVISCLAW_API_KEY 优先。

python
client = JarvisClaw()  # 从环境变量读取
go
client, err := jc.NewClient()  // 从环境变量读取

超时

超时是客户端级别的设置,不是单次请求级别。

python
from jarvisclaw import JarvisClaw

client = JarvisClaw(api_key="sk-...", timeout=60)  # 秒,默认 120
go
import (
    "context"
    "time"
    jc "github.com/api-jarvisclaw/go-sdk/v2"
)

client, _ := jc.NewClient(jc.WithAPIKey("sk-..."), jc.WithTimeout(60*time.Second))

// 单次调用的截止时间通过传入的 context 控制:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

resp, err := client.Execute(ctx, jc.ExecuteRequest{
    Intent:  "chat_completion",
    Payload: map[string]any{"messages": []map[string]any{{"role": "user", "content": "你好"}}},
})

Python SDK 会对 4295xx 做最多 3 次指数退避重试。单次调用不支持 timeout 参数 —— 需要不同超时请另建一个客户端。


最快上手:Agent

Agent 把意图解析和对话封装成一次调用,并自动追踪消费。

python
from jarvisclaw import Agent

agent = Agent(api_key="sk-your-api-key", default_budget=1.00)

# 一行:在预算内解析最优模型并调用
print(agent.ask("用三句话解释量子计算", budget=0.01, optimize="cost"))

# 流式输出
for chunk in agent.stream("写一首关于 AI Agent 的诗"):
    print(chunk, end="", flush=True)

# 带工具的自主循环
@agent.tool
def calculator(expression: str) -> str:
    """计算一个数学表达式。"""
    return str(eval(expression))

result = agent.run("2^100 + 3^50 等于多少?")
print(result.text)
print(result.cost)        # CostTracker —— 本次 run 的消费
print(result.iterations)
go
ctx := context.Background()
client, _ := jc.NewClient(jc.WithAPIKey("sk-your-api-key"))

// 在预算内解析后直接对话 —— 一次调用
text, err := client.Ask(ctx, "用三句话解释量子计算",
    jc.AskOptions{Budget: 0.01, Optimize: "cost"})
if err != nil {
    log.Fatal(err)
}
fmt.Println(text)

optimize / Optimize 取值为 costqualitylatency,默认 cost


意图执行

JarvisClaw.execute()intentpayload 是位置参数,之后可选 budgetconstraints 关键字参数。返回值是所选提供商的响应原文 —— chat_completion 即标准 OpenAI 格式补全。

1. 文本生成(chat_completion

python
result = client.execute(
    "chat_completion",
    {
        "messages": [
            {"role": "system", "content": "你是一个有帮助的助手。"},
            {"role": "user", "content": "用三句话解释量子计算。"},
        ],
        "temperature": 0.7,
        "max_tokens": 200,
    },
    budget={"max_total_usd": 0.05},
)

print(result["choices"][0]["message"]["content"])
go
raw, err := client.Execute(ctx, jc.ExecuteRequest{
    Intent: "chat_completion",
    Payload: map[string]any{
        "messages": []map[string]any{
            {"role": "system", "content": "你是一个有帮助的助手。"},
            {"role": "user", "content": "用三句话解释量子计算。"},
        },
        "temperature": 0.7,
        "max_tokens":  200,
    },
})
if err != nil {
    log.Fatal(err)
}
// Execute 返回 json.RawMessage —— 提供商的响应原文
var out struct {
    Choices []struct {
        Message struct{ Content string } `json:"message"`
    } `json:"choices"`
}
_ = json.Unmarshal(raw, &out)
fmt.Println(out.Choices[0].Message.Content)

需要 preferences

JarvisClaw.execute() 不接受 preferences。要干预选路请用 IntentClient

python
from jarvisclaw import IntentClient

intent = IntentClient(api_key="sk-...")
result = intent.execute(
    "chat_completion",
    {"messages": [{"role": "user", "content": "你好"}]},
    constraints={"max_price_usd": 0.05},
    preferences={"optimize_for": "quality"},
)

2. 流式输出

流式走 /v1/intent/subscribe,产出的是 SSE 事件而非纯文本。每个事件形如 {"event": ..., "data": ...}

python
for event in client.stream(
    "chat_completion",
    {"messages": [{"role": "user", "content": "写一首关于 AI Agent 的诗。"}]},
):
    if event["event"] == "chunk":
        print(event["data"].get("content", ""), end="", flush=True)
    elif event["event"] == "done":
        print(f"\n\n费用: ${event['data'].get('actual_cost_usd')}")
go
stream, err := client.Subscribe(ctx, jc.SubscribeRequest{
    Intent:  "chat_completion",
    Payload: map[string]any{"messages": []map[string]any{{"role": "user", "content": "写一首诗。"}}},
})
if err != nil {
    log.Fatal(err)
}
defer stream.Close()

for {
    ev, err := stream.Next()
    if err != nil {
        break
    }
    fmt.Printf("[%s] %v\n", ev.Event, ev.Data)
}

只要纯文本流、不走 AIP 的话,ChatClient.stream()(Python)与 ChatClient.Stream()(Go) 直接产出文本块:

python
from jarvisclaw import ChatClient

chat = ChatClient(api_key="sk-...")
for chunk in chat.stream("讲个笑话"):
    print(chunk, end="")
go
cc, _ := jc.NewChatClient(jc.WithAPIKey("sk-..."))
stream, _ := cc.Stream(ctx, "讲个笑话")
for chunk := range stream.Channel() {
    fmt.Print(chunk)
}

3. 图片生成(image_generation

python
result = client.execute(
    "image_generation",
    {"prompt": "赛博朋克城市的日落", "size": "1024x1024"},
    budget={"max_total_usd": 0.12},
)
print(result["data"][0]["url"])
print(f"费用: ${result['price']['amount']} USD")
go
// 也可以用专用客户端,它会帮你解析响应:
ic, _ := jc.NewImageClient(jc.WithAPIKey("sk-..."))
img, err := ic.Generate(ctx, "赛博朋克城市的日落", jc.WithSize("1024x1024"))
if err != nil {
    log.Fatal(err)
}
fmt.Println(img.URL)

图片响应是 OpenAI 同形结构,外加两个 JarvisClaw 字段:顶层 idprice 对象。CDN 链接取 data[0].url


4. 视频生成(video_generation

视频是异步的 —— 提交后轮询。专用客户端会自动轮询。

python
from jarvisclaw import VideoClient

video = VideoClient(api_key="sk-your-api-key")

# 阻塞模式 —— SDK 轮询直到 MP4 就绪
job = video.generate("无人机航拍热带岛屿",
                     model="bytedance/seedance-2.0", duration=5)
print(job.url)

# 非阻塞模式
job = video.generate("日落时的海浪", wait=False)
print(job.id, job.status)     # 例如 "bytedance:video_24d2...", "queued"
# ... 稍后 ...
print(video.status(job.id).url)
go
vc, _ := jc.NewVideoClient(jc.WithAPIKey("sk-your-api-key"))

job, err := vc.Generate(ctx, "无人机航拍热带岛屿",
    jc.WithVideoModel("bytedance/seedance-2.0"), jc.WithDuration(5), jc.WithWait(true))
if err != nil {
    log.Fatal(err)
}
fmt.Println(job.URL)

Job ID 带提供商前缀(bytedance:video_xxx),不是 vg_xxx。生成通常需 60–180 秒,高分辨率要留 更多余量。视频按秒计费seedance-2.0 为 $0.227/秒,5 秒约 $1.14 —— 预算别按整段估。 详见视频生成


5. 语音合成(text_to_speech

python
from jarvisclaw import AudioClient

audio = AudioClient(api_key="sk-your-api-key")

# 返回带原始字节的 AudioResponse —— SDK 会自动跟随 CDN 链接下载
result = audio.speech("欢迎使用 JarvisClaw。", model="elevenlabs/flash-v2.5", voice="sarah")
with open("output.mp3", "wb") as f:
    f.write(result.content)
go
ac, _ := jc.NewAudioClient(jc.WithAPIKey("sk-your-api-key"))

result, err := ac.Speech(ctx, "欢迎使用 JarvisClaw。",
    jc.WithAudioModel("elevenlabs/flash-v2.5"), jc.WithVoice("sarah"))
if err != nil {
    log.Fatal(err)
}
os.WriteFile("output.mp3", result.Data, 0644)

auto/tts 与 x402 钱包

实测中智能路由 TTS 对钱包直付(private_key)调用方结算失败。用 private_key 时请显式指定 ElevenLabs 模型。音色默认 sarah


6. 语音识别(转写)

转写走 multipart 文件上传,不是 JSON 里塞 base64。

python
from jarvisclaw import AudioClient

audio = AudioClient(api_key="sk-your-api-key")

with open("recording.mp3", "rb") as f:
    text = audio.transcribe(f, model="whisper-1", language="zh")
print(text)
bash
curl https://api.jarvisclaw.ai/v1/audio/transcriptions \
  -H "Authorization: Bearer sk-your-api-key" \
  -F file="@recording.mp3" \
  -F model="whisper-1"

transcribe() 直接返回文本字符串。Go SDK 暂无转写封装 —— 请直接向 /v1/audio/transcriptions 发 multipart 请求。

没有 speech_to_text 意图

语音识别不在 AIP 的意图常量表内,请直接调用 /v1/audio/transcriptions


python
from jarvisclaw import SearchClient

search = SearchClient(api_key="sk-your-api-key")

# 走 /v1/search(智能路由摘要),返回 list[SearchResult]
for r in search.query("2026 年最新 AI Agent 框架", num_results=5):
    print(r.title, r.url, r.snippet[:80])

# 结构化的 Exa 网页正文
contents = search.contents(["https://example.com/article"])
go
sc, _ := jc.NewSearchClient(jc.WithAPIKey("sk-your-api-key"))

resp, err := sc.Query(ctx, "2026 年最新 AI Agent 框架", jc.WithNumResults(5))
if err != nil {
    log.Fatal(err)
}
fmt.Println(resp.Summary, resp.SourcesUsed)
for _, r := range resp.Citations {
    fmt.Printf("  %s: %s\n", r.Title, r.URL)
}

query() 返回摘要而非排序链接

SearchClient.query() 请求 /v1/searchmodel=auto/search),返回带内联引用的 AI 摘要。 当响应没有结构化引用时,Python SDK 会返回单条 SearchResult(title="Search Result", url="", snippet=<摘要>) —— 所以 .url 常为空。需要逐条 标题和 URL,请直接调用 POST /v1/marketplace/exa/search。详见网页搜索


高级用法

预算控制

execute_budget()IntentClient 上,budget 是必填的第三个位置参数。服务端只读取 max_total_usd(外加可选的 preferred_payment_methodallow_overdraft)。

python
from jarvisclaw import IntentClient

intent = IntentClient(private_key="0x<agent-wallet-key>")

result = intent.execute_budget(
    "chat_completion",
    {"messages": [{"role": "user", "content": "总结这份文档……"}]},
    {"max_total_usd": 0.50},
)

print(result["status"])            # "success" | "rejected" | "error"
print(result.get("risk_level"))
print(result.get("actual_cost_usd"))
go
resp, err := client.ExecuteBudget(ctx, jc.ExecuteBudgetRequest{
    Intent:  "chat_completion",
    Payload: map[string]any{"messages": []map[string]any{{"role": "user", "content": "总结这份文档……"}}},
    Budget:  jc.Budget{MaxTotalUSD: 0.50},
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("status=%s risk=%s\n", resp.Status, resp.RiskLevel)
if resp.ActualCostUSD != nil {
    fmt.Printf("cost=%.6f\n", *resp.ActualCostUSD)
}

单次与每日限额

per_call_limit_usddaily_limit_usd 不是这个请求的字段。持久化限额请用 PUT /v1/wallet/limits 设置(per_request_max_usddaily_max_usdmonthly_max_usd)。 详见钱包与资金库


自然语言解析

用自然语言描述需求,AIP 通过 embedding 相似度解析意图。该端点只解析,不执行、不扣费 —— 拿到提供商后自行调用。

python
# 暂无 SDK 封装 —— 直接调端点
result = client._post("/v1/intent/resolve/natural", json={
    "query": "我想生成一张戴墨镜的猫的图片",
    "constraints": {"max_price_usd": 0.10},
})

if result["status"] == "resolved":
    print(result["intent"], result["confidence"])
    for m in result.get("matches", []):
        print(f"  {m['provider_name']}: ${m.get('price_usd')}{m.get('endpoint')}")
elif result["status"] == "clarify":
    print(result["clarify"]["question"])
    for opt in result["clarify"].get("options", []):
        print(f"  - {opt}")
bash
curl -X POST https://api.jarvisclaw.ai/v1/intent/resolve/natural \
  -H "Authorization: Bearer sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"query": "生成一张戴墨镜的猫的图片"}'

status 取值为 resolvedclarifybudget_insufficientno_match。需要澄清时,追问内容在 clarify 对象里(questionoptionsround),不是顶层的 message/options


提供商解析(Resolve)

python
matches = client.resolve(
    "chat_completion",
    constraints={
        "max_price_usd": 0.05,
        "max_latency_ms": 3000,
        "features": ["function_calling", "json_mode"],
    },
)

for m in matches["matches"]:
    print(f"{m['provider_id']}: ${m['estimated_price_usd']}, score={m['score']}, {m['reason']}")
print(f"{matches['intent_type']} 共有 {matches['total_available']} 个可用提供商")
go
maxPrice, maxLatency := 0.05, 3000

resp, err := client.Resolve(ctx, jc.ResolveRequest{
    Intent: "chat_completion",
    Constraints: jc.Constraints{
        MaxPriceUSD:  &maxPrice,
        MaxLatencyMS: &maxLatency,
        Features:     []string{"function_calling", "json_mode"},
    },
    Preferences: jc.Preferences{OptimizeFor: "quality"},
})
if err != nil {
    log.Fatal(err)
}
for _, m := range resp.Matches {
    fmt.Printf("%s: $%.6f score=%.2f %s\n", m.ProviderID, m.EstimatedPriceUSD, m.Score, m.Reason)
}

Go 的约束字段是指针

MaxPriceUSD*float64MaxLatencyMS*int —— 需取变量地址,字面量无法编译。 ResolveRequest 上的 Constraints/Preferences 是值类型,而 ExecuteRequest 上是指针类型。

候选字段为 provider_idscoreestimated_price_usdpricingendpointmodelreason。没有 resolution_idexpires_at —— 解析不做预留,因此也不存在过期。


审计日志(Audit)

python
entries = client.audit()   # 无参数;范围由凭证决定

for e in entries["entries"]:
    print(f"[{e['timestamp']}] {e['event_type']} req={e['request_id']}")
    print(f"  {e.get('details')}")
print(f"共 {entries['count']} 条")
go
resp, err := client.Audit(ctx)
if err != nil {
    log.Fatal(err)
}
for _, e := range resp.Entries {
    fmt.Printf("[%s] %s req=%s %v\n", e.Timestamp, e.EventType, e.RequestID, e.Details)
}

审计端点不支持过滤

GET /v1/intent/audit 不接受任何查询参数,返回 {entries, count} —— 没有 total/page/page_size,也不能按日期或意图类型过滤。每条记录是 {timestamp, request_id, user_id, event_type, details}event_type 是生命周期事件 (intent_resolvedexecution_completesettlement_confirmed 等)而非意图名。Python 的 audit() 同样不接受任何参数,固定请求 /v1/intent/audit。要查消费历史请用下方的分析方法。


成本分析

python
from jarvisclaw import IntentClient

intent = IntentClient(api_key="sk-...")

# 聚合后的消费与结算数据
print(intent.spend(period="7d", group_by=["day", "model"]))

# spend() 的便捷包装
print(intent.cost_by_model(period="7d"))
print(intent.daily_trend(period="30d"))

# 从日志挖掘的质量指标与深度扫描汇总
print(intent.quality(period="7d"))
print(intent.insights(period="7d"))
go
rows, _ := client.Spend(ctx, jc.AnalyticsParams{
    Period:  "7d",
    GroupBy: []string{"day", "model"},
})

// Spend 的便捷包装
byModel, _ := client.CostByModel(ctx, jc.AnalyticsParams{Period: "7d"})
trend, _ := client.DailyTrend(ctx, jc.AnalyticsParams{Period: "30d"})

quality, _ := client.QualityMetrics(ctx, jc.AnalyticsParams{Period: "7d"})
insights, _ := client.Insights(ctx, jc.AnalyticsParams{Period: "7d"})

对应 /api/analytics/{aggregate,quality,insights}

period 可取 "24h""7d"(默认)、"30d""90d",传其他值服务端会回落到 "7d"group_by 可取 daymodelapi_sourceprincipal_typechannelgroupclient_id,为空时默认 day,model,api_source

数据范围由服务端依据鉴权上下文强制约束。像 SDK 这样用 API 令牌(sk-...)调用时,只能拿到自己的数据:该路径下 user_id 会被忽略,即使令牌属于管理员也一样;只有在控制台登录(会话鉴权)的管理员才能用 user_id 放宽范围。AIP 用量出现在同一批数据中,以 api_source="aip" 标识 —— 旧的 /v1/aip/analytics/* 端点已被移除。


网络资源(Network)

节点列举与爬取需要管理员权限。

python
from jarvisclaw import NetworkClient

net = NetworkClient(api_key="sk-admin-key")
print(net.list_peers())
print(net.crawl())
go
peers, _ := client.NetworkPeers(ctx)
_, _ = client.NetworkCrawl(ctx)

浏览和执行网络资源是公开的,暂无 SDK 封装 —— 直接调端点:

bash
# 自然语言资源推荐(standard 档免费)
curl -X POST https://api.jarvisclaw.ai/v1/network/recommend \
  -H "Content-Type: application/json" \
  -d '{"query": "我需要分析股票市场数据", "max_results": 5}'

# 全文搜索网络资源(免费)
curl "https://api.jarvisclaw.ai/v1/network/search?q=stock&limit=5"

# 执行网络资源(付费)
curl -X POST https://api.jarvisclaw.ai/v1/network/execute \
  -H "Authorization: Bearer sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"resource_id": 532, "payload": {"ticker": "AAPL"}}'

resource_id/v1/network/apis 返回的数字 id,不是 slug;推荐接口的查询字段是 query、结果上限字段是 max_results。详见 AIP → 网络


错误处理

python
from jarvisclaw import (
    JarvisClaw,
    JarvisClawError,
    APIError,
    AuthenticationError,
    RateLimitError,
    InsufficientBalanceError,
    PaymentError,
)

client = JarvisClaw(private_key="0x...")

try:
    result = client.execute(
        "chat_completion",
        {"messages": [{"role": "user", "content": "你好"}]},
    )
except AuthenticationError as e:
    print(f"密钥无效 [{e.status_code}]: {e.message}")
except InsufficientBalanceError as e:
    print(f"USDC 余额不足 [{e.status_code}]: {e.message}")
    print(f"服务端返回: {e.body}")
except RateLimitError as e:
    print(f"触发限流,{e.retry_after} 秒后重试")
except APIError as e:
    print(f"API 错误 [{e.status_code}]: {e.message}")
except JarvisClawError as e:
    print(f"SDK 错误: {e}")
go
import (
    "errors"
    jc "github.com/api-jarvisclaw/go-sdk/v2"
)

raw, err := client.Execute(ctx, jc.ExecuteRequest{
    Intent:  "chat_completion",
    Payload: map[string]any{"messages": []map[string]any{{"role": "user", "content": "你好"}}},
})
if err != nil {
    var authErr *jc.AuthenticationError
    var balErr *jc.InsufficientBalanceError
    var rateErr *jc.RateLimitError
    var apiErr *jc.APIError

    switch {
    case errors.As(err, &authErr):
        fmt.Printf("密钥无效: %s\n", authErr.Message)
    case errors.As(err, &balErr):
        fmt.Printf("USDC 余额不足: %s\n", balErr.Message)
    case errors.As(err, &rateErr):
        fmt.Printf("触发限流: %s\n", rateErr.Message)
    case errors.As(err, &apiErr):
        fmt.Printf("API 错误 [%d]: %s\n", apiErr.StatusCode, apiErr.Message)
    default:
        fmt.Printf("传输错误: %v\n", err)
    }
}
_ = raw

Python 异常层级:JarvisClawErrorAPIError(带 status_codemessagebody)→ AuthenticationError / RateLimitError / InsufficientBalanceErrorPaymentError 继承 JarvisClawError,用于 x402 签名失败。RateLimitError.retry_after 读取响应体的 retry_after

Agent 另有自己的 BudgetExceededError.budget.spent),在 run 超出预算时抛出。

Go 侧结构一致:APIErrorStatusCode/Message/Body,被 AuthenticationErrorRateLimitErrorInsufficientBalanceError 嵌入;PaymentError 嵌入 JarvisClawError。 它们都没有 .Type 字段 —— 请按具体类型或 StatusCode 分支。


异步(Python)

python
import asyncio
from jarvisclaw.aio import ChatClient, ImageClient

async def main():
    async with ChatClient(private_key="0x...") as chat, \
               ImageClient(private_key="0x...") as image:

        text, img = await asyncio.gather(
            chat.complete("什么是 AIP?"),
            image.generate("火星上的猫"),
        )
        print(text, img.url)

        async for chunk in chat.stream("讲个故事"):
            print(chunk, end="")

asyncio.run(main())

可用的异步客户端:ChatClientImageClientVideoClientAudioClientSearchClientMarketplaceClientWalletClientIntentClient。需要 pip install jarvisclaw[async]。 详见异步与并发


OpenAI 兼容入口

python
from jarvisclaw import OpenAI

client = OpenAI(api_key="sk-your-api-key")

resp = client.chat.completions.create(
    model="auto",
    messages=[{"role": "user", "content": "你好!"}],
)
print(resp.choices[0].message.content)

这个包装在熟悉的接口上加了 x402 支持。若你更想用官方 openai 包,只需把 base_url 指向 https://api.jarvisclaw.ai/v1 —— 见快速开始


完整示例:Agent 循环

python
from jarvisclaw import Agent, BudgetExceededError

agent = Agent(private_key="0x<agent-wallet-key>", default_budget=5.00)

def agent_loop(instructions: list[str]):
    for instruction in instructions:
        try:
            reply = agent.ask(instruction, budget=0.05)
        except BudgetExceededError as e:
            print(f"已停止:花费 ${e.spent:.4f},上限 ${e.budget:.4f}")
            return
        print(f"Agent: {reply}")

    print(f"钱包余额: ${agent.get_balance():.4f} USDC")

agent_loop([
    "向量数据库有哪些取舍?",
    "用一句话总结上面的回答。",
])
go
package main

import (
    "context"
    "fmt"
    "log"

    jc "github.com/api-jarvisclaw/go-sdk/v2"
)

func main() {
    client, err := jc.NewClient(jc.WithPrivateKey("0x<agent-wallet-key>"))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()

    for _, instruction := range []string{
        "向量数据库有哪些取舍?",
        "用一句话总结上面的回答。",
    } {
        reply, err := client.Ask(ctx, instruction, jc.AskOptions{Budget: 0.05})
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("Agent: %s\n", reply)
    }

    balance, _ := client.GetBalance(ctx)
    fmt.Printf("钱包余额: $%.4f USDC\n", balance)
}

需要保留多轮上下文时,Python 用 agent.run(...),Go 则自行维护消息数组并调用 ChatClient.Completion(ctx, messages, ...)


链接