Core modules: - Laws: CRUD, search, AI-powered QA - Analysis: legal research and case management - Contracts: lifecycle management with templates - Signatures: electronic signature workflow Infrastructure: - FastAPI + SQLite + async SQLAlchemy - Docker deployment support - 54 unit tests passing Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
124 lines
3.8 KiB
Python
124 lines
3.8 KiB
Python
"""LLM service for AI-powered features."""
|
|
from typing import List, Dict, Any, Optional
|
|
import httpx
|
|
|
|
from app.core.config import settings
|
|
|
|
|
|
class LLMService:
|
|
"""Service for LLM API interactions."""
|
|
|
|
def __init__(self):
|
|
self.api_base = settings.LLM_API_BASE
|
|
self.api_key = settings.LLM_API_KEY
|
|
self.model = settings.LLM_MODEL
|
|
|
|
async def chat_completion(
|
|
self,
|
|
messages: List[Dict[str, str]],
|
|
temperature: float = 0.7,
|
|
max_tokens: int = 2000,
|
|
) -> str:
|
|
"""Get chat completion from LLM."""
|
|
if not self.api_key:
|
|
# Return mock response for testing
|
|
return "这是一个模拟的法律回复。"
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.post(
|
|
f"{self.api_base}/chat/completions",
|
|
headers={
|
|
"Authorization": f"Bearer {self.api_key}",
|
|
"Content-Type": "application/json",
|
|
},
|
|
json={
|
|
"model": self.model,
|
|
"messages": messages,
|
|
"temperature": temperature,
|
|
"max_tokens": max_tokens,
|
|
},
|
|
timeout=60.0,
|
|
)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
return data["choices"][0]["message"]["content"]
|
|
|
|
async def legal_qa(
|
|
self,
|
|
question: str,
|
|
context: Optional[str] = None,
|
|
) -> str:
|
|
"""Answer a legal question."""
|
|
system_prompt = """你是一个专业的法律助手。请根据以下原则回答问题:
|
|
1. 准确引用相关法律条文
|
|
2. 解释法律条文的含义和适用条件
|
|
3. 提供实用的法律建议
|
|
4. 如不确定,请明确说明"""
|
|
|
|
messages = [
|
|
{"role": "system", "content": system_prompt},
|
|
]
|
|
|
|
if context:
|
|
messages.append({
|
|
"role": "user",
|
|
"content": f"参考以下法律内容:\n{context}\n\n问题:{question}"
|
|
})
|
|
else:
|
|
messages.append({"role": "user", "content": question})
|
|
|
|
return await self.chat_completion(messages)
|
|
|
|
async def analyze_legal_issue(
|
|
self,
|
|
issue_description: str,
|
|
relevant_laws: Optional[List[str]] = None,
|
|
) -> str:
|
|
"""Analyze a legal issue and provide insights."""
|
|
system_prompt = """你是一个专业的法律分析师。请根据以下结构分析法律问题:
|
|
1. 问题定性
|
|
2. 相关法律依据
|
|
3. 法律分析
|
|
4. 风险提示
|
|
5. 建议"""
|
|
|
|
user_content = f"请分析以下法律问题:\n{issue_description}"
|
|
|
|
if relevant_laws:
|
|
user_content += f"\n\n相关法律:\n" + "\n".join(relevant_laws)
|
|
|
|
messages = [
|
|
{"role": "system", "content": system_prompt},
|
|
{"role": "user", "content": user_content},
|
|
]
|
|
|
|
return await self.chat_completion(messages, temperature=0.5)
|
|
|
|
async def review_contract(
|
|
self,
|
|
contract_content: str,
|
|
contract_type: Optional[str] = None,
|
|
) -> str:
|
|
"""Review a contract and identify potential issues."""
|
|
system_prompt = """你是一个专业的合同审查专家。请审查合同并:
|
|
1. 识别潜在风险条款
|
|
2. 指出不明确的条款
|
|
3. 提出修改建议
|
|
4. 检查法律合规性"""
|
|
|
|
user_content = f"请审查以下合同内容:\n{contract_content}"
|
|
|
|
if contract_type:
|
|
user_content = f"合同类型:{contract_type}\n\n{user_content}"
|
|
|
|
messages = [
|
|
{"role": "system", "content": system_prompt},
|
|
{"role": "user", "content": user_content},
|
|
]
|
|
|
|
return await self.chat_completion(messages, max_tokens=3000)
|
|
|
|
|
|
# Singleton instance
|
|
llm_service = LLMService()
|