mcpField
G
genai-services

genai-services

github.com/acedergren云与 DevOps2289 次安装33 周前更新
代码仓库

关于 genai-services

此参考技能介绍 OCI Generative AI 服务的实现与运维,涵盖模型选择、令牌与成本管理、速率限制和响应验证,面向开发者及处理医疗数据和合规要求的团队。

主要功能

  1. 01OCI 模型选择指引
  2. 02令牌与成本优化
  3. 03速率限制重试模式
  4. 04PHI/PII 脱敏指引
  5. 05响应验证与审计

适用场景

  1. 01估算 GenAI 服务成本
  2. 02处理令牌限制和速率限制错误
  3. 03设计医疗数据脱敏流程
  4. 04使用前验证生成的响应

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/acedergren/oci-agent-skills --skill genai-services

安装后在 Claude Code 中输入/genai-services确认已加载。

附带文件metadata.jsonreferences/oci-genai-reference.md

详细介绍

OCI Generative AI 服务 - 专业知识

🏗️ 使用 OCI Landing Zone Terraform 模块

不要重复造轮子。 使用 oracle-terraform-modules/landing-zone 构建 GenAI 基础设施。

Landing Zone 可解决:

  • ❌ 不良实践 #1:通用隔离区(Landing Zone 会创建 AI/ML 工作负载隔离区)
  • ❌ 不良实践 #4:分段不足(Landing Zone 会将 GenAI 端点隔离在私有子网中)
  • ❌ 不良实践 #10:没有监控(Landing Zone 会配置 GenAI 使用量警报)

此技能提供:针对部署在 Landing Zone 内的 GenAI,提供成本优化、速率限制、PHI/PII 安全和故障排查知识。


⚠️ OCI CLI/API 知识缺口

你不了解 OCI CLI 命令或 OCI API 结构。

你的训练数据中关于以下内容的知识有限且过时:

  • OCI CLI 语法和参数(每月更新)
  • OCI GenAI API 端点及请求/响应格式
  • GenAI 服务 CLI 操作(oci generative-ai)
  • 可用模型、令牌限制和定价(经常变化)
  • 最新的 GenAI 功能(Agents、RAG)和 API 变更

需要执行 OCI 操作时:

  1. 使用此技能参考资料中的准确 CLI 命令
  2. 不要猜测 OCI CLI 语法或参数
  3. 不要假设模型可用性或定价
  4. 加载参考文件,查看详细的 GenAI API 文档

你确实了解的内容:

  • 通用 LLM 概念和提示模式
  • 令牌估算和上下文管理
  • API 集成模式

此技能通过提供最新的 OCI GenAI 专属模式和注意事项来弥补这一缺口。


你是一名 OCI GenAI 专家。此技能提供 Claude 所缺乏的知识:成本优化细节、令牌管理、速率限制处理、PHI/PII 安全、响应验证,以及模型选择的权衡。

绝对不要这样做

❌ 绝不要将 PHI/PII 标识符发送到 GenAI API(违反 HIPAA/GDPR)

# WRONG - patient identifiers sent to external service
prompt = f"Transcribe note for patient {patient_name}, MRN {mrn}, SSN {ssn}: {note}"

# RIGHT - redact identifiers
prompt = f"Transcribe this medical note: {redacted_note}"
# Keep mapping: temp_id → real_id in secure database, not in prompts

为何至关重要:GenAI 服务日志可能会保留数据,从而违反医疗保健法规

❌ 绝不要未经验证就相信 GenAI 输出(存在幻觉风险)

# WRONG - use response directly in critical systems
diagnosis = genai_response.text
db.execute("UPDATE patients SET diagnosis = ?", diagnosis)

# RIGHT - validate structure and flag for human review
response = genai_response.text
if validate_medical_format(response):
    db.execute("UPDATE patients SET ai_suggested_diagnosis = ?, status = 'PENDING_REVIEW'", response)

幻觉率:事实类查询为 5-15%,医疗/法律领域更高

❌ 绝不要忽略令牌限制

  • command-r-plus:128k 上下文窗口(输入 + 输出)
  • command-r:4k 上下文(便宜得多,但有限制)
  • 超出限制:请求会被静默截断,或以 400 错误失败

❌ 绝不要在未处理速率限制的情况下调用 GenAI

# WRONG - no retry logic, fails on rate limit
response = genai_client.chat(request)

# RIGHT - exponential backoff
def call_with_retry(func, max_retries=5):
    for attempt in range(max_retries):
        try:
            return func()
        except oci.exceptions.ServiceError as e:
            if e.status == 429 and attempt < max_retries - 1:
                wait = (2 ** attempt) + random.uniform(0, 1)
                logger.warning(f"Rate limited, retry in {wait:.2f}s")
                time.sleep(wait)
            else:
                raise

❌ 绝不要未经同意就缓存响应(数据隐私)

  • 缓存可以节省成本,但可能违反隐私政策
  • 缓存医疗/个人数据前,须获得用户明确同意
  • 仅缓存匿名化数据

❌ 绝不要将 GenAI 用于确定性任务

  • 错误:“从 OCR 文本中提取发票总额”(应使用正则表达式/结构化解析)
  • 错误:“验证电子邮件格式”(应使用验证库)
  • 正确:“总结患者病史”“生成报告叙述”(创造性任务)

模型选择:成本与性能

模型上下文成本(每 1M 个令牌)最适合避免用于
command-r-plus128k~$15 输入,$75 输出复杂推理、长文档简单任务(成本高)
command-r4k~$1.50 输入,$7.50 输出聊天、短提示词、高调用量长文档、RAG
embed-english-v3不适用每 1M 个约 ~$0.10语义搜索、聚类文本生成
llama-2-70b4k~$2 输入,$10 输出开放权重、经济高效生产环境(支持有限)

成本优化策略:

  1. 优先使用嵌入进行搜索(成本比生成低 1000 倍)
  2. 缓存重复查询的响应(需征得同意)
  3. 简单任务使用 command-r,仅在需要时使用 command-r-plus
  4. 智能截断输入(仅保留相关上下文)

成本计算示例

场景:医疗转录服务

  • 平均病历:输入 500 个 token,输出 300 个 token = 共 800 个 token
  • 每天 1000 份病历 = 每天 80 万个 token = 每月 2400 万个 token

未优化:

Model: command-r-plus
Input:  12M × ($15/1M) = $180/month
Output: 12M × ($75/1M) = $900/month
Total: $1,080/month

优化后(缓存命中率为 30%,简单病历使用 command-r):

70% unique notes = 16.8M tokens
60% simple (command-r): 10M × $1.50 input + $7.50 output = $90
40% complex (command-r-plus): 6.72M × $15 input + $75 output = $605
Total: $695/month (36% savings)

Token 管理

各模型的 Token 限制
模型最大上下文最大输出备注
command-r-plus128k(输入+输出)不定每个 token 约 4 个字符(粗略估算)
command-r4k2k适用于聊天
embed-english-v3512不适用仅用于嵌入
截断策略
def truncate_for_model(text: str, model: str = "command-r-plus", max_output: int = 2000):
    """Truncate input to fit token budget"""

    # Rough estimate: 1 token ≈ 4 characters
    if model == "command-r-plus":
        max_input_tokens = 128000 - max_output
    elif model == "command-r":
        max_input_tokens = 4000 - max_output
    else:
        max_input_tokens = 2000

    max_chars = max_input_tokens * 4

    if len(text) <= max_chars:
        return text

    # Keep most recent content (chronological data like logs, notes)
    logger.warning(f"Input exceeds {max_input_tokens} tokens, truncating")
    return "...[earlier content truncated]...\n" + text[-max_chars:]
提示词优化

效率低(浪费 token):

Please carefully analyze the following medical record and provide a comprehensive
summary including all diagnoses, medications, allergies, and treatment plans. Be
thorough and include all relevant details from the patient's history...

[5000 word medical record]

优化后(减少 40% 的 token):

Summarize: diagnoses, meds, allergies, treatment plan.

[5000 word medical record]

节省的 token:每个提示词约节省 50 个 token × 每天 1000 次请求 = 每天节省 5 万个 token = 每天 $2.25(每月 $68)

速率限制

OCI GenAI 服务限制(每个区间):
模型每分钟请求数每天请求数每次请求的 Token 数
command-r-plus201000128k
command-r6030004k
Embeddings10010000512
错误处理
import time
import random
from oci.exceptions import ServiceError

def generate_with_backoff(genai_client, request, max_retries=5):
    """Call GenAI with exponential backoff on rate limits"""

    for attempt in range(max_retries):
        try:
            response = genai_client.chat(request)
            return response.data.chat_response.text

        except ServiceError as e:
            if e.status == 429:  # Rate limit
                if attempt < max_retries - 1:
                    # Exponential backoff: 1s, 2s, 4s, 8s, 16s
                    wait = (2 ** attempt) + random.uniform(0, 1)
                    logger.warning(f"Rate limited (429), retry {attempt+1}/{max_retries} in {wait:.1f}s")
                    time.sleep(wait)
                else:
                    logger.error(f"Rate limit exceeded after {max_retries} retries")
                    raise

            elif e.status == 400:  # Bad request (often token limit)
                logger.error(f"Bad request (400): {e.message}")
                if "token" in e.message.lower():
                    logger.error("Token limit exceeded - truncate input")
                raise

            else:
                logger.error(f"GenAI error ({e.status}): {e.message}")
                raise

响应验证(医疗保健领域至关重要)

def validate_medical_response(response: str) -> tuple[bool, list[str]]:
    """Validate GenAI medical response for safety"""

    issues = []

    # Check 1: Response not empty
    if not response or len(response.strip()) < 10:
        issues.append("Response too short or empty")

    # Check 2: No obvious hallucination markers
    hallucination_markers = [
        "I don't have access",
        "I cannot",
        "As an AI",
        "[INSERT",
        "TODO",
    ]
    for marker in hallucination_markers:
        if marker.lower() in response.lower():
            issues.append(f"Potential hallucination marker: {marker}")

    # Check 3: Expected structure present (customize per use case)
    required_sections = ["Chief Complaint", "Assessment", "Plan"]
    missing_sections = [s for s in required_sections if s.lower() not in response.lower()]
    if missing_sections:
        issues.append(f"Missing sections: {missing_sections}")

    # Check 4: No PII leak (if input was redacted)
    pii_patterns = [
        r'\b\d{3}-\d{2}-\d{4}\b',  # SSN
        r'\b[A-Z]{2}\d{6,8}\b',     # MRN patterns
    ]
    for pattern in pii_patterns:
        if re.search(pattern, response):
            issues.append(f"Potential PII in response: {pattern}")

    is_valid = len(issues) == 0
    return is_valid, issues


# Usage
response_text = genai_response.data.chat_response.text
is_valid, issues = validate_medical_response(response_text)

if is_valid:
    store_for_review(response_text)
else:
    logger.warning(f"Invalid response: {issues}")
    flag_for_manual_review(response_text, issues)

医疗保健领域的特定注意事项

HIPAA 合规性

最低要求:

  • ✅ 与 Oracle 签订业务伙伴协议(BAA)
  • ✅ 发送至 GenAI 前对 PHI 进行脱敏
  • ✅ 记录所有 GenAI API 调用的审计日志
  • ✅ 传输中和静态数据均加密
  • ✅ 访问控制(哪些人可以调用 GenAI)
  • ✅ 数据保留政策(提示词/响应的保留时长)

切勿默认认为 GenAI 符合 HIPAA 要求——请向 Oracle 核实 BAA 的覆盖范围

去标识化策略
def redact_phi(text: str) -> tuple[str, dict]:
    """Remove PHI from text, return redacted text + mapping"""

    mapping = {}
    redacted = text

    # Patient names (use NER or pattern matching)
    names = extract_names(text)  # Your NER function
    for i, name in enumerate(names):
        placeholder = f"[PATIENT_{i}]"
        mapping[placeholder] = name
        redacted = redacted.replace(name, placeholder)

    # Medical Record Numbers
    mrn_pattern = r'\b(MRN|Medical Record):?\s*([A-Z0-9]{6,10})\b'
    redacted = re.sub(mrn_pattern, r'\1: [REDACTED]', redacted)

    # SSN
    ssn_pattern = r'\b\d{3}-\d{2}-\d{4}\b'
    redacted = re.sub(ssn_pattern, '[SSN_REDACTED]', redacted)

    # Dates (optional - some use cases need dates)
    # date_pattern = r'\b\d{1,2}/\d{1,2}/\d{4}\b'
    # redacted = re.sub(date_pattern, '[DATE]', redacted)

    return redacted, mapping


# Usage
redacted_note, phi_mapping = redact_phi(patient_note)
genai_response = genai_client.chat(prompt=f"Summarize: {redacted_note}")
# Store phi_mapping securely, use to re-identify if needed

渐进式加载参考资料

OCI Generative AI 参考资料(Oracle 官方文档)

在以下情况下加载 oci-genai-reference.md:

  • 需要全面了解 GenAI API 文档
  • 了解所有可用模型及其功能
  • 使用 OCI 实现 RAG(检索增强生成)
  • 需要 Oracle 关于 GenAI Agent 的官方指导
  • 了解微调和自定义模型部署

以下情况无需加载:

  • 快速了解 API 用法示例(此技能中已涵盖)
  • 模型选择指导(见上方决策树)
  • 成本计算(见上方公式)

何时使用此技能

  • GenAI API 实现:模型选择、成本估算、SDK 用法
  • 错误排查:速率限制(429)、Token 限制(400)、身份验证
  • 成本优化:缓存策略、降级模型、提示词优化
  • 医疗保健/合规:PHI 处理、HIPAA 要求、审计日志
  • 响应验证:幻觉检测、结构检查
  • 生产环境:速率限制处理、错误恢复、监控

评论

支持 Markdown